Tutorial:Physics (日本語)

この用例では、緑色の地面を転がる赤玉の作成します。

このページの末尾に関税品の用例を掲載してあります。また、関数はすべて一本のファイルに記述します: main.lua

love.load() 関数から説明を始めます。

love.load()

最初に、物理物体を内部へ存在させるためにワールド (仮想空間、世界) を設定してください。

function love.load()
  love.physics.setMeter(64) -- 世界において1メートル当たりの高さは 64 ピクセルです
  world = love.physics.newWorld(0, 9.81*64, true) -- 水平重力は 0、垂直重力は  9.81 の物体が存在するワールドを作成します。


さて、世界が創造されたので、物体形状、および取付具を追加します。

   objects = {} -- 全ての物理オブジェクトを保持するテーブル
 
  -- 地面を作成します
  objects.ground = {}
  objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) -- 中心から形状の錨 (長方形は次回に作成します) であるため、
                                                                     -- (650/2, 650-50/2) へ移動する必要があることをお忘れなく
  objects.ground.shape = love.physics.newRectangleShape(650, 50) -- 幅 650、高さ 50 の長方形を作成します。
  objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) -- 物体に形状を取り付けます
 
  -- 玉を作成します
  objects.ball = {}
  objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") -- 世界の中心に動的にした物体を配置すると、転がして移動できます
  objects.ball.shape = love.physics.newCircleShape( 20) -- 玉の形状は半径 20 です
  objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1) -- 物体に取付具を接続して密度に 1 を指定します。
  objects.ball.fixture:setRestitution(0.9) -- 玉を弾ませます
  -- 遊びまわる一組のブロックを作成します

  objects.block1 = {}
  objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
  objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
  objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) -- 高密度にすると質量は増大します。
  objects.block2 = {}

  objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
  objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)

さて love.load() 関数をラップするために、画面の大きさおよび背景色を設定します。

  -- グラフィックスの設定を初期化します
  love.graphics.setBackgroundColor(0.41, 0.53, 0.97) -- 背景の描画色を綺麗な青色にします
  love.window.setMode(650, 650) -- ウィンドウの寸法を 650 x 650 の全画面表示へ、 VSYNC を有効化、アンチエイリアシングを無効化に設定します
end

よろしい、それで物理演算エンジンの初期化設定には十分です。 さて love.update() 関数を編集します。

love.update()

function love.update(dt)
  world:update(dt) -- これは世界を動かすために配置します
 
  -- ここへキーボード・イベントを作成します
  if love.keyboard.isDown("right") then --右矢印キーを押すと玉は右方向へ押し出されます
    objects.ball.body:applyForce(400, 0)
  elseif love.keyboard.isDown("left") then --左矢印キーを押すと玉は左方向へ押し出されます
    objects.ball.body:applyForce(-400, 0)
  elseif love.keyboard.isDown("up") then -- 上矢印キーを押すと玉は空中へ浮遊します
    objects.ball.body:setPosition(650/2, 650/2)
    objects.ball.body:setLinearVelocity(0, 0) -- 位置の変化により生成された潜在的な速力を阻止するために 0 まで速度を設定する必要があります
  end
end

これで世界は更新されるようになるため、地面と玉を描画できます。

love.draw()

最初は、地面です。

function love.draw()
  love.graphics.setColor(0.28, 0.63, 0.05) -- 地面の描画色を緑色にします
  love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- 地面の座標で使用する"塗りつぶされた"多角形を描画します

さらに最後のほうで玉とブロックを表す円形を描画します。

  love.graphics.setColor(0.76, 0.18, 0.05) -- 玉の描画色を赤色にします
  love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius())

  love.graphics.setColor(0.20, 0.20, 0.20) -- ブロックの描画色を灰色にします
  love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints()))
  love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints()))
end

このファイルを zip ファイルへ格納して、 physics.love (または任意のもの) へ名称変更して、実行してください。また、約束したように、緑が茂る環境内で玉は周辺を転がります。

