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