' Particle Pinch ' ' Copyright 2005 Ian Cowburn ' ' $Id$ ' Strict Import noddybox.vector Import noddybox.bitmapfont Const MASSSIZE:Int=8 Const MASSRAD:Int=4 Const SHIPSIZE:Int=12 Const SHIPRAD:Int=6 Type Lookup Global si:Double[] Global co:Double[] Function Init() si=New Double[360] co=New Double[360] For Local a:Int=0 To 359 si[a]=Sin(a) co[a]=Cos(a) Next End Function End Type Type GameGFX Global font:TBitmapFont Global smallfont:TBitmapFont Global star:TImage Global ship:TImage Global collector:TImage Global point:TImage Global particle:Timage Global pointer:TImage Global shock:TImage Global play_button:TImage Global edit_button:TImage Global load_button:TImage Global toy_button:TImage Global quit_button:TImage Global left_button:TImage Global right_button:TImage Global scores_button:TImage Global keys_button:TImage End Type Type GameConfig Global kleft:Int Global kright:Int Global kthrust:Int Global kreverse:Int Global kblast:Int Function Load() Local s:TStream=ReadStream("ppinch.config") If s=Null kleft=KEY_O kright=KEY_P kthrust=KEY_Q kreverse=KEY_A kblast=KEY_SPACE Return EndIf s=LittleEndianStream(s) kleft=s.ReadInt() kright=s.ReadInt() kthrust=s.ReadInt() kreverse=s.ReadInt() kblast=s.ReadInt() s.Close() End Function Function Save() Local s:TStream=WriteStream("ppinch.config") If s=Null Return EndIf s=LittleEndianStream(s) s.WriteInt(kleft) s.WriteInt(kright) s.WriteInt(kthrust) s.WriteInt(kreverse) s.WriteInt(kblast) s.Close() End Function EndType Type TGfxObject Field x:Double Field y:Double EndType Type TMass Extends TGfxObject Field v:TVector Field mass:Double Field friend:Int Field inverse:Int Field img:TImage Field swallow:Int Field rad:Int Method New() v=TVector.Create() x=Rnd(0,GraphicsWidth()) y=Rnd(0,GraphicsWidth()) mass=25 friend=True inverse=False swallow=0 rad=MASSRAD End Method Method Attract(o:TMass) If o=Self Return EndIf Local d:TVector=TVector.Create(o.x-x,o.y-y) Local l:Double=d.Length() If l>0.1 l:*l d.Normalise() d.Scale((1/l)*o.mass) If o.inverse d.Minus() EndIf v.Add(d) If v.Length()>MASSSIZE v.SetLength(MASSSIZE) EndIf EndIf End Method Method Move(wrap:Int) x:+v.x y:+v.y If wrap If x<0 x:+GraphicsWidth() EndIf If x>GraphicsWidth() x:-GraphicsWidth() EndIf If y<0 y:+GraphicsHeight() EndIf If y>GraphicsHeight() y:-GraphicsHeight() EndIf Else If x<0 x=0 EndIf If x>GraphicsWidth() x=GraphicsWidth() EndIf If y<0 y=0 EndIf If y>GraphicsHeight() y=GraphicsHeight() EndIf EndIf End Method Method Draw() SetColor(255,255,255) DrawImage(img,x,y,swallow) swallow=0 End Method End Type Type TShip Extends TMass Field a:Int Method New() v=TVector.Create() x=-1 y=-1 mass=25 friend=False inverse=False swallow=0 rad=SHIPRAD a=0 End Method Method RotateLeft() a:-2 If a<0 a:+359 EndIf End Method Method RotateRight() a=(a+2) Mod 360 End Method Method Thrust() v.x:+Lookup.si[a]*0.1 v.y:+Lookup.co[a]*-0.1 If v.Length()>MASSSIZE v.SetLength(MASSSIZE) EndIf End Method Method Reverse() v.x:+Lookup.si[a]*-0.05 v.y:+Lookup.co[a]*0.05 If v.Length()>MASSSIZE v.SetLength(MASSSIZE) EndIf End Method Method Draw() SetColor(255,255,255) SetRotation(a) DrawImage(img,x,y) SetRotation(0) swallow=0 End Method End Type Type TPoint Extends TGfxObject Global img:TImage Field lx:Double Field ly:Double Field v:TVector Field r:Int Field g:Int Field b:Int Field dead:Int Field lost:Int Method New() v=TVector.Create() x=Rnd(0,GraphicsWidth()) y=Rnd(0,GraphicsWidth()) lx=x ly=y r=Rand(100,200) g=Rand(100,200) b=Rand(100,200) dead=False lost=False End Method Method Attract:Int(o:TMass) If dead Or lost Return EndIf Local d:TVector=TVector.Create(o.x-x,o.y-y) Local l:Double=d.Length() If lMASSRAD v.SetLength(MASSRAD) EndIf EndIf Return dead End Method Method Move(wrap:Int=False) If (Not dead) And (Not lost) lx=x ly=y x:+v.x y:+v.y If wrap If x<0 x:+GraphicsWidth() EndIf If x>GraphicsWidth() x:-GraphicsWidth() EndIf If y<0 y:+GraphicsHeight() EndIf If y>GraphicsHeight() y:-GraphicsHeight() EndIf Else If x<0 Or y<0 Or x>GraphicsWidth() Or y>GraphicsHeight() lost=True TParticleMachine.AddLost(Self) EndIf EndIf EndIf End Method Method Draw() If (Not dead) And (Not lost) SetColor(r,g,b) DrawImage(img,x,y,0) EndIf End Method End Type Type TParticle Global img:TImage Field parent:TGfxObject Field x:Double Field y:Double Field a:Double Field r:Int Field g:Int Field b:Int Field dx:Double Field dy:Double Field ai:Double Function FromLostPoint:TParticle(p:TPoint, d:Int) Local o:TParticle=New TParticle o.x=p.lx'-p.v.x*d o.y=p.ly'-p.v.y*d o.dx=-p.v.x*d o.dy=-p.v.y*d o.r=p.r o.g=p.g o.b=p.b o.a=1 o.ai=-0.05 Return o End Function Function FromCapturedPoint:TParticle(p:TPoint, d:Int) Local o:TParticle=New TParticle o.x=p.x o.y=p.y o.dx=Rnd(-1,1) o.dy=Rnd(-1,1) o.r=p.r o.g=p.g o.b=p.b o.a=1 o.ai=-0.05 Return o End Function Function FromCoord:TParticle(x:Int, y:Int) Local o:TParticle=New TParticle o.x=x o.y=y o.dx=Rnd(-2,2) o.dy=Rnd(-2,2) o.r=Rand(128,255) o.g=Rand(128,255) o.b=Rand(128,255) o.a=1 o.ai=-0.01 Return o End Function Function Angular:TParticle(x:Int, y:Int, a:Int, sp:Double, r:Int, g:Int, b:Int, al:Double, ali:Double, parent:TGfxObject) Local o:TParticle=New TParticle o.parent=parent o.x=x o.y=y o.dx=sp*Lookup.si[a] o.dy=sp*Lookup.co[a] o.r=r o.g=g o.b=b o.a=al o.ai=ali Return o End Function Method Update() x:+dx y:+dy a:+ai If a>0 SetAlpha(a) SetColor(r,g,b) If parent DrawImage(img,parent.x+x,parent.y+y) Else DrawImage(img,x,y) EndIf EndIf End Method End Type Type TParticleMachine Global list:TList Function Init() list=CreateList() End Function Function Clear() list.Clear() End Function Function AddLost(p:TPoint) For Local f:Int=0 To 5 list.AddLast(TParticle.FromLostPoint(p,f)) Next End Function Function AddCaptured(p:TPoint) For Local f:Int=0 To 5 list.AddLast(TParticle.FromCapturedPoint(p,f)) Next End Function Function AddFirework(x:Int, y:Int) For Local f:Int=0 To 20 list.AddLast(TParticle.FromCoord(x,y)) Next End Function Function AddShockwave(o:TGfxObject) For Local a:Int=0 To 359 list.AddLast(TParticle.Angular(0,0,a,1.0,255,255,0,1,-0.01,o)) list.AddLast(TParticle.Angular(0,0,a,Rnd(0.8,1.2),255,0,0,1,-0.01,o)) list.AddLast(TParticle.Angular(0,0,a,Rnd(0.8,1.2),255,0,0,1,-0.01,o)) list.AddLast(TParticle.Angular(0,0,a,Rnd(0.8,1.2),255,0,0,1,-0.01,o)) Next End Function Function Process() Local l:TLink=list.FirstLink() Local t:TLink While l<>Null Local p:TParticle=TParticle(l.Value()) p.Update() If p.a<0.01 t=l.NextLink() l.Remove() l=t Else l=l.NextLink() EndIf Wend SetAlpha(1) SetColor(255,255,255) End Function End Type