ほぼ完成品のスクリーンショット。

main.lua

function love.load()
  -- 世界において1メートル当たりの高さは 64 ピクセルです
  love.physics.setMeter(64)
  -- 水平重力は 0、垂直重力は  9.81 の
  -- 物体が存在するワールドを作成します。
  world = love.physics.newWorld(0, 9.81*64, true)

  objects = {} -- 全ての物理オブジェクトを保持するテーブル

  -- 地面を作成します
  objects.ground = {}
  -- 留意して欲しいのは、中心から形状の錨 (長方形は次回に作成します) であるため、
  -- (650/2, 650-50/2) へ移動する必要があることをお忘れなく
  objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2)
  -- 幅 650、高さ 50 の長方形を作成します。
  objects.ground.shape = love.physics.newRectangleShape(650, 50)
  -- 物体に形状を取り付けます
  objects.ground.fixture = love.physics.newFixture(objects.ground.body,
                                                   objects.ground.shape)

  -- 玉を作成します
  objects.ball = {}
  -- 世界の中心に動的にした物体を配置するため、
  -- 転がして移動できます
  objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic")
  -- 玉の形状は半径 20 です
  objects.ball.shape = love.physics.newCircleShape(20)
  -- 物体に取付具を接続して密度に 1 を指定します。
  objects.ball.fixture = love.physics.newFixture(objects.ball.body,
                                                 objects.ball.shape, 1)
  objects.ball.fixture:setRestitution(0.9) -- 玉を弾ませます

  -- 遊びまわる一組のブロックを作成します
  objects.block1 = {}
  objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
  objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
  -- 高密度にすると質量は増大します。
  objects.block1.fixture = love.physics.newFixture(objects.block1.body,
                                                   objects.block1.shape, 5)

  objects.block2 = {}
  objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
  objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block2.fixture = love.physics.newFixture(objects.block2.body,
                                                   objects.block2.shape, 2)

  -- グラフィックスの設定を初期化します
  -- 背景の描画色を綺麗な青色にします
  love.graphics.setBackgroundColor(0.41, 0.53, 0.97)
  love.window.setMode(650, 650) -- ウィンドウの寸法を 650 x 650 へ設定します
end


function love.update(dt)
  world:update(dt) -- これは世界を動かすために配置します

  -- ここへキーボード・イベントを作成します
  -- --右矢印キーを押すと玉は右方向へ押し出されます
  if love.keyboard.isDown("right") then
    objects.ball.body:applyForce(400, 0)
  -- 左矢印キーを押すと玉は左方向へ押し出されます
  elseif love.keyboard.isDown("left") then
    objects.ball.body:applyForce(-400, 0)
  -- 上矢印キーを押すと玉は空中へ浮遊します
  elseif love.keyboard.isDown("up") then
    objects.ball.body:setPosition(650/2, 650/2)
    -- 位置の変化により生成された潜在的な速力を阻止するために
    --  0 まで速度を設定する必要があります
    objects.ball.body:setLinearVelocity(0, 0)
  end
end

function love.draw()
  -- 地面の描画色を緑色にします
  love.graphics.setColor(0.28, 0.63, 0.05)
  -- 地面の座標で使用する"塗りつぶされた"多角形を描画します
  love.graphics.polygon("fill", objects.ground.body:getWorldPoints(
                           objects.ground.shape:getPoints()))

  -- 玉の描画色を赤色にします
  love.graphics.setColor(0.76, 0.18, 0.05)
  love.graphics.circle("fill", objects.ball.body:getX(),
                       objects.ball.body:getY(), objects.ball.shape:getRadius())

  -- ブロックの描画色を灰色にします
  love.graphics.setColor(0.20, 0.20, 0.20)
  love.graphics.polygon("fill", objects.block1.body:getWorldPoints(
                           objects.block1.shape:getPoints()))
  love.graphics.polygon("fill", objects.block2.body:getWorldPoints(
                           objects.block2.shape:getPoints()))
end

そのほかの言語