Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Physics
--# Main
--ignore the lines below,they help manage the code tabs
tabs={} f=""
for i=1,6 do f=f.."P"..i.."={} table.insert(tabs,P"..i..") " end
ff=loadstring(f) ff() ff=nil f=nil
--This code manages which Code tab is run
--it remembers your last choice, and if you select a different one, it runs that instead
function setup()
LastCode=readProjectData("Code") or 1
parameter.integer("Choose_a_tab",1,#tabs,LastCode,RunCode)
grav=physics.gravity()
end
function RunCode()
output.clear()
saveProjectData("Code",Choose_a_tab)
print("CODE "..Choose_a_tab)
if c and c.cleanup then c.cleanup() end
c=tabs[Choose_a_tab]
c.setup()
end
function draw()
output.clear()
for i=1,#tabs do print(i,"=",tabs[i].description()) end
c.draw()
end
function touched(touch)
if c.touched then c.touched(touch) end
end
--# P1
-- P1
--create one ball that moves across the screen and feels gravity
--but it disappears off the edges!
function P1.setup()
p = physics.body(CIRCLE,50) --create physics ball, radius 50 pixels
p.restitution = .8 --very bouncy
--Now give it some velocity (velocity is in pixels per second, ie per 60 redraws)
p.linearVelocity = vec2(math.random(100,400),math.random(100,400))
p.x = math.random(60,250) --POSITION it randomly on the screen
p.y = math.random(400,600)
--choose a random colour for the ball
pColor=color(math.random(0,255),math.random(0,255),math.random(0,255),100)
end
function P1.draw()
background(220)
fill(pColor)
ellipse(p.x,p.y,100) --draw ellipse over the physics object, diameter 100 pixels
end
function P1.description()
return "One ball falling"
end
function P1.cleanup() --get rid of physics object if we switch to another tab
p:destroy()
end
--# P2
-- P2
--add floor and walls for ball to bounce off
--- ********* < shows code changes
function P2.setup()
p = physics.body(CIRCLE,50) --create physics ball, radius 50 pixels
p.restitution = .8 --very bouncy
--Now give it some velocity (velocity is in pixels per second, ie per 60 redraws)
p.linearVelocity = vec2(math.random(100,400),math.random(100,400))
p.x = math.random(60,250) --POSITION it randomly on the screen
p.y = math.random(400,600)
--choose a random colour for the ball
pColor=color(math.random(0,255),math.random(0,255),math.random(0,255),100)
--create floor and walls *******************************************
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0)) -----bottom
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT)) ---left side
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT)) --right side
end
function P2.draw()
background(220)
fill(pColor)
ellipse(p.x,p.y,100) --draw ellipse over the physics object, diameter 100 pixels
end
function P2.description()
return "One ball bouncing off walls"
end
function P2.cleanup() --get rid of physics object if we switch to another tab
p:destroy()
w1:destroy()
w2:destroy()
w3:destroy()
end
--# P3
-- P3
--add more balls
--put code in functions
function P3.setup()
balls={} -- create table of 5 physics objects ************
for i=1,5 do
balls[i]=P3.CreateBall()
end
P3.CreateWalls()
end
function P3.CreateBall() -- function to create a physics object **********
local p = physics.body(CIRCLE,50)
p.restitution = .8
--Now give it some velocity (velocity is in pixels per second, ie per 60 redraws)
p.linearVelocity = vec2(math.random(100,400),math.random(100,400))
--POSITION it randomly on the screen
p.x = math.random(60,250)
p.y = math.random(400,600)
p.color=color(math.random(0,255),math.random(0,255),math.random(0,255),100)
return p
end
function P3.CreateWalls() ---create walls *********
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
end
function P3.draw()
background(220)
pushStyle()
fill(255,255,0)
for i=1,#balls do
fill(balls[i].color)
ellipse(balls[i].x,balls[i].y,100)
end
popStyle()
end
function P3.description()
return "Several balls bouncing"
end
function P3.cleanup() --get rid of physics objects if we switch to another tab
for i=1,#balls do
balls[i]:destroy()
end
balls=nil
w1:destroy()
w2:destroy()
w3:destroy()
end
--# P4
-- P4
--instead of balls falling to the floor, let's do a tabletop
--now the balls are rolling round a table
--we do this by simply turning off gravity
function P4.setup()
balls={} -- create table of 5 physics objects
for i=1,5 do
balls[i]=P4.CreateBall()
end
P4.CreateWalls()
physics.gravity(0,0) -- turn off gravity **************
end
function P4.CreateBall() -- function to create a physics object
local p = physics.body(CIRCLE,50)
p.restitution = .8
--Now give it some velocity (velocity is in pixels per second, ie per 60 redraws)
p.linearVelocity = vec2(math.random(100,400),math.random(100,400))
--POSITION it randomly on the screen
p.x = math.random(60,250)
p.y = math.random(400,600)
p.color=color(math.random(0,255),math.random(0,255),math.random(0,255),100)
return p
end
function P4.CreateWalls() ---create walls
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
w4 = physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT)) --- put in top wall too **********
end
function P4.draw()
background(220)
pushStyle()
fill(255,255,0)
for i=1,#balls do
fill(balls[i].color)
ellipse(balls[i].x,balls[i].y,100)
end
popStyle()
end
function P4.description()
return "Balls rolling around table"
end
function P4.cleanup() --get rid of physics objects if we switch to another tab
for i=1,#balls do
balls[i]:destroy()
end
balls=nil
w1:destroy()
w2:destroy()
w3:destroy()
w4:destroy()
physics.gravity(grav.x,grav.y) --restore default
end
--# P5
-- P5
--instead of balls falling to the floor, let's do a tabletop
--now the balls are rolling round a table
--we do this by simply turning off gravity
function P5.setup()
rects={} --create table of rectangles **********
w=100 --width
h=80 --height
for i=1,5 do
rects[i]=P5.CreateRect(w,h)
end
P5.CreateWalls()
physics.gravity(0,0) -- turn off gravity **************
end
function P5.CreateRect(w,h) -- function to create a physics object
local p = physics.body(POLYGON,vec2(-w/2,h/2),vec2(-w/2,-h/2),vec2(w/2,-h/2),vec2(w/2,h/2))
p.restitution = .8
--Now give it some velocity (velocity is in pixels per second, ie per 60 redraws)
p.linearVelocity = vec2(math.random(100,400),math.random(100,400))
--POSITION it randomly on the screen
p.x = math.random(60,250)
p.y = math.random(400,600)
p.color=color(math.random(0,255),math.random(0,255),math.random(0,255),100)
return p
end
function P5.CreateWalls() ---create walls
w1 = physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
w2 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
w3 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
w4 = physics.body(EDGE,vec2(0,HEIGHT),vec2(WIDTH,HEIGHT)) --- put in top wall too **********
end
function P5.draw()
background(220)
pushStyle()
fill(255,255,0)
for i=1,#rects do
fill(rects[i].color)
local x,y=rects[i].x,rects[i].y
pushMatrix()
translate(x,y)
rotate(rects[i].angle)
rect(-w/2,-h/2,w,h)
popMatrix()
end
popStyle()
end
function P5.description()
return "Rectangles spinning"
end
function P5.cleanup() --get rid of physics objects if we switch to another tab
for i=1,#rects do
rects[i]:destroy()
end
rects=nil
w1:destroy()
w2:destroy()
w3:destroy()
w4:destroy()
physics.gravity(grav.x,grav.y) --restore default
end
--# P6
-- P6
--make a character walk and jump
--make it full screen
function P6.setup()
displayMode(FULLSCREEN)
P6.CreateScene() --set up scene
P6.SetupChar()
end
function P6.draw()
background(220)
P6.DrawScene()
P6.DrawChar()
P6.ShowInstructions()
end
function P6.SetupChar()
char=readImage("Planet Cute:Character Boy") --read in image (change it if you like)
ch = physics.body(CIRCLE,char.width/2) --create physics circle, radius = 1/2 height of char
ch.x=30
ch.y=floorHeight+100
ch.restitution = .1 --not very bouncy
ch.linearVelocity = vec2(0,0)
ch.x = WIDTH/2 --POSITION it randomly on the screen
ch.y = HEIGHT/2
end
function P6.CreateScene()
--do floor first
floorHeight=50 --floor
floor=physics.body(EDGE,vec2(0,floorHeight),vec2(WIDTH,floorHeight))
--now do platforms
gap=150 --vertical gap between platforms
plat={}
plat[1]={x1=200,x2=450,y=floorHeight+gap}
plat[2]={x1=400,x2=700,y=floorHeight+2*gap}
plat[3]={x1=650,x2=900,y=floorHeight+gap}
--create physics objects for platforms
for i=1,#plat do
plat[i].body=physics.body(EDGE,vec2(plat[i].x1,plat[i].y),vec2(plat[i].x2,plat[i].y))
end
--set visible platform depth
platDepth=5 --pixels
--side walls
w1 = physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT)) ---left side
w2 = physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT)) --right side
end
function P6.DrawScene()
pushStyle()
--draw ground as solid rectangle
fill(185, 157, 140, 255)
rect(0,0,WIDTH,floorHeight)
--draw floor on top, as a thick line
stroke(62, 121, 181, 255) --line colour
strokeWidth(5) --thick line
line(0,floorHeight-platDepth,WIDTH,floorHeight-platDepth)
--draw platforms
fill(62, 121, 181, 255)
for i=1,#plat do
line(plat[i].x1,plat[i].y-platDepth,plat[i].x2,plat[i].y-platDepth)
end
popStyle()
end
function P6.DrawChar()
sprite(char,ch.x,ch.y)
end
function P6.ShowInstructions()
--write instructions
pushStyle()
fill(255,0,0)
fontSize(24)
textMode(CORNER)
text("Touch middle of screen to jump",50,HEIGHT-80)
text("Touch left/right of screen to walk",50,HEIGHT-120)
text("Touch button at top left of screen for menu controls",50,HEIGHT-160)
popStyle()
end
function P6.touched(touch)
if touch.state==BEGAN then
if touch.x<WIDTH/3 then --left side - go left
ch:applyForce(vec2(-500,0))
elseif touch.x<WIDTH*2/3 then --middle - jump
if ch.linearVelocity.y==0 then ch:applyForce(vec2(0,5000)) end
else --right side, go right
ch:applyForce(vec2(500,0))
end
end
end
function P6.description()
return "A jumping platform game"
end
function P6.cleanup() --get rid of physics object if we switch to another tab
floor:destroy()
for i=1,#plat do
plat[i].body:destroy()
end
w1:destroy()
w2:destroy()
ch:destroy()
displayMode(STANDARD)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment