PicoPicoGameEngine

Quick Links

Source Code

g=ppgraph
pos=pppoint

sc=ppscreen
B=sc:size()
Bw=sc:size().width
Bh=sc:size().height

se=ppsemml[1]

sqrt=math.sqrt
floor=math.floor
sin=math.sin
cos=math.cos
rand=math.random

draw=function(s,c)
local p
for i=1,#s.p do
p=s.p[i]
g:line(
  s.v[p[1]],
  s.v[p[2]],c)
end
end

function abs(v)
if v<0 then v=-v end
return v
end

function add(a,b,r)
 local v
 v=pos()
 v.x=a.x+b.x*r
 v.y=a.y+b.y*r
 return v
end

function sub(a,b)
return add(a,b,-1)
end

function nml(p)
local q=pos()
local l
l=p.x*p.x+p.y*p.y
l=sqrt(l)
q.x=p.x/l
q.y=p.y/l
return q
end

function dot(a,b)
local q=pos()
q.x=a.x*b.x
q.y=a.y*b.y
local r
r=q.x+q.y
return r
end

function cross(a,b)
local t
t=a.x*b.y-a.y*b.x
return t
end

function len(a,b)
local dx=a.x-b.x
local dy=a.y-b.y
return dx*dx+dy*dy
end

calccross=function(s,t,ans)
local function
crosspos(a,b,c,d)
local t,n1,n2,u,ab
t=sub(b,a)
ab=t
n1=nml(t)
t=sub(d,c)
n2=nml(t)
w1=dot(n1,n2)
w2=1-w1*w1
u=sub(c,a)
local d1,d2
d1=dot(u,n1)-dot(u,n2)*w1
d1=d1/w2
local aa=pos()
aa.x=a.x+n1.x*d1
aa.y=a.y+n1.y*d1
local bb=pos()
bb.x=aa.x-c.x
bb.y=aa.y-c.y
d2=dot(bb,n2)
if d2<0 then
 return nil
end
local h=pos(aa)
aa.x=aa.x-a.x
aa.y=aa.y-a.y
l2=ab.x*ab.x+ab.y*ab.y
d1=dot(aa,ab)
if d1>=0 and d1<l2 then
h.d=""..floor(d2)..","
      ..floor(l2)
return h
end
end
local a,b
local v,w,z
v=s.v
for i=1,#s.p do
a=s.p[i]
w=t.v
for j=1,#t.p do
b=t.p[j]
z=crosspos(v[a[1]],v[a[2]],
        w[b[1]],w[b[2]])
if z then
ans[#ans+1]=z
end
end
end
end

p1={
 v={
  pos(Bw/2,Bh/2),
  pos(Bw/2-150,Bh),
 },
 p={
  {1,2},
 },
 draw=draw
}

p2={
 v={
  pos(120,50),
  pos(Bw-120,50),
  pos(120,100),
  pos(Bw-120,100),
  pos(120,50),
  pos(120,100),
  pos(Bw-120,50),
  pos(Bw-120,100),

  pos(100,150),
  pos(Bw-100,150),
  pos(100,100+150),
  pos(Bw-100,100+150),
  pos(100,150),
  pos(100,100+150),
  pos(Bw-100,150),
  pos(Bw-100,100+150),

  pos(120,300),
  pos(Bw-120,300),
  pos(120,350),
  pos(Bw-120,350),
  pos(120,300),
  pos(120,350),
  pos(Bw-120,300),
  pos(Bw-120,350),

 },
 p={
  {1,2},
  {3,4},
  {5,6},
  {7,8},
  {1+8,2+8},
  {3+8,4+8},
  {5+8,6+8},
  {7+8,8+8},
  {1+16,2+16},
  {3+16,4+16},
  {5+16,6+16},
  {7+16,8+16},
 },
 draw=draw
}

for i=1,#p2.v do
 p2.v[i].y=p2.v[i].y+(Bh-400)/2
end

o=ppoffscreen.new()
o:create(32,32)
o:circle(16,16,15)

o:pos((Bw-32)/2,(Bh-32)/2)

dd={}

function seover()
 if not gameover then
  se:play("o4cgcgcg")
 end
end

q={}
function viewline(x,y)
local p={}
p.p=pppoint(x,y)
p.q=rand(0,359)*math.pi*2/360
p.r=rand(10,30)/5000
if rand(1,2)==1
then
p.r=-p.r
end
p.idle=function(s,ans)
 ans={}
 if not gameover then
 s.q=s.q+s.r
 end
 local dx,dy
 dx=sin(s.q)*1000
 dy=cos(s.q)*1000
 p1.v[1].x=s.p.x
 p1.v[1].y=s.p.y
 local p=pppoint(s.p.x+dx,
                 s.p.y+dy)
 p1.v[2].x=s.p.x+dx
 p1.v[2].y=s.p.y+dy
 local l=len(p1.v[1],p)
 calccross(p2,p1,ans)
 for i=1,#ans do
  local u=ans[i]
  local m
  m=len(p1.v[1],u)
  if m<l then
   l=m
   p=u
  end
 end
 p1.v[2].x=p.x
 p1.v[2].y=p.y
 local n1=len(
    p1.v[2],p1.v[1])
 local n2=len(
    o+pppoint(16,16),p1.v[1])
 s.aa=0
 if n2<n1 then
  local m1,m2
  m1=nml(
      sub(p1.v[2],p1.v[1]))
  m2=nml(
      sub(o+pppoint(16,16),
          p1.v[1]))
  s.aa=dot(m1,m2)
  if s.aa>0 then
    m1=sub(p1.v[2],p1.v[1])
    m2=sub(o+pppoint(16,16),
           p1.v[1])
    local d
    d=cross(m1,m2)/sqrt(n1)
    if d>-16 and d<16 then
      dd[#dd+1]=
        floor(d)
      seover()
      gameover=true
    end
   end
 end
end
return p
end

score=0
gameover=false
p16=pppoint(16,16)

q[#q+1]=viewline(50,50)
q[#q+1]=viewline(Bw-50,50)
q[#q+1]=viewline(50,Bh-50)
q[#q+1]=viewline(Bw-50,Bh-50)
q[#q+1]=viewline(50,(Bh-32)/2)
q[#q+1]=viewline(Bw-50,(Bh-32)/2)

pt=pppoint(100,100)
pt.draw=function(s)
 g:circle(s+p16,16,g.yellow)
end
pt.set=function(s)
 s.x=rand(16,Bw-16)
 s.y=rand(16,Bh-16)
end
pt:set()

function start()
 dd={}
 if not gameover then
 o:drag(pptouch(),B)
 end
 o:draw()
 pt:draw()
 if len(pt,o)<24*24 then
  pt:set()
  score=score+1
  se:play("o7c")
 end
 local ans={}
 for i=1,#q do
  q[i]:idle(ans)
  g:circle(q[i].p,16,g.red)
  p1:draw(g.red)
  if len(q[i].p,o+p16)<16*16 then
    seover()
    gameover=true
  end
 end
 p2:draw(g.cyan)
 g:print(score)
 if gameover then
   g:pos(88,160)
   g:print("GAME OVER",g.red)
 end
end