# Crates: A Physics Experiment

Well, good evening! There was another topic someone posted a while back which had a very simple example of a box, a ball and a floor. I played with it a bit (longer than I care to admit) and created some code that I think may help others to understand the physics of Codea and using sprites.

Also, I can’t help but think there are some code-saving steps I’m missing.

Enjoy, and feel free to offer any feedback!

``````
--# Main
-- Crates
function setup()
saveProjectInfo("Description", "An Experiment in Physics")
supportedOrientations(LANDSCAPE_RIGHT)
displayMode(FULLSCREEN)
angle = 0
spin = 0
strokeWidth(5)
stroke(116, 62, 39, 255)
Objects:init()
--This command establishes all the important information we need about our objects.
touches = {}
end

function drawPoly(body)
--This is an invaluable (if not complicated-looking) function from the Physics Lab
--example that draws the lines of a polygon on the screen. Renamed for simplicity.
pushMatrix()
translate(body.x, body.y)
rotate(body.angle)
if body.shapeType == POLYGON then
local points = body.points
local a, b
for j = 1,#points do
a = points[j]
b = points[(j % #points)+1]
line(a.x, a.y, b.x, b.y)
end end
popMatrix()
end

function draw()
background(40, 40, 50)
physics.gravity(Gravity)
--This uses the device orientation as Gravity input. This must be done in the draw()
--function so that the orientation is re-assessed every frame.
Objects:text()
--Because we draw the text first, it will appear BEHIND out background image.
sprite("Cargo Bot:Opening Crates",WIDTH/2, 296,WIDTH,296*2)
--This doesn't serve any practical purpose aside from drawing a pretty background.
drawPoly(walls)
--This command draws the lines of a polygon, in this case, the walls.
drawPoly(crate)
drawPoly(crate2)
drawPoly(crate3)
drawPoly(gold)
--These command draw the lines of the crates. Comment these out if you only
--want to see the sprites
Objects:draw()
--This draws the sprites at the exact location of the polygons! Neat, huh?
if CurrentTouch.state == BEGAN or CurrentTouch.state == MOVING then
if CurrentTouch.x < WIDTH/2 then
spin = 500
gold:applyTorque(spin) end
if CurrentTouch.x > WIDTH/2 then
spin = -500
gold:applyTorque(spin) end
end
--This bit of nonsense makes the gold crate spin in the direction of the touch.
end

--# Objects
Objects = class()

function Objects:init()
--This command establishes all the important information we need about our objects.
walls = physics.body(POLYGON, vec2(1,0), vec2(WIDTH,0), vec2(WIDTH,HEIGHT),
vec2(0,HEIGHT), vec2(0,1), vec2(20,21), vec2(20,HEIGHT-20),
vec2(WIDTH-20,HEIGHT-20), vec2(WIDTH-20, 20), vec2(21,20))
--All these positions might look daunting, but dont worry: These are just
--the points of the walls around our experiment.
walls.type = STATIC
--"STATIC" means "STATIONARY";They don't get to bounce around like our crate.

--All of the following is information used to create our crate. Remember, this only
--creates the "idea" of the crate. In order to see it on the screen, we need to either
--make Codea draw the lines, or draw a sprite at the exact location of the "idea".
--Sorry if that sounds a bit philosophical ;)
crate = physics.body(POLYGON, vec2(0,0), vec2(100,0), vec2(100,100), vec2(0,100))
--This creates the shape of the crate. (0,0) refers to the position of the shape,
--not a position on the screen
crate.type = DYNAMIC
--This means the shape can move around, unlike our walls
crate.x = WIDTH*.25
crate.y = HEIGHT/2
--The position on the screen. If this is done in draw(), the box will not be able
--to move since you're telling Codea where to put it every frame
crate.restitution = .6
--How much the crate bounces... Try playing with numbers between 0 and 2.
crate.sleepingAllowed = false
--This command prevents objects from sleeping AKA locking in place once stopped
crate.angle = 40
--The angle the shape STARTS at. Again, if this is located in draw(), then you're
--telling Codea what the angle MUST be instead of letting it change.

crate2 = physics.body(POLYGON, vec2(0,0), vec2(100,0), vec2(100,100), vec2(0,100))
--This creates a second crate with slightly different values
crate2.type = DYNAMIC
crate2.x = WIDTH*.5
crate2.y = HEIGHT/2
crate2.restitution = .7
crate2.sleepingAllowed = false
crate2.angle = 80

crate3 = physics.body(POLYGON, vec2(0,0), vec2(100,0), vec2(100,100), vec2(0,100))
crate3.type = DYNAMIC
crate3.x = WIDTH*.75
crate3.y = HEIGHT/2
crate3.restitution = .8
crate3.sleepingAllowed = false
crate3.angle = 15

gold = physics.body(POLYGON, vec2(0,0), vec2(100,0), vec2(100,100), vec2(0,100))
gold.type = DYNAMIC
gold.x = WIDTH*.5
gold.y = HEIGHT/4
gold.restitution = .5
gold.sleepingAllowed = false
end

function Objects:draw()
pushMatrix()
--The rotating of the crate image must be done in a "matrix", otherwise the
--rotation command will turn everything on the screen!
translate(crate.x, crate.y)
--"translate" reorients the position of (0,0). In this case, the position of the
--crate is now (0,0), no matter where on the screen it appears!
rotate(crate.angle)
--So long as the sprite and the polygon rotate at exactly the same angle, they
--will overlap exactly.
sprite("Cargo Bot:Title Large Crate 1", 50,50, 100, 100)
--Since (0,0) was reset to the polygon's exact position, we need to make sure that
--the sprite corresponds to the "new" (0,0)
popMatrix()

pushMatrix()
--This will draw a sprite for our second crate
translate(crate2.x, crate2.y)
rotate(crate2.angle)
sprite("Cargo Bot:Title Large Crate 2", 50,50, 100, 100)
popMatrix()

pushMatrix()
translate(crate3.x, crate3.y)
rotate(crate3.angle)
sprite("Cargo Bot:Title Large Crate 3", 50,50, 100, 100)
popMatrix()

pushMatrix()
translate(gold.x, gold.y)
rotate(gold.angle)
sprite("Cargo Bot:Crate Yellow 2", 50,50, 100, 100)
popMatrix()
end

function Objects:text()
pushMatrix()
angle = angle + .5
if angle > 360 then angle = 0 end
translate(WIDTH/2,HEIGHT/2)
rotate(angle)
fontSize(70)
font("HoeflerText-Black")
fill(116, 62, 39, 255)
text("Bounce The Crates!",0,0)
popMatrix()
end
``````

Thanks! many things got more clear now, great boost for a starter.