Skip to content

Instantly share code, notes, and snippets.

@dermotbalson
Last active December 9, 2015 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dermotbalson/e023dbff7b83d3f4340b to your computer and use it in GitHub Desktop.
Save dermotbalson/e023dbff7b83d3f4340b to your computer and use it in GitHub Desktop.
Cut the fruit
function setup()
ReadImages()
tp={} --this will store our swipe points so we can draw a line
fruit={} --the items we will cut
AddFruit() --add the first fruit
FPS=60 --speed checker
end
--read in all the images we will use
function ReadImages()
images={readImage("SpaceCute:Health Heart"),readImage("Tyrian Remastered:Space Ice 5"),
readImage("Small World:House White"),readImage("Small World:Store Extra Large"),
readImage("Planet Cute:Gem Orange"),readImage("Planet Cute:Gem Blue"),readImage("Planet Cute:Enemy Bug")}
end
--drops a new piece of fruit
function AddFruit()
local i=math.random(1,#images)
local img=images[i]
local w,h=img.width,img.height
local pos=vec2((0.2+0.6*math.random())*WIDTH,HEIGHT+100)
--create a rectangle mesh for the image
local m=mesh()
m.vertices={vec2(-w/2,-h/2),vec2(w/2,-h/2),vec2(w/2,h/2),vec2(w/2,h/2),vec2(-w/2,h/2),vec2(-w/2,-h/2)}
m.texCoords={vec2(0,0),vec2(1,0),vec2(1,1),vec2(1,1),vec2(0,1),vec2(0,0)}
m.texture=img
m:setColors(color(255))
--add to our objects table
--replace tells Codea if the object is replaced when it goes off the screen
--it is true except where objects have been split, when only one of the two new objects
--has this set to true
table.insert(fruit,{m=m,pos=pos,w=w,h=h,img=img,angle=0,rot=1,speed=vec2(0,-2),replace=true})
end
function draw()
background(123, 186, 210, 255)
--add a new fruit every three seconds until we have 5 in total
if #fruit<5 and ElapsedTime/7>#fruit then AddFruit() end
FPS=FPS*0.9+0.1/DeltaTime --speed check
text(math.floor(FPS),50,50)
--update and draw the objects
for i,f in pairs(fruit) do
f.angle=f.angle+f.rot --rotation
f.pos=f.pos+f.speed --position
if f.pos.y<-50 then --it's fallen off the screen
if f.replace then AddFruit() end --replace it if necessary
table.remove(fruit,i) --delete it
else --draw it
pushMatrix()
translate(f.pos.x,f.pos.y)
rotate(f.angle)
f.m:draw()
popMatrix()
end
end
-- draw the swipe line, if there is one
stroke(255,255,0)
strokeWidth(4)
for j=1,#tp-1 do line(tp[j].x,tp[j].y,tp[j+1].x,tp[j+1].y) end
end
function touched(t)
if t.state==BEGAN then
tp={vec2(t.x,t.y)} --first swipe point
for i,f in pairs(fruit) do --clear enter,exit values for all objects
f.enter,f.exit=nil,nil
end
elseif t.state==MOVING then
local v=vec2(t.x,t.y)
table.insert(tp,v) --add point to swipe list
for i,f in pairs(fruit) do
local tv=Transform(f,v) --rotate point
if IsInsideFruit(f,tv) then --if inside, set enter or exit point
f.enter = f.enter or tv
elseif f.enter and not f.exit then --we've exited, split the object
f.exit=tv
BreakFruit(i)
end
end
elseif t.state==ENDED then
tp={}
end
end
function IsInsideFruit(f,p)
if f.broken then return end --we can't swipe on split objects, so they have a "broken" property = true
--this prevents them ever returning true for this function, ie they get ignored
if math.abs(p.x-f.pos.x)<f.w/2 and math.abs(p.y-f.pos.y)<f.h/2 then return true end
end
--rotates a point by the negative of the object's angle
function Transform(f,p)
local r=math.rad(-f.angle)
local s,c=math.sin(r),math.cos(r)
local pp=p-f.pos --rotate around the object's centre
return vec2(pp.x*c-pp.y*s,pp.x*s+pp.y*c)+f.pos
end
--used below
function Angle(v)
return math.atan2(v.y,v.x)
end
function BreakFruit(id)
local f=fruit[id]
local p1,p2=f.enter,f.exit
local w,h,w2,h2=f.w,f.h,f.w/2,f.h/2
local c={vec2(-w2,-h2),vec2(w2,-h2),vec2(w2,h2),vec2(-w2,h2)} --corners of image
local p,pp1,pp2=(p1+p2)/2-f.pos,p1-f.pos,p2-f.pos --localised midpoint and ends of cut line
local a1=Angle(pp1-p) --angle of line from p to pp1
local a2=Angle(pp2-p) --angle of line from p to pp2
local v1,v2={{pp1,a1},{pp2,a2}},{{pp1,a1},{pp2,a2}} --add cut points to both tables
if a1>a2 then a1,a2=a2,a1 end --swap them if a2>a1
for i=1,#c do
local a=Angle(c[i]-p) --angle of line from p to c[i]
--if angle is between a1 and a2, add point to first list, else second list
if a>a1 and a<a2 then v1[#v1+1]={c[i],a} else v2[#v2+1]={c[i],a} end
end
--sort both tables by angle
table.sort(v1,function(a,b) return a[2]<b[2] end)
table.sort(v2,function(a,b) return a[2]<b[2] end)
--create two meshes
local m1,m2=mesh(),mesh()
local j
local v,t={},{}
--create triangles
for i=1,#v1 do
v[#v+1]=v1[i][1]
v[#v+1]=p
j=i+1 if j>#v1 then j=1 end
v[#v+1]=v1[j][1]
end
m1.vertices=v
local u=vec2(0,0)
--create texture mappings
for i=1,#v do
t[i]=vec2((v[i].x+w2)/w,(v[i].y+h2)/h)
t[i].x=math.max(0,math.min(1,t[i].x))
t[i].y=math.max(0,math.min(1,t[i].y))
u=u+v[i]
end
--calculate average of vertex positions, this will be the position of this object
local pos=f.pos+u/#v
m1.texCoords=t
m1.texture=f.img
m1:setColors(color(255))
table.insert(fruit,{m=m1,pos=pos,img=img,angle=f.angle,rot=f.rot,speed=vec2(-1,-3),broken=true,replace=true})
--now do it all again for the second object
local v,t={},{}
for i=1,#v2 do
v[#v+1]=v2[i][1]
v[#v+1]=p
j=i+1 if j>#v2 then j=1 end
v[#v+1]=v2[j][1]
end
m2.vertices=v
local u=vec2(0,0)
for i=1,#v do
t[i]=vec2((v[i].x+w2)/w,(v[i].y+h2)/h)
t[i].x=math.max(0,math.min(1,t[i].x))
t[i].y=math.max(0,math.min(1,t[i].y))
u=u+v[i]
end
local pos=f.pos+u/#v
m2.texCoords=t
m2.texture=f.img
m2:setColors(color(255))
table.insert(fruit,{m=m2,pos=pos,img=img,angle=f.angle,rot=-f.rot,speed=vec2(1,-3),broken=true})
--delete the old object
table.remove(fruit,id)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment