Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Last active December 16, 2015 19:39
Show Gist options
  • Save dermotbalson/5487143 to your computer and use it in GitHub Desktop.
Save dermotbalson/5487143 to your computer and use it in GitHub Desktop.
timers
function setup()
--set up parameters so we can watch the FPS
parameter.boolean("Smoothing",false)
parameter.integer("FPS_One",1,65,60)
parameter.integer("FPS_Ave60",1,65,60)
parameter.integer("FPS_Weighted",1,65,60)
--and the balloon count
parameter.integer("Balloon_Count",0,1000,0)
balls={} --to hold balloon details
ballInterval=.1 --new balloon every 0.1 sec
maxBalls=600
t=0 --timer used for new balloons
end
function draw()
background(159, 189, 196, 255)
FPS_One=1/DeltaTime
FPS_Ave60=FPS.SpeedAve()
FPS_Weighted=FPS.SpeedWeight()
t=t+DeltaTime --or t=ElapsedTime --from when program started
--add new ball if t> interval to next ball (and if max not exceeded)
if t>ballInterval and #balls<maxBalls then
balls[#balls+1]={
x=math.random(0,WIDTH), --random screen position
y=math.random(0,HEIGHT),
s=math.random(20,80), --diameter
vx=math.random(-60,60), -- x speed in pixels/sec
vy=math.random(-60,60),
--note alpha (last item in color) is set low, so balloons look transparent
c=color(math.random(0,255),math.random(0,255),math.random(0,255),math.random(50,150))
}
--deduct interval
t=t-ballInterval
Balloon_Count=#balls
end
--manage ball position and draw them
--if user wants smoothing, use DeltaTime, else assume time interval of 1/60 second
local interval
if Smoothing then interval=DeltaTime else interval=1/60 end
pushStyle()
for i=1,#balls do
--adjust x position
balls[i].x=balls[i].x+balls[i].vx*interval
--calculate position of left hand side of balloon
--remember balls[i].x measures the centre, so the left hand side is one radius to the left
local x=balls[i].x-balls[i].s/2 --deduct half diameter
if x<0 then --we've hit the left side
balls[i].vx=-balls[i].vx --reverse direction
balls[i].x=balls[i].x-x --bounce back by the same amount we went too far
end
--do same test for right hand side
x=WIDTH- balls[i].x-balls[i].s/2
if x<0 then
balls[i].vx=-balls[i].vx
balls[i].x=balls[i].x+x
end
--test bottom
balls[i].y=balls[i].y+balls[i].vy*interval
local y=balls[i].y-balls[i].s/2
if y<0 then
balls[i].vy=-balls[i].vy
balls[i].y=balls[i].y-y
end
--test top
y=HEIGHT- balls[i].y-balls[i].s/2
if y<0 then
balls[i].vy=-balls[i].vy
balls[i].y=balls[i].y+y
end
--draw ball in new position
fill(balls[i].c)
ellipse(balls[i].x,balls[i].y,balls[i].s)
end
popStyle()
end
--the remaining code is to measure the drawing speed in Frames Per Second (FPS)
--codea tries to redraw at 60 FPS, and our eyes can distinguish about 24 FPs
--The FPS functions are held in a table rather than a class
--because we're not going to store any data in them
--and we don't need more than one of them, so we don't need the "self" property
--provided by a class
--You don't really need to put these functions in a table at all, because they
--are so simple, but I'm just reminding you of various techniques (eg using a
--table to store utility functions)
FPS={}
FPS.s=60 --starting frames per second
function FPS.SpeedWeight() -- from user JMV38
--this method uses weights, 0.9 and 0.1, to gradually
--give more importance to newer observations
--each new observation has a weight of 0.1 or 10%, which reduces
--after each redraw, because it is multiplied by 0.9
--The nice thing about this method is it only requires storing one number
FPS.s = FPS.s*0.9+ 1/(DeltaTime)*0.1
return FPS.s
end
--this second method uses the average of the past 10 drawing intervals
--it is fairer than the method above but more cumbersome because
--you have to store the past 10 observations
--even if Lua tables make this quite easy to do
FPS.n=10 --number of observations to average
FPS.t={}
function FPS.SpeedAve()
if FPS.ave==nil then
for i=1,FPS.n do
FPS.t[i]=60 --starting set of speeds
end
FPS.ave=60
end
FPS.t[#FPS.t+1]=1/DeltaTime --speed of latest observation
--there's no need to add up and average all 10 observations
--all we need to do is remove the oldest one and add the latest one
FPS.ave=(FPS.ave*FPS.n+1/DeltaTime-FPS.t[1])/FPS.n --adjust average
table.remove(FPS.t,1) --remove oldest observation
return FPS.ave
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment