From 8dbb5e4ab32cc2e0d105f51fde19dedb5b2bb2bc Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 22 Nov 2005 00:46:56 +0000 Subject: Initial import --- gametypes.bmx | 478 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 gametypes.bmx (limited to 'gametypes.bmx') diff --git a/gametypes.bmx b/gametypes.bmx new file mode 100644 index 0000000..b12972b --- /dev/null +++ b/gametypes.bmx @@ -0,0 +1,478 @@ +' Hardwire +' +' Copyright 2005 Ian Cowburn +' +' $Id$ +' +Strict +Import "types.bmx" +Import "particle.bmx" +Import "sounds.bmx" + +Type Pit + Const WIDTH=10 + Const HEIGHT=14 + + Function X:Int(p:Int) + Return 230+p*32 + End Function + + Function Y:Int(p:Int) + Return 96+p*32 + End Function +End Type + +Type TWire + Const CROSS:Int=0 + Const LEFT_RIGHT:Int=1 + Const TOP_BOTTOM:Int=2 + Const TOP_LEFT:Int=3 + Const TOP_RIGHT:Int=4 + Const BOTTOM_LEFT:Int=5 + Const BOTTOM_RIGHT:Int=6 + + Const DIR_NONE:Int=0 + Const DIR_UP:Int=1 + Const DIR_RIGHT:Int=2 + Const DIR_DOWN:Int=3 + Const DIR_LEFT:Int=4 + + Global rotright:Int[] + Global rotleft:Int[] + Global img:TImage[] + Global dir:Int[][] + Global dx:Int[] + Global dy:Int[] + + Global dirname:String[] + Global typename:String[] + + Field t:Int + + Function Init() + rotright=[0,2,1,4,6,3,5] + rotleft=[0,2,1,5,3,6,4] + + img=[GameGFX.cross,GameGFX.left_right,GameGFX.top_bottom,GameGFX.top_left,GameGFX.top_right,GameGFX.bottom_left,GameGFX.bottom_right] + + ' CROSS LEFT_RIGHT TOP_BOTTOM TOP_LEFT TOP_RIGHT BOTTOM_LEFT BOTTOM_RIGHT + dir=[[DIR_UP,DIR_RIGHT,DIR_DOWN,DIR_LEFT], [DIR_NONE,DIR_RIGHT,DIR_NONE,DIR_LEFT], [DIR_UP,DIR_NONE,DIR_DOWN,DIR_NONE], [DIR_NONE,DIR_UP,DIR_LEFT,DIR_NONE], [DIR_NONE,DIR_NONE,DIR_RIGHT,DIR_UP], [DIR_LEFT,DIR_DOWN,DIR_NONE,DIR_NONE], [DIR_RIGHT,DIR_NONE,DIR_NONE,DIR_DOWN]] + + dx=[0,0,1,0,-1] + dy=[0,-1,0,1,0] + + dirname=["NONE","UP","RIGHT","DOWN","LEFT"] + typename=["CROSS","LEFT_RIGHT","TOP_BOTTOM","TOP_LEFT","TOP_RIGHT","BOTTOM_LEFT","BOTTOM_RIGHT"] + End Function + + Method New() + t=Rand(0,6) + End Method + + Function Create:TWire(t:Int) + Local o:TWire=New TWire + o.t=t + Return o + End Function + + Method Image:TImage() + Return img[t] + End Method + + Method RotateLeft() + t=rotleft[t] + End Method + + Method RotateRight() + t=rotright[t] + End Method + + Method Traverse:Int(d:Int) + If d=DIR_NONE + Return DIR_NONE + EndIf + + Return dir[t][d-1] + End Method + + Function DirX:Int(d:Int) + Return dx[d] + End Function + + Function DirY:Int(d:Int) + Return dy[d] + End Function +End Type + +Type TFallingBlock + Field w:TWire + Field x:Int + Field y:Double + Field yi:Double + + Function Create:TFallingBlock(x:Int, y:Double) + Local o:TFallingBlock=New TFallingBlock + o.w=New TWire + o.x=x + o.y=y + o.yi=0 + Return o + End Function + + Method Update() + y:+yi + yi=Max(4.0,yi+0.1) + End Method + + Method Draw() + SetColor(255,255,255) + DrawImage(GameGFX.tile,Pit.X(x),y) + SetColor(128,128,128) + DrawImage(w.Image(),Pit.X(x),y) + End Method +End Type + +Type TWireListEnt + Field w:TWire + Field x:Int + Field y:Int + + Function Create:TWireListEnt(x:Int, y:Int, w:TWire) + Local o:TWireListEnt=New TWireListEnt + o.x=x + o.y=y + o.w=w + Return o + End Function +End Type + +Type TWireList + Field list:TList + Field col:Int + + Method New() + list=CreateList() + col=128 + End Method + + Method Add(x:Int, y:Int, w:TWire) + list.AddLast(TWireListEnt.Create(x,y,w)) + End Method + + Method Draw:Int() + col=Max(255,col+5) + SetColor(col,col,col) + For Local e:TWireListEnt=EachIn list + DrawImage(e.w.Image(),Pit.X(e.x),Pit.Y(e.y)) + Next + + If col<255 + Return True + Else + For Local e:TWireListEnt=EachIn list + Particles.AddImage(e.w.Image(),Pit.X(e.x),Pit.Y(e.y)) + Next + Return False + EndIf + End Method +End Type + +Type TGameMap + Field map:TWire[Pit.WIDTH,Pit.HEIGHT] + Field trode_col:Int + Field trode_coli:Int + Field overflow:Int + Field top:Int[Pit.WIDTH] + Field drop:TList + Field cx:Int + Field cy:Int + Field path:TList + + Method New() + trode_col=0 + trode_coli=1 + overflow=False + drop=CreateList() + path=CreateList() + CalcTop() + cx=0 + cy=Pit.HEIGHT-2 + End Method + + Method CalcTop() + For Local x:Int=0 Until Pit.WIDTH + top[x]=-1 + For Local y:Int=Pit.Height-1 To 0 Step -1 + If Not map[x,y] + top[x]=y + Exit + EndIf + Next + Next + End Method + + Method AddRow(y:Int=-32) + If BlockInteract() Then Return + + For Local x:Int=0 Until Pit.WIDTH + drop.AddLast(TFallingBlock.Create(x,y)) + Next + End Method + + Method BlockInteract:Int() + Return overflow Or path.Count() + End Method + + Method FindPath:Int(l:TWireList, x:Int, y:Int, dir:Int) + If y<0 + Return False + EndIf + + If x<0 Or x=Pit.WIDTH Or y=Pit.HEIGHT + Return True + EndIf + + Local w:TWire=map[x,y] + + If Not w + Return False + EndIf + + dir=w.Traverse(dir) + + If dir=TWire.DIR_NONE + Return False + EndIf + + l.Add(x,y,w) + + Return FindPath(l,x+TWire.DirX(dir),y+TWire.DirY(dir),dir) + End Method + + Method FindLoop:Int(l:TWireList, ox:Int, oy:Int, x:Int, y:Int, dir:Int) + If y<0 Or x<0 Or x=Pit.WIDTH Or y=Pit.HEIGHT + Return False + EndIf + + Local w:TWire=map[x,y] + + If Not w + Return False + EndIf + + dir=w.Traverse(dir) + + If dir=TWire.DIR_NONE + Return False + EndIf + + l.Add(x,y,w) + + x:+TWire.DirX(dir) + y:+TWire.DirY(dir) + + If x=ox And y=oy + Return True + EndIf + + Return FindLoop(l,ox,oy,x,y,dir) + End Method + + Method CheckWires() + For Local y:Int=0 Until Pit.HEIGHT + Local l:TWireList=New TWireList + + If FindPath(l,0,y,TWire.DIR_RIGHT) + path.AddLast(l) + EndIf + + l=New TWireList + + If FindPath(l,Pit.WIDTH-1,y,TWire.DIR_LEFT) + path.AddLast(l) + EndIf + Next + + For Local x:Int=0 Until Pit.WIDTH + Local l:TWireList=New TWireList + + If FindPath(l,x,Pit.HEIGHT-1,TWire.DIR_UP) + path.AddLast(l) + EndIf + Next + + For Local x:Int=0 Until Pit.WIDTH + For Local y:Int=0 Until Pit.HEIGHT + If map[x,y] + Local l:TWireList=New TWireList + Select map[x,y].t + Case TWire.CROSS, TWire.LEFT_RIGHT, TWire.TOP_LEFT, TWire.BOTTOM_LEFT + If FindLoop(l,x,y,x,y,TWire.DIR_LEFT) + path.AddLast(l) + EndIf + End Select + EndIf + Next + Next + End Method + + Method CursorLeft() + If BlockInteract() Then Return + cx=Max(0,cx-1) + End Method + + Method CursorRight() + If BlockInteract() Then Return + cx=Min(Pit.WIDTH-2,cx+1) + End Method + + Method CursorUp() + If BlockInteract() Then Return + cy=Max(0,cy-1) + End Method + + Method CursorDown() + If BlockInteract() Then Return + cy=Min(Pit.HEIGHT-2,cy+1) + End Method + + Method Rotate() + If BlockInteract() Then Return + Local done:Int=False + For Local x:Int=0 To 1 + For Local y:Int=0 To 1 + If map[cx+x,cy+y] + map[cx+x,cy+y].RotateRight() + done=True + EndIf + Next + Next + + If done + Sound.Click() + EndIf + + CheckWires() + End Method + + Method Draw:Int() + Local score:Int=0 + + SetColor(255,255,255) + DrawImage(GameGFX.pit_bottomleft,Pit.X(-1),Pit.Y(Pit.HEIGHT)) + DrawImage(GameGFX.pit_bottomright,Pit.X(Pit.WIDTH),Pit.Y(Pit.HEIGHT)) + + DrawImage(GameGFX.pit_top,Pit.X(-1),Pit.Y(0)) + DrawImage(GameGFX.pit_top,Pit.X(Pit.WIDTH),Pit.Y(0)) + SetColor(trode_col,trode_col,0) + DrawImage(GameGFX.trode_left,Pit.X(-1),Pit.Y(0)) + DrawImage(GameGFX.trode_right,Pit.X(Pit.WIDTH),Pit.Y(0)) + + For Local f:Int=0 Until Pit.WIDTH + SetColor(255,255,255) + DrawImage(GameGFX.pit_bottom,Pit.X(f),Pit.Y(Pit.HEIGHT)) + SetColor(trode_col,trode_col,0) + DrawImage(GameGFX.trode_bottom,Pit.X(f),Pit.Y(Pit.HEIGHT)) + Next + + For Local f:Int=1 Until Pit.HEIGHT + SetColor(255,255,255) + DrawImage(GameGFX.pit_side,Pit.X(-1),Pit.Y(f)) + DrawImage(GameGFX.pit_side,Pit.X(Pit.WIDTH),Pit.Y(f)) + SetColor(trode_col,trode_col,0) + DrawImage(GameGFX.trode_left,Pit.X(-1),Pit.Y(f)) + DrawImage(GameGFX.trode_right,Pit.X(Pit.WIDTH),Pit.Y(f)) + Next + + For Local x:Int=0 Until Pit.WIDTH + For Local y:Int=0 Until Pit.HEIGHT + If map[x,y] + SetColor(255,255,255) + DrawImage(GameGFX.tile,Pit.X(x),Pit.Y(y)) + SetColor(128,128,128) + DrawImage(map[x,y].Image(),Pit.X(x),Pit.Y(y)) + EndIf + Next + Next + + If BlockInteract() + For Local b:TFallingBlock=EachIn drop + b.Draw() + Next + + Local l:TEasyLink=TEasyLink.Create(path) + Local check:Int=False + + While l.Value() + Local b:TWireList=TWireList(l.Value()) + + If b.Draw() + l.MoveNext() + Else + If Not overflow + score:+b.list.Count() + For Local e:TWireListEnt=EachIn b.list + For Local y:Int=e.y To 1 Step -1 + map[e.x,y]=map[e.x,y-1] + Next + map[e.x,0]=Null + Particles.AddDust(Pit.X(e.x)+16,Pit.Y(e.y)+32) + check=True + Next + EndIf + l.Remove() + EndIf + Wend + + If check + Sound.Path() + CalcTop() + CheckWires() + EndIf + Else + Local hit:Int=False + + Local l:TEasyLink=TEasyLink.Create(drop) + + While l.Value() + Local b:TFallingBlock=TFallingBlock(l.Value()) + Local t:Int=Pit.Y(top[b.x])'-ImageHeight(GameGFX.tile) + + b.Update() + + If b.y>t + If top[b.x]=-1 + overflow=True + b.y=t + l.MoveNext() + Else + hit=True + map[b.x,top[b.x]]=b.w + Particles.AddDust(Pit.X(b.x)+16,Pit.Y(top[b.x])+32) + l.Remove() + EndIf + Else + b.Draw() + l.MoveNext() + EndIf + Wend + + If hit And Not overflow + Sound.Click() + CheckWires() + CalcTop() + EndIf + EndIf + + SetColor(trode_col,trode_col,0) + DrawImage(GameGFX.cursor,Pit.X(cx),Pit.Y(cy)) + + trode_col:+trode_coli + + If (trode_col=255 And trode_coli>0) Or (trode_col=200 And trode_coli<0) + trode_coli=-trode_coli + EndIf + + Return score + End Method +End Type -- cgit v1.2.3