Difference between revisions of "Tutorial:Physics"
(Adapted to 0.8, added some blocks to play around with) |
m (cut down cruft) |
||
Line 1: | Line 1: | ||
− | In this | + | In this example we will create a red ball that rolls around on a green ground. |
The finished example is at the end of this page. All of these functions may be placed in one file: main.lua | The finished example is at the end of this page. All of these functions may be placed in one file: main.lua | ||
Line 7: | Line 7: | ||
=== love.load() === | === love.load() === | ||
− | First we need to set up a world for the physics bodies to exist in. | + | First we need to set up a [[love.physics.newWorld|world]] for the physics bodies to exist in. |
<source lang="lua"> | <source lang="lua"> | ||
function love.load() | function love.load() | ||
Line 14: | Line 14: | ||
</source> | </source> | ||
− | Now that a [[world]] has been created, we can add [[bodies]] to it. | + | Now that a [[love.physics.newWorld|world]] has been created, we can add [[Body|bodies]], [[Shape|shapes]], and [[Fixture|fixture]] to it. |
<source lang="lua"> | <source lang="lua"> | ||
Line 23: | Line 23: | ||
objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) --remember, the shape (the rectangle we create next) anchors to the body from its center, so we have to move it to (650/2, 650-50/2) | objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) --remember, the shape (the rectangle we create next) anchors to the body from its center, so we have to move it to (650/2, 650-50/2) | ||
objects.ground.shape = love.physics.newRectangleShape(0, 0, 650, 50) --anchor the shape to the body, and make it a width of 650 and a height of 50 | objects.ground.shape = love.physics.newRectangleShape(0, 0, 650, 50) --anchor the shape to the body, and make it a width of 650 and a height of 50 | ||
− | objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) | + | objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) --attach shape to body |
--let's create a ball | --let's create a ball | ||
objects.ball = {} | objects.ball = {} | ||
objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") --place the body in the center of the world and make it dynamic, so it can move around | objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") --place the body in the center of the world and make it dynamic, so it can move around | ||
− | objects.ball.body:setMass(15) | + | objects.ball.body:setMass(15) --give it a mass of 15 |
objects.ball.shape = love.physics.newCircleShape(0, 0, 20) --the ball's shape has no offset from it's body and has a radius of 20 | objects.ball.shape = love.physics.newCircleShape(0, 0, 20) --the ball's shape has no offset from it's body and has a radius of 20 | ||
− | objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1.0) | + | objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1.0) --attach shape to body and give it a friction of 1.0 |
objects.ball.fixture:setRestitution(0.9) --let the ball bounce | objects.ball.fixture:setRestitution(0.9) --let the ball bounce | ||
− | --let's create | + | --let's create a couple blocks to play around with |
objects.block1 = {} | objects.block1 = {} | ||
objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic") | objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic") | ||
Line 43: | Line 43: | ||
objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic") | objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic") | ||
objects.block2.body:setMass(300) | objects.block2.body:setMass(300) | ||
− | objects.block2.shape = love.physics.newRectangleShape(0, 0, 50 | + | objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50) |
objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2) | objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</source> | </source> | ||
− | Now to wrap up the love.load function, let's set up the screen size and background color. | + | Now to wrap up the [[love.load]] function, let's set up the screen size and background color. |
<source lang="lua"> | <source lang="lua"> | ||
Line 83: | Line 71: | ||
objects.ball.body:applyForce(-400, 0) | objects.ball.body:applyForce(-400, 0) | ||
elseif love.keyboard.isDown("up") then --press the up arrow key to set the ball in the air | elseif love.keyboard.isDown("up") then --press the up arrow key to set the ball in the air | ||
− | objects.ball.body: | + | objects.ball.body:setPosition(650/2, 650/2) |
end | end | ||
end | end | ||
Line 110: | Line 98: | ||
love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints())) | love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints())) | ||
love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints())) | love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints())) | ||
− | |||
− | |||
end | end | ||
</source> | </source> | ||
Line 117: | Line 103: | ||
There you have it! Put this file in a [[zip|zip file]], rename it to physics.love (or whatever), run it. And you'll have a ball rolling around in a lush green environment like I promised. | There you have it! Put this file in a [[zip|zip file]], rename it to physics.love (or whatever), run it. And you'll have a ball rolling around in a lush green environment like I promised. | ||
− | [[Image:Tutorial-PhysicsBall.jpg|thumb|Screenshot of the finished product.]] | + | [[Image:Tutorial-PhysicsBall.jpg|thumb|Screenshot of the mostly finished product.]] |
Line 137: | Line 123: | ||
objects.ball = {} | objects.ball = {} | ||
objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") --place the body in the center of the world and make it dynamic, so it can move around | objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") --place the body in the center of the world and make it dynamic, so it can move around | ||
− | objects.ball.body:setMass(15) | + | objects.ball.body:setMass(15) --give it a mass of 15 |
objects.ball.shape = love.physics.newCircleShape(0, 0, 20) --the ball's shape has no offset from it's body and has a radius of 20 | objects.ball.shape = love.physics.newCircleShape(0, 0, 20) --the ball's shape has no offset from it's body and has a radius of 20 | ||
− | objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1.0) | + | objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1.0) --attach shape to body and give it a friction of 1.0 |
objects.ball.fixture:setRestitution(0.9) --let the ball bounce | objects.ball.fixture:setRestitution(0.9) --let the ball bounce | ||
− | --let's create | + | --let's create a couple blocks to play around with |
objects.block1 = {} | objects.block1 = {} | ||
objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic") | objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic") | ||
Line 152: | Line 138: | ||
objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic") | objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic") | ||
objects.block2.body:setMass(300) | objects.block2.body:setMass(300) | ||
− | objects.block2.shape = love.physics.newRectangleShape(0, 0, 50 | + | objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50) |
objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2) | objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
--initial graphics setup | --initial graphics setup | ||
love.graphics.setBackgroundColor(104, 136, 248) --set the background color to a nice blue | love.graphics.setBackgroundColor(104, 136, 248) --set the background color to a nice blue | ||
Line 182: | Line 156: | ||
objects.ball.body:applyForce(-400, 0) | objects.ball.body:applyForce(-400, 0) | ||
elseif love.keyboard.isDown("up") then --press the up arrow key to set the ball in the air | elseif love.keyboard.isDown("up") then --press the up arrow key to set the ball in the air | ||
− | objects.ball.body: | + | objects.ball.body:setPosition(650/2, 650/2) |
end | end | ||
end | end | ||
Line 196: | Line 170: | ||
love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints())) | love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints())) | ||
love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints())) | love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints())) | ||
− | |||
− | |||
end | end | ||
</source> | </source> |
Revision as of 20:56, 15 April 2012
In this example we will create a red ball that rolls around on a green ground.
The finished example is at the end of this page. All of these functions may be placed in one file: main.lua
We'll start in the love.load function.
love.load()
First we need to set up a world for the physics bodies to exist in.
function love.load()
love.physics.setMeter(64) --the height of a meter our worlds will be 64px
world = love.physics.newWorld(0, 9.81*64, true) --create a world for the bodies to exist in with horizontal gravity of 0 and vertical gravity of 9.81
Now that a world has been created, we can add bodies, shapes, and fixture to it.
objects = {} -- table to hold all our physical objects
--let's create the ground
objects.ground = {}
objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) --remember, the shape (the rectangle we create next) anchors to the body from its center, so we have to move it to (650/2, 650-50/2)
objects.ground.shape = love.physics.newRectangleShape(0, 0, 650, 50) --anchor the shape to the body, and make it a width of 650 and a height of 50
objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) --attach shape to body
--let's create a ball
objects.ball = {}
objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") --place the body in the center of the world and make it dynamic, so it can move around
objects.ball.body:setMass(15) --give it a mass of 15
objects.ball.shape = love.physics.newCircleShape(0, 0, 20) --the ball's shape has no offset from it's body and has a radius of 20
objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1.0) --attach shape to body and give it a friction of 1.0
objects.ball.fixture:setRestitution(0.9) --let the ball bounce
--let's create a couple blocks to play around with
objects.block1 = {}
objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
objects.block1.body:setMass(3000) --uff, very heavy block at the bottom
objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) --with plenty of friction, will be hard to move around
objects.block2 = {}
objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
objects.block2.body:setMass(300)
objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)
Now to wrap up the love.load function, let's set up the screen size and background color.
--initial graphics setup
love.graphics.setBackgroundColor(104, 136, 248) --set the background color to a nice blue
love.graphics.setMode(650, 650, false, true, 0) --set the window dimensions to 650 by 650 with no fullscreen, vsync on, and no antialiasing
end
Okay, that's enough for the initial set up of the physics engine. Now we need do edit the love.update() function.
love.update()
function love.update(dt)
world:update(dt) --this puts the world into motion
--here we are going to create some keyboard events
if love.keyboard.isDown("right") then --press the right arrow key to push the ball to the right
objects.ball.body:applyForce(400, 0)
elseif love.keyboard.isDown("left") then --press the left arrow key to push the ball to the left
objects.ball.body:applyForce(-400, 0)
elseif love.keyboard.isDown("up") then --press the up arrow key to set the ball in the air
objects.ball.body:setPosition(650/2, 650/2)
end
end
Now that the world is updating, we can draw the ground and ball.
love.draw()
First, the ground.
function love.draw()
love.graphics.setColor(72, 160, 14) -- set the drawing color to green for the ground
love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- draw a "filled in" polygon using the ground's coordinates
And finally, we can draw the circle that represents the ball and the blocks.
love.graphics.setColor(193, 47, 14) --set the drawing color to red for the ball
love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius(), 20) -- we want 20 line segments to form the "circle"
love.graphics.setColor(50, 50, 50) -- set the drawing color to grey for the blocks
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
There you have it! Put this file in a zip file, rename it to physics.love (or whatever), run it. And you'll have a ball rolling around in a lush green environment like I promised.
The main.lua
function love.load()
love.physics.setMeter(64) --the height of a meter our worlds will be 64px
world = love.physics.newWorld(0, 9.81*64, true) --create a world for the bodies to exist in with horizontal gravity of 0 and vertical gravity of 9.81
objects = {} -- table to hold all our physical objects
--let's create the ground
objects.ground = {}
objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) --remember, the shape (the rectangle we create next) anchors to the body from its center, so we have to move it to (650/2, 650-50/2)
objects.ground.shape = love.physics.newRectangleShape(0, 0, 650, 50) --anchor the shape to the body, and make it a width of 650 and a height of 50
objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape); --attach shape to body
--let's create a ball
objects.ball = {}
objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") --place the body in the center of the world and make it dynamic, so it can move around
objects.ball.body:setMass(15) --give it a mass of 15
objects.ball.shape = love.physics.newCircleShape(0, 0, 20) --the ball's shape has no offset from it's body and has a radius of 20
objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1.0) --attach shape to body and give it a friction of 1.0
objects.ball.fixture:setRestitution(0.9) --let the ball bounce
--let's create a couple blocks to play around with
objects.block1 = {}
objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
objects.block1.body:setMass(3000) --uff, very heavy block at the bottom
objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) --with plenty of friction, will be hard to move around
objects.block2 = {}
objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
objects.block2.body:setMass(300)
objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)
--initial graphics setup
love.graphics.setBackgroundColor(104, 136, 248) --set the background color to a nice blue
love.graphics.setMode(650, 650, false, true, 0) --set the window dimensions to 650 by 650
end
function love.update(dt)
world:update(dt) --this puts the world into motion
--here we are going to create some keyboard events
if love.keyboard.isDown("right") then --press the right arrow key to push the ball to the right
objects.ball.body:applyForce(400, 0)
elseif love.keyboard.isDown("left") then --press the left arrow key to push the ball to the left
objects.ball.body:applyForce(-400, 0)
elseif love.keyboard.isDown("up") then --press the up arrow key to set the ball in the air
objects.ball.body:setPosition(650/2, 650/2)
end
end
function love.draw()
love.graphics.setColor(72, 160, 14) -- set the drawing color to green for the ground
love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- draw a "filled in" polygon using the ground's coordinates
love.graphics.setColor(193, 47, 14) --set the drawing color to red for the ball
love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius(), 20) -- we want 20 line segments to form the "circle"
love.graphics.setColor(50, 50, 50) -- set the drawing color to grey for the blocks
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
Other languages
Dansk –
Deutsch –
English –
Español –
Français –
Indonesia –
Italiano –
Lietuviškai –
Magyar –
Nederlands –
Polski –
Português –
Română –
Slovenský –
Suomi –
Svenska –
Türkçe –
Česky –
Ελληνικά –
Български –
Русский –
Српски –
Українська –
עברית –
ไทย –
日本語 –
正體中文 –
简体中文 –
Tiếng Việt –
한국어
More info