From 26c98ba56e72beaf8a99eafbedd2b0c64ac13954 Mon Sep 17 00:00:00 2001 From: Ian C Date: Sat, 27 May 2006 23:24:02 +0000 Subject: Updates --- GFX/small.bmf | Bin 9888 -> 24544 bytes HELP/help.txt | 162 ++--- game.bmx | 676 ++++++++++---------- gametypes.bmx | 1937 +++++++++++++++++++++++++++++---------------------------- hardwire.bmx | 770 ++++++++++++----------- help.bmx | 598 +++++++++--------- particle.bmx | 652 +++++++++---------- sounds.bmx | 124 ++-- types.bmx | 886 +++++++++++++------------- 9 files changed, 2973 insertions(+), 2832 deletions(-) diff --git a/GFX/small.bmf b/GFX/small.bmf index 16d8db4..b2f51f5 100644 Binary files a/GFX/small.bmf and b/GFX/small.bmf differ diff --git a/HELP/help.txt b/HELP/help.txt index 0d98d52..190aa53 100644 --- a/HELP/help.txt +++ b/HELP/help.txt @@ -1,81 +1,81 @@ - -@THE RULES - -You start with an empty pit that has electrodes -down the sides and at the bottom. - -#incbin::HELP/pit.png - -You must connect these using geometric -shapes that fall from the sky which have -wires embedded in the blocks... - -#incbin::HELP/piece.png - -I'm sure you'll (cough) recognise the shapes. - -Once a piece has landed in the pit if a -connection can be made between electrodes, -or a loop of wires can be made, then these -are removed and you score lovely points... - -#incbin::HELP/wire1.png - -#incbin::HELP/loop1.png - -If a connection cannot be made, as in this one: - -#incbin::HELP/wire2.png - -Then the peices are unglued and any hanging bits -drop down into the pit to make other possible -loops... - -#incbin::HELP/wire3.png - -If a piece lands with anything sticking out of the -top of the pit, it's GAME OVER. - - -@SPECIAL PIECES - -Once in a while a special piece may drop down... - - -!SMART BOMB - -$incbin::HELP/bomb.png - -This special will destroy all blocks that are the -same as the one it lands on. Landing on nothing -is perhaps not a good idea... - - -!TWISTER - -$incbin::HELP/twister.png - -The twister will rotate all the pieces in the pit -four times, scoring any loops and wires that -are made from doing this. - - -!SMART NUKE - -$incbin::HELP/nuke.png - -The smart nuke destroy all blocks that match -the blocks surrounding the point were it lands. - - -!SUPER CROSS - -~incbin::HELP/cross.png - -This will change all blocks above, below and to -the left and right radiating out from the -special to cross pieces. - - -* * * * * * * * * * * * * - + +@THE RULES + +You start with an empty pit that has electrodes +down the sides and at the bottom. + +#incbin::HELP/pit.png + +You must connect these using geometric +shapes that fall from the sky which have +wires embedded in the blocks... + +#incbin::HELP/piece.png + +I'm sure you'll (cough) recognise the shapes. + +Once a piece has landed in the pit if a +connection can be made between electrodes, +or a loop of wires can be made, then these +are removed and you score lovely points... + +#incbin::HELP/wire1.png + +#incbin::HELP/loop1.png + +If a connection cannot be made, as in this one: + +#incbin::HELP/wire2.png + +Then the peices are unglued and any hanging bits +drop down into the pit to make other possible +connections and loops... + +#incbin::HELP/wire3.png + +If a piece lands with anything sticking out of the +top of the pit, it's GAME OVER. + + +@SPECIAL PIECES + +Once in a while a special piece may drop down... + + +!SMART BOMB + +$incbin::HELP/bomb.png + +This special will destroy all blocks that are the +same as the one it lands on. Landing on nothing +is perhaps not a good idea... + + +!TWISTER + +$incbin::HELP/twister.png + +The twister will rotate all the pieces in the pit +four times, scoring any loops and wires that +are made from doing this. + + +!SMART NUKE + +$incbin::HELP/nuke.png + +The smart nuke destroy all blocks that match +the blocks surrounding the point were it lands. + + +!SUPER CROSS + +~incbin::HELP/cross.png + +This will change all blocks above, below and to +the left and right radiating out from the +special to cross pieces. + + +* * * * * * * * * * * * * + diff --git a/game.bmx b/game.bmx index d07d1a3..3857f30 100644 --- a/game.bmx +++ b/game.bmx @@ -1,330 +1,346 @@ -' Hardwire -' -' Copyright 2005 Ian Cowburn -' -' $Id$ -' -Strict -Import "types.bmx" -Import "particle.bmx" -Import "sounds.bmx" -Import "gametypes.bmx" - -Type TBufferedKey - Global list:TList - Field key:Int - Field del:Int - Field cnt:Int - - Function Clear() - list=CreateList() - End Function - - Function Create:TBufferedKey(key:Int, del:Int=30) - Local o:TBufferedKey=New TBufferedKey - o.key=key - o.del=del - o.cnt=0 - list.AddLast(o) - Return o - End Function - - Function Flush() - For Local k:TBufferedKey=EachIn list - k.cnt=0 - Next - End Function - - Function Idle() - For Local k:TBufferedKey=EachIn list - If k.cnt - k.cnt:-1 - EndIf - Next - End Function - - Method ForceRelease() - cnt=999999 - End Method - - Method Poll:Int() - If KeyDown(key) - If cnt - cnt:-1 - Return False - Else - cnt=del - Return True - EndIf - Else - cnt=0 - Return False - EndIf - End Method -End Type - -Type TGame - Field level:Int - Field score:Int - Field gm:TGameMap - Field timer:Int - Field alpha:Double - Field alphainc:Double - Field count:Int - Field total:Int - Field block:TPiece - Field nextblock:TPiece - Field drop:Int - Field fade:TFadeScreen - Field bdrop:TGameBackdrop - Field kleft:TBufferedKey - Field kright:TBufferedKey - Field krotleft:TBufferedKey - Field krotright:TBufferedKey - Field kdrop:TBufferedKey - - Method New() - score=0 - gm=New TGameMap - level=1 - Particles.Clear() - TextParticles.Clear() - ExplosionParticles.Clear() - alpha=0.0 - alphainc=0.01 - count=0 - total=0 - nextblock=TPiece.Create(False) - drop=False - CreateNext(False) - fade=TFadeScreen.FadeIn() - bdrop=New TGameBackdrop - - TBufferedKey.Clear() - kleft=TBufferedKey.Create(GameConfig.kleft) - kright=TBufferedKey.Create(GameConfig.kright) - krotleft=TBufferedKey.Create(GameConfig.krotleft) - krotright=TBufferedKey.Create(GameConfig.krotright) - kdrop=TBufferedKey.Create(GameConfig.kdrop,1) - End Method - - Method SetInitLevel(l:Int) - level=l - SetTimer() - End Method - - Method SetTimer() - If drop - timer=5 - Else - timer=Max(HERTZ/5,(16-level)*HERTZ/5) - EndIf - End Method - - Method LevelUp() - level:+1 - count=0 - End Method - - Method CreateNext(special:Int) - block=nextblock - block.y=-3 - block.x=Pit.WIDTH/2 - nextblock=TPiece.Create(special) - nextblock.x=Pit.WIDTH+3 - nextblock.y=1 - drop=False - End Method - - Method Pause() - Local i:Timage=CreateImage(GraphicsWidth(),GraphicsHeight(),1,MASKEDIMAGE|DYNAMICIMAGE|FILTEREDIMAGE) - - GrabImage(i,0,0) - MidHandleImage(i) - SetColor(255,255,255) - - FlushKeys() - - Local a:Int[]=[0,0,0,0,0,0,0,0] - Local ac:Int[]=[7,6,5,4,3,2,1,0] - - While Not KeyHit(GameConfig.kpause) - Cls - - Local al:Double=0.3 - - For Local f:Int=0 Until a.length - SetAlpha(al) - SetRotation(a[f]) - SetScale(al*2,al*2) - DrawImage(i,GraphicsWidth()/2,GraphicsHeight()/2) - If ac[f]>0 - ac[f]:-1 - Else - If f Mod 2 - a[f]:+1 - Else - a[f]:-1 - EndIf - EndIf - al:+0.1 - Next - - SetRotation(0) - SetScale(1,1) - GameGFX.large.Centre("PAUSED",GraphicsHeight()/2-16) - - Flip - Wend - - SetAlpha(1) - SetRotation(0) - SetScale(1,1) - - FlushKeys - TBufferedKey.Flush() - End Method - - Method Play:Int() - Local playing:Int=True - - Cls - - bdrop.Draw() - - GameGFX.large.Draw("SCORE",0,0,255,255,0) - GameGFX.large.Draw(score,0,20) - - GameGFX.large.Draw("LEVEL",0,100,255,255,0) - GameGFX.large.Draw(level,0,120) - - GameGFX.large.Draw("HISCORE",0,200,255,255,0) - If score>GameConfig.hiscore - GameConfig.hiscore=score - EndIf - GameGFX.large.Draw(GameConfig.hiscore,0,220) - - nextblock.Draw() - - block.Draw() - - If Not gm.overflow - If KeyHit(KEY_ESCAPE) - playing=False - EndIf - - If Not gm.BlockInteract() - timer:-1 - - If timer<=0 - SetTimer() - block.y:+1 - - If block.Collides(gm) - block.y:-1 - block.AddToMap(gm) - count:+1 - total:+1 - If count>10 - LevelUp() - EndIf - - kdrop.ForceRelease() - - If Not gm.overflow - score:+level*2 - CreateNext((total Mod 17)=0) ' 17 - Else - FlushKeys() - TBufferedKey.Flush() - EndIf - EndIf - EndIf - - If kleft.Poll() - block.x:-1 - If block.Collides(gm) - block.x:+1 - EndIf - EndIf - - If kright.Poll() - block.x:+1 - If block.Collides(gm) - block.x:-1 - EndIf - EndIf - - If krotright.Poll() - block.RotateRight() - If block.Collides(gm) - block.x:-1 - If block.Collides(gm) - block.x:+1 - block.RotateLeft() - EndIf - EndIf - EndIf - - If krotleft.Poll() - block.RotateLeft() - If block.Collides(gm) - block.x:+1 - If block.Collides(gm) - block.x:-1 - block.RotateRight() - EndIf - EndIf - EndIf - - If kdrop.Poll() - timer=0 - 'drop=True - EndIf - Else - TBufferedKey.Idle() - EndIf - - score:+gm.Draw()*level*20 - Else - gm.Draw() - - SetAlpha(alpha) - SetColor(255,255,255) - DrawImage(GameGFX.gameover,GraphicsWidth()/2,GraphicsHeight()/2) - SetAlpha(1) - alpha:+alphainc - If (alpha<=0.7 And alphainc<0) Or (alpha>=1.0 And alphainc>0) - alpha=Max(0,Min(1,alpha)) - alphainc=-alphainc - EndIf - - If KeyHit(KEY_ENTER) Or KeyHit(KEY_ESCAPE) - playing=False - EndIf - EndIf - - Particles.Draw() - ExplosionParticles.Draw() - TextParticles.Draw() - - If KeyHit(GameConfig.kpause) And Not gm.overflow - Pause() - EndIf - - Sound.Process() - - If fade - If fade.Fade() - fade.Draw() - Else - fade=Null - EndIf - EndIf - - Flip - - Return playing - End Method -End Type - +' Hardwire +' +' Copyright (C) 2005 Ian Cowburn (ianc@noddybox.co.uk) +' +' This program is free software; you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation; either version 2 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY; without even the implied warranty of +' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +' GNU General Public License for more details. +' +' You should have received a copy of the GNU General Public License +' along with this program; if not, write to the Free Software +' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +' +' ------------------------------------------------------------------------- +' +' $Id$ +' +Strict +Import "types.bmx" +Import "particle.bmx" +Import "sounds.bmx" +Import "gametypes.bmx" + +Type TBufferedKey + Global list:TList + Field key:Int + Field del:Int + Field cnt:Int + + Function Clear() + list=CreateList() + End Function + + Function Create:TBufferedKey(key:Int, del:Int=30) + Local o:TBufferedKey=New TBufferedKey + o.key=key + o.del=del + o.cnt=0 + list.AddLast(o) + Return o + End Function + + Function Flush() + For Local k:TBufferedKey=EachIn list + k.cnt=0 + Next + End Function + + Function Idle() + For Local k:TBufferedKey=EachIn list + If k.cnt + k.cnt:-1 + EndIf + Next + End Function + + Method ForceRelease() + cnt=999999 + End Method + + Method Poll:Int() + If KeyDown(key) + If cnt + cnt:-1 + Return False + Else + cnt=del + Return True + EndIf + Else + cnt=0 + Return False + EndIf + End Method +End Type + +Type TGame + Field level:Int + Field score:Int + Field gm:TGameMap + Field timer:Int + Field alpha:Double + Field alphainc:Double + Field count:Int + Field total:Int + Field block:TPiece + Field nextblock:TPiece + Field drop:Int + Field fade:TFadeScreen + Field bdrop:TGameBackdrop + Field kleft:TBufferedKey + Field kright:TBufferedKey + Field krotleft:TBufferedKey + Field krotright:TBufferedKey + Field kdrop:TBufferedKey + + Method New() + score=0 + gm=New TGameMap + level=1 + Particles.Clear() + TextParticles.Clear() + ExplosionParticles.Clear() + alpha=0.0 + alphainc=0.01 + count=0 + total=0 + nextblock=TPiece.Create(False) + drop=False + CreateNext(False) + fade=TFadeScreen.FadeIn() + bdrop=New TGameBackdrop + + TBufferedKey.Clear() + kleft=TBufferedKey.Create(GameConfig.kleft) + kright=TBufferedKey.Create(GameConfig.kright) + krotleft=TBufferedKey.Create(GameConfig.krotleft) + krotright=TBufferedKey.Create(GameConfig.krotright) + kdrop=TBufferedKey.Create(GameConfig.kdrop,1) + End Method + + Method SetInitLevel(l:Int) + level=l + SetTimer() + End Method + + Method SetTimer() + If drop + timer=5 + Else + timer=Max(5,(20-level)*5) + EndIf + End Method + + Method LevelUp() + level:+1 + count=0 + End Method + + Method CreateNext(special:Int) + block=nextblock + block.y=-3 + block.x=Pit.WIDTH/2 + nextblock=TPiece.Create(special) + nextblock.x=Pit.WIDTH+3 + nextblock.y=1 + drop=False + End Method + + Method Pause() + Local i:Timage=CreateImage(GraphicsWidth(),GraphicsHeight(),1,MASKEDIMAGE|DYNAMICIMAGE|FILTEREDIMAGE) + + GrabImage(i,0,0) + MidHandleImage(i) + SetColor(255,255,255) + + FlushKeys() + + Local a:Int[]=[0,0,0,0,0,0,0,0] + Local ac:Int[]=[7,6,5,4,3,2,1,0] + + While Not KeyHit(GameConfig.kpause) + Cls + + Local al:Double=0.3 + + For Local f:Int=0 Until a.length + SetAlpha(al) + SetRotation(a[f]) + SetScale(al*2,al*2) + DrawImage(i,GraphicsWidth()/2,GraphicsHeight()/2) + If ac[f]>0 + ac[f]:-1 + Else + If f Mod 2 + a[f]:+1 + Else + a[f]:-1 + EndIf + EndIf + al:+0.1 + Next + + SetRotation(0) + SetScale(1,1) + GameGFX.large.Centre("PAUSED",GraphicsHeight()/2-16) + + Flip + Wend + + SetAlpha(1) + SetRotation(0) + SetScale(1,1) + + FlushKeys + TBufferedKey.Flush() + End Method + + Method Play:Int() + Local playing:Int=True + + Cls + + bdrop.Draw() + + GameGFX.large.Draw("SCORE",0,0,255,255,0) + GameGFX.large.Draw(Number.Format(score),0,20) + + GameGFX.large.Draw("LEVEL",0,100,255,255,0) + GameGFX.large.Draw(level,0,120) + + GameGFX.large.Draw("HISCORE",0,200,255,255,0) + If score>GameConfig.hiscore + GameConfig.hiscore=score + EndIf + GameGFX.large.Draw(Number.Format(GameConfig.hiscore),0,220) + + nextblock.Draw() + + block.Draw() + + If Not gm.overflow + If KeyHit(KEY_ESCAPE) + playing=False + EndIf + + If Not gm.BlockInteract() + timer:-1 + + If timer<=0 + SetTimer() + block.y:+1 + + If block.Collides(gm) + block.y:-1 + block.AddToMap(gm) + count:+1 + total:+1 + If count>10 + LevelUp() + EndIf + + kdrop.ForceRelease() + + If Not gm.overflow + score:+level*2 + CreateNext((total Mod 17)=0) ' 17 + Else + FlushKeys() + TBufferedKey.Flush() + EndIf + EndIf + EndIf + + If kleft.Poll() + block.x:-1 + If block.Collides(gm) + block.x:+1 + EndIf + EndIf + + If kright.Poll() + block.x:+1 + If block.Collides(gm) + block.x:-1 + EndIf + EndIf + + If krotright.Poll() + block.RotateRight() + If block.Collides(gm) + block.x:-1 + If block.Collides(gm) + block.x:+1 + block.RotateLeft() + EndIf + EndIf + EndIf + + If krotleft.Poll() + block.RotateLeft() + If block.Collides(gm) + block.x:+1 + If block.Collides(gm) + block.x:-1 + block.RotateRight() + EndIf + EndIf + EndIf + + If kdrop.Poll() + timer=0 + 'drop=True + EndIf + Else + TBufferedKey.Idle() + EndIf + + score:+gm.Draw()*level*20 + Else + gm.Draw() + + SetAlpha(alpha) + SetColor(255,255,255) + DrawImage(GameGFX.gameover,GraphicsWidth()/2,GraphicsHeight()/2) + SetAlpha(1) + alpha:+alphainc + If (alpha<=0.7 And alphainc<0) Or (alpha>=1.0 And alphainc>0) + alpha=Max(0,Min(1,alpha)) + alphainc=-alphainc + EndIf + + If KeyHit(KEY_ENTER) Or KeyHit(KEY_ESCAPE) + playing=False + EndIf + EndIf + + Particles.Draw() + ExplosionParticles.Draw() + TextParticles.Draw() + + If KeyHit(GameConfig.kpause) And Not gm.overflow + Pause() + EndIf + + Sound.Process() + + If fade + If fade.Fade() + fade.Draw() + Else + fade=Null + EndIf + EndIf + + Flip + + Return playing + End Method +End Type + diff --git a/gametypes.bmx b/gametypes.bmx index 24d1617..5875363 100644 --- a/gametypes.bmx +++ b/gametypes.bmx @@ -1,960 +1,977 @@ -' Hardwire -' -' Copyright 2005 Ian Cowburn -' -' $Id$ -' -Strict -Import "types.bmx" -Import "particle.bmx" -Import "sounds.bmx" - -Type Pit - Const WIDTH=10 - Const HEIGHT=13 - - Function X:Int(p:Int) - Return 230+p*32 - End Function - - Function Y:Int(p:Int) - Return 120+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 SPECIAL_BOMB:Int=7 - Const SPECIAL_TWISTER:Int=8 - Const SPECIAL_NUKE:Int=9 - Const SPECIAL_CROSS:Int=10 - - 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,7,8,9,10] - rotleft=[0,2,1,5,3,6,4,7,8,9,10] - - img=[GameGFX.cross, .. - GameGFX.left_right, .. - GameGFX.top_bottom, .. - GameGFX.top_left, .. - GameGFX.top_right, .. - GameGFX.bottom_left, .. - GameGFX.bottom_right, .. - GameGFX.special_bomb, .. - GameGFX.special_twister, .. - GameGFX.special_nuke, .. - GameGFX.special_cross] - - dir=[[DIR_UP,DIR_RIGHT,DIR_DOWN,DIR_LEFT], .. ' CROSS - [DIR_NONE,DIR_RIGHT,DIR_NONE,DIR_LEFT], .. ' LEFT_RIGHT - [DIR_UP,DIR_NONE,DIR_DOWN,DIR_NONE], .. ' TOP_BOTTOM - [DIR_NONE,DIR_UP,DIR_LEFT,DIR_NONE], .. ' TOP_LEFT - [DIR_NONE,DIR_NONE,DIR_RIGHT,DIR_UP], .. ' TOP_RIGHT - [DIR_LEFT,DIR_DOWN,DIR_NONE,DIR_NONE], .. ' BOTTOM_LEFT - [DIR_RIGHT,DIR_NONE,DIR_NONE,DIR_DOWN], .. ' BOTTOM_RIGHT - [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_BOMB - [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_TWISTER - [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_NUKE - [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE]] ' SPECIAL_CROSS - - 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","SPECIAL BOMB","SPECIAL TWISTER"] - End Function - - Method New() - t=Rand(0,6) - End Method - - Function Create:TWire(t:Int[]) - Local o:TWire=New TWire - o.t=t[Rand(0,t.length-1)] - 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 TPiece Abstract - Field x:Int - Field y:Int - Field ox:Int - Field oy:Int - Field map:TWire[4,4] - Field rot:Int - Field offx:Int[4] - Field offy:Int[4] - Field special:Int - Field special_pulse:Int - Field col:Int - Field coli:Int - Field frame:Int - Field framed:Int - Field framespd:Int - Field framei:Int - Field pong:Int - - Function Create:TPiece(special:Int) - Local o:TPiece - - If special - Select Rand(0,3) - Case 0 - o=TPiece(New TPiece_SpecialBomb) - Case 1 - o=TPiece(New TPiece_SpecialTwister) - Case 2 - o=TPiece(New TPiece_SpecialNuke) - Case 3 - o=TPiece(New TPiece_SpecialCross) - End Select - Else - Select Rand(0,5) - Case 0 - o=TPiece(New TPiece_S_Left) - Case 1 - o=TPiece(New TPiece_S_Right) - Case 2 - o=TPiece(New TPiece_L_Left) - Case 3 - o=TPiece(New TPiece_L_Right) - Case 4 - o=TPiece(New TPiece_Square) - Case 5 - o=TPiece(New TPiece_Bar) - End Select - EndIf - - o.BaseInit(special) - - Return o - End Function - - Function CreateSpecific:TPiece(t:Int) - Local o:TPiece - Local s:Int=False - - Select t - Case 0 - o=TPiece(New TPiece_S_Left) - Case 1 - o=TPiece(New TPiece_S_Right) - Case 2 - o=TPiece(New TPiece_L_Left) - Case 3 - o=TPiece(New TPiece_L_Right) - Case 4 - o=TPiece(New TPiece_Square) - Case 5 - o=TPiece(New TPiece_Bar) - Case 6 - o=TPiece(New TPiece_SpecialBomb) - s=True - Case 7 - o=TPiece(New TPiece_SpecialTwister) - s=True - Case 8 - o=TPiece(New TPiece_SpecialNuke) - s=True - Case 9 - o=TPiece(New TPiece_SpecialCross) - s=True - Default - Return Create(False) - End Select - - o.BaseInit(s) - - Return o - End Function - - Method Init() Abstract - - Method BaseInit(special:Int) - special_pulse=False - framespd=5 - pong=False - Init() - rot=0 - ox=offx[rot] - oy=offy[rot] - self.special=special - col=255 - coli=-1 - frame=0 - framed=0 - framei=1 - End Method - - Method Draw() - If special - col:+coli - If col=255 Or col=128 - coli=-coli - EndIf - - framed:+1 - If framed=framespd - framed=0 - If pong - frame:+framei - If frame=0 Or frame=3 - framei=-framei - EndIf - Else - frame=(frame+1) Mod 4 - EndIf - EndIf - - For Local px:Int=0 Until 4 - For Local py:Int=0 Until 4 - If map[px,py] - Local gx:Int=Pit.X(x-ox+px) - Local gy:Int=Pit.Y(y-oy+py) - SetColor(255,255,255) - DrawImage(GameGFX.tile,gx,gy) - If special_pulse - SetColor(col,col/2,255-col) - EndIf - DrawImage(map[px,py].Image(),gx,gy,frame) - EndIf - Next - Next - Else - For Local px:Int=0 Until 4 - For Local py:Int=0 Until 4 - If map[px,py] - Local gx:Int=Pit.X(x-ox+px) - Local gy:Int=Pit.Y(y-oy+py) - SetColor(255,255,255) - DrawImage(GameGFX.tile,gx,gy) - SetColor(128,128,128) - DrawImage(map[px,py].Image(),gx,gy) - EndIf - Next - Next - EndIf - End Method - - Method RotateLeft() - If special Then Return - - If rot=0 - rot=3 - Else - rot:-1 - EndIf - - ox=offx[rot] - oy=offy[rot] - - Local m:TWire[4,4] - - For Local px:Int=0 Until 4 - For Local py:Int=0 Until 4 - If map[px,py] - map[px,py].RotateLeft() - EndIf - m[py,3-px]=map[px,py] - Next - Next - - map=m - End Method - - Method RotateRight() - If special Then Return - - rot=(rot+1) Mod 4 - - ox=offx[rot] - oy=offy[rot] - - Local m:TWire[4,4] - - For Local px:Int=0 Until 4 - For Local py:Int=0 Until 4 - If map[px,py] - map[px,py].RotateRight() - EndIf - m[3-py,px]=map[px,py] - Next - Next - - map=m - End Method - - Method Collides:Int(gm:TGameMap) - For Local px:Int=0 Until 4 - For Local py:Int=0 Until 4 - If map[px,py] - Local gx:Int=x-ox+px - Local gy:Int=y-oy+py - - If gx<0 Or gx>=Pit.WIDTH Or gy>=Pit.HEIGHT - Return True - EndIf - - If gy>=0 And gm.map[gx,gy] - Return True - EndIf - EndIf - Next - Next - - Return False - End Method - - Method AddToMap(gm:TGameMap) - If special - gm.SetSpecial(TSpecial(Self)) - Else - For Local px:Int=0 Until 4 - For Local py:Int=0 Until 4 - If map[px,py] - Local gx:Int=x-ox+px - Local gy:Int=y-oy+py - - If gy<0 - gm.overflow=True - Else - gm.map[gx,gy]=map[px,py] - - If gy=Pit.HEIGHT-1 Or gm.map[gx,gy+1] - Particles.AddDust(Pit.X(gx)+16,Pit.Y(gy)+32) - EndIf - EndIf - EndIf - Next - Next - - Sound.Click() - - If Not gm.overflow - If Not gm.CheckWires() - gm.Flatten() - gm.CheckWires() - EndIf - EndIf - EndIf - End Method -End Type - -Type TSpecial Extends TPiece Abstract - Method DoSpecial:Int(gm:TGameMap) Abstract -End Type - -Type TPiece_S_Right Extends TPiece - Method Init() - map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_RIGHT]) - map[2,0]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) - map[0,1]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) - map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT]) - offx=[1,2,2,0] - offy=[1,1,2,2] - End Method -End Type - - -Type TPiece_S_Left Extends TPiece - Method Init() - map[0,0]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) - map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT]) - map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT]) - map[2,1]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) - offx=[1,2,2,0] - offy=[1,1,2,2] - End Method -End Type - - -Type TPiece_L_Right Extends TPiece - Method Init() - map[0,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_RIGHT]) - map[1,0]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) - map[0,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) - map[0,2]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) - offx=[0,2,3,1] - offy=[1,0,2,3] - End Method -End Type - - -Type TPiece_L_Left Extends TPiece - Method Init() - map[0,0]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) - map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT]) - map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) - map[1,2]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) - offx=[1,2,2,1] - offy=[1,1,2,2] - End Method -End Type - - -Type TPiece_Square Extends TPiece - Method Init() - map[0,0]=TWire.Create([TWire.CROSS]) - map[1,0]=TWire.Create([TWire.CROSS]) - map[0,1]=TWire.Create([TWire.CROSS]) - map[1,1]=TWire.Create([TWire.CROSS]) - offx=[0,2,2,0] - offy=[1,1,3,3] - End Method -End Type - - -Type TPiece_Bar Extends TPiece - Method Init() - map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT,TWire.BOTTOM_RIGHT,TWire.TOP_BOTTOM]) - map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) - map[1,2]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) - map[1,3]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) - offx=[1,1,2,1] - offy=[1,1,1,2] - End Method -End Type - -Type TPiece_SpecialBomb Extends TSpecial - Method Init() - map[0,0]=TWire.Create([TWire.SPECIAL_BOMB]) - offx=[0,0,0,0] - offy=[0,0,0,0] - End Method - - Method DoSpecial:Int(gm:TGameMap) - Draw() - - Local l:TWireList=New TWireList - - If y0 And gm.map[x-1,y] - AddToList(gm,l,gm.map[x-1,y].t) - EndIf - - If x0 - map[x,y]=map[x,y-1] - y:-1 - Wend - map[x,0]=Null - End Method - - Method AnyAbove:Int(x:Int, y:Int) - While y>=0 - If map[x,y] - Return True - EndIf - y:-1 - Wend - - Return False - End Method - - Method Flatten() - For Local x:Int=0 Until Pit.WIDTH - Local y:Int=Pit.HEIGHT-1 - Local drop:Int=False - - While y>0 And AnyAbove(x,y) - If map[x,y] - If drop - Particles.AddDust(Pit.X(x)+16,Pit.Y(y)+32) - EndIf - drop=False - y:-1 - Else - DropColumn(x,y) - EndIf - Wend - Next - 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(trode_col,trode_col,0) - DrawImage(map[x,y].Image(),Pit.X(x),Pit.Y(y)) - EndIf - Next - Next - - If special - If Not special.DoSpecial(Self) - special=Null - EndIf - EndIf - - 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 - map[e.x,e.y]=Null - Next - EndIf - l.Remove() - check=True - EndIf - Wend - - If check - Sound.Path() - Flatten() - CheckWires() - EndIf - - 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 +' Hardwire +' +' Copyright (C) 2005 Ian Cowburn (ianc@noddybox.co.uk) +' +' This program is free software; you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation; either version 2 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY; without even the implied warranty of +' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +' GNU General Public License for more details. +' +' You should have received a copy of the GNU General Public License +' along with this program; if not, write to the Free Software +' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +' +' ------------------------------------------------------------------------- +' +' $Id$ +' +Strict +Import "types.bmx" +Import "particle.bmx" +Import "sounds.bmx" + +Type Pit + Const WIDTH=10 + Const HEIGHT=13 + + Function X:Int(p:Int) + Return 230+p*32 + End Function + + Function Y:Int(p:Int) + Return 120+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 SPECIAL_BOMB:Int=7 + Const SPECIAL_TWISTER:Int=8 + Const SPECIAL_NUKE:Int=9 + Const SPECIAL_CROSS:Int=10 + + 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,7,8,9,10] + rotleft=[0,2,1,5,3,6,4,7,8,9,10] + + img=[GameGFX.cross, .. + GameGFX.left_right, .. + GameGFX.top_bottom, .. + GameGFX.top_left, .. + GameGFX.top_right, .. + GameGFX.bottom_left, .. + GameGFX.bottom_right, .. + GameGFX.special_bomb, .. + GameGFX.special_twister, .. + GameGFX.special_nuke, .. + GameGFX.special_cross] + + dir=[[DIR_UP,DIR_RIGHT,DIR_DOWN,DIR_LEFT], .. ' CROSS + [DIR_NONE,DIR_RIGHT,DIR_NONE,DIR_LEFT], .. ' LEFT_RIGHT + [DIR_UP,DIR_NONE,DIR_DOWN,DIR_NONE], .. ' TOP_BOTTOM + [DIR_NONE,DIR_UP,DIR_LEFT,DIR_NONE], .. ' TOP_LEFT + [DIR_NONE,DIR_NONE,DIR_RIGHT,DIR_UP], .. ' TOP_RIGHT + [DIR_LEFT,DIR_DOWN,DIR_NONE,DIR_NONE], .. ' BOTTOM_LEFT + [DIR_RIGHT,DIR_NONE,DIR_NONE,DIR_DOWN], .. ' BOTTOM_RIGHT + [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_BOMB + [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_TWISTER + [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE], .. ' SPECIAL_NUKE + [DIR_NONE,DIR_NONE,DIR_NONE,DIR_NONE]] ' SPECIAL_CROSS + + 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","SPECIAL BOMB","SPECIAL TWISTER"] + End Function + + Method New() + t=Rand(0,6) + End Method + + Function Create:TWire(t:Int[]) + Local o:TWire=New TWire + o.t=t[Rand(0,t.length-1)] + 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 TPiece Abstract + Field x:Int + Field y:Int + Field ox:Int + Field oy:Int + Field map:TWire[4,4] + Field rot:Int + Field offx:Int[4] + Field offy:Int[4] + Field special:Int + Field special_pulse:Int + Field col:Int + Field coli:Int + Field frame:Int + Field framed:Int + Field framespd:Int + Field framei:Int + Field pong:Int + + Function Create:TPiece(special:Int) + Local o:TPiece + + If special + Select Rand(0,3) + Case 0 + o=TPiece(New TPiece_SpecialBomb) + Case 1 + o=TPiece(New TPiece_SpecialTwister) + Case 2 + o=TPiece(New TPiece_SpecialNuke) + Case 3 + o=TPiece(New TPiece_SpecialCross) + End Select + Else + Select Rand(0,5) + Case 0 + o=TPiece(New TPiece_S_Left) + Case 1 + o=TPiece(New TPiece_S_Right) + Case 2 + o=TPiece(New TPiece_L_Left) + Case 3 + o=TPiece(New TPiece_L_Right) + Case 4 + o=TPiece(New TPiece_Square) + Case 5 + o=TPiece(New TPiece_Bar) + End Select + EndIf + + o.BaseInit(special) + + Return o + End Function + + Function CreateSpecific:TPiece(t:Int) + Local o:TPiece + Local s:Int=False + + Select t + Case 0 + o=TPiece(New TPiece_S_Left) + Case 1 + o=TPiece(New TPiece_S_Right) + Case 2 + o=TPiece(New TPiece_L_Left) + Case 3 + o=TPiece(New TPiece_L_Right) + Case 4 + o=TPiece(New TPiece_Square) + Case 5 + o=TPiece(New TPiece_Bar) + Case 6 + o=TPiece(New TPiece_SpecialBomb) + s=True + Case 7 + o=TPiece(New TPiece_SpecialTwister) + s=True + Case 8 + o=TPiece(New TPiece_SpecialNuke) + s=True + Case 9 + o=TPiece(New TPiece_SpecialCross) + s=True + Default + Return Create(False) + End Select + + o.BaseInit(s) + + Return o + End Function + + Method Init() Abstract + + Method BaseInit(special:Int) + special_pulse=False + framespd=5 + pong=False + Init() + rot=0 + ox=offx[rot] + oy=offy[rot] + self.special=special + col=255 + coli=-1 + frame=0 + framed=0 + framei=1 + End Method + + Method Draw() + If special + col:+coli + If col=255 Or col=128 + coli=-coli + EndIf + + framed:+1 + If framed=framespd + framed=0 + If pong + frame:+framei + If frame=0 Or frame=3 + framei=-framei + EndIf + Else + frame=(frame+1) Mod 4 + EndIf + EndIf + + For Local px:Int=0 Until 4 + For Local py:Int=0 Until 4 + If map[px,py] + Local gx:Int=Pit.X(x-ox+px) + Local gy:Int=Pit.Y(y-oy+py) + SetColor(255,255,255) + DrawImage(GameGFX.tile,gx,gy) + If special_pulse + SetColor(col,col/2,255-col) + EndIf + DrawImage(map[px,py].Image(),gx,gy,frame) + EndIf + Next + Next + Else + For Local px:Int=0 Until 4 + For Local py:Int=0 Until 4 + If map[px,py] + Local gx:Int=Pit.X(x-ox+px) + Local gy:Int=Pit.Y(y-oy+py) + SetColor(255,255,255) + DrawImage(GameGFX.tile,gx,gy) + SetColor(128,128,128) + DrawImage(map[px,py].Image(),gx,gy) + EndIf + Next + Next + EndIf + End Method + + Method RotateLeft() + If special Then Return + + If rot=0 + rot=3 + Else + rot:-1 + EndIf + + ox=offx[rot] + oy=offy[rot] + + Local m:TWire[4,4] + + For Local px:Int=0 Until 4 + For Local py:Int=0 Until 4 + If map[px,py] + map[px,py].RotateLeft() + EndIf + m[py,3-px]=map[px,py] + Next + Next + + map=m + End Method + + Method RotateRight() + If special Then Return + + rot=(rot+1) Mod 4 + + ox=offx[rot] + oy=offy[rot] + + Local m:TWire[4,4] + + For Local px:Int=0 Until 4 + For Local py:Int=0 Until 4 + If map[px,py] + map[px,py].RotateRight() + EndIf + m[3-py,px]=map[px,py] + Next + Next + + map=m + End Method + + Method Collides:Int(gm:TGameMap) + For Local px:Int=0 Until 4 + For Local py:Int=0 Until 4 + If map[px,py] + Local gx:Int=x-ox+px + Local gy:Int=y-oy+py + + If gx<0 Or gx>=Pit.WIDTH Or gy>=Pit.HEIGHT + Return True + EndIf + + If gy>=0 And gm.map[gx,gy] + Return True + EndIf + EndIf + Next + Next + + Return False + End Method + + Method AddToMap(gm:TGameMap) + If special + gm.SetSpecial(TSpecial(Self)) + Else + For Local px:Int=0 Until 4 + For Local py:Int=0 Until 4 + If map[px,py] + Local gx:Int=x-ox+px + Local gy:Int=y-oy+py + + If gy<0 + gm.overflow=True + Else + gm.map[gx,gy]=map[px,py] + + If gy=Pit.HEIGHT-1 Or gm.map[gx,gy+1] + Particles.AddDust(Pit.X(gx)+16,Pit.Y(gy)+32) + EndIf + EndIf + EndIf + Next + Next + + Sound.Click() + + If Not gm.overflow + If Not gm.CheckWires() + gm.Flatten() + gm.CheckWires() + EndIf + EndIf + EndIf + End Method +End Type + +Type TSpecial Extends TPiece Abstract + Method DoSpecial:Int(gm:TGameMap) Abstract +End Type + +Type TPiece_S_Right Extends TPiece + Method Init() + map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_RIGHT]) + map[2,0]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) + map[0,1]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) + map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT]) + offx=[1,2,2,0] + offy=[1,1,2,2] + End Method +End Type + + +Type TPiece_S_Left Extends TPiece + Method Init() + map[0,0]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) + map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT]) + map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT]) + map[2,1]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) + offx=[1,2,2,0] + offy=[1,1,2,2] + End Method +End Type + + +Type TPiece_L_Right Extends TPiece + Method Init() + map[0,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_RIGHT]) + map[1,0]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.BOTTOM_LEFT,TWire.LEFT_RIGHT]) + map[0,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) + map[0,2]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) + offx=[0,2,3,1] + offy=[1,0,2,3] + End Method +End Type + + +Type TPiece_L_Left Extends TPiece + Method Init() + map[0,0]=TWire.Create([TWire.CROSS,TWire.TOP_RIGHT,TWire.BOTTOM_RIGHT,TWire.LEFT_RIGHT]) + map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT]) + map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) + map[1,2]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) + offx=[1,2,2,1] + offy=[1,1,2,2] + End Method +End Type + + +Type TPiece_Square Extends TPiece + Method Init() + map[0,0]=TWire.Create([TWire.CROSS]) + map[1,0]=TWire.Create([TWire.CROSS]) + map[0,1]=TWire.Create([TWire.CROSS]) + map[1,1]=TWire.Create([TWire.CROSS]) + offx=[0,2,2,0] + offy=[1,1,3,3] + End Method +End Type + + +Type TPiece_Bar Extends TPiece + Method Init() + map[1,0]=TWire.Create([TWire.CROSS,TWire.BOTTOM_LEFT,TWire.BOTTOM_RIGHT,TWire.TOP_BOTTOM]) + map[1,1]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) + map[1,2]=TWire.Create([TWire.CROSS,TWire.TOP_BOTTOM]) + map[1,3]=TWire.Create([TWire.CROSS,TWire.TOP_LEFT,TWire.TOP_RIGHT,TWire.TOP_BOTTOM]) + offx=[1,1,2,1] + offy=[1,1,1,2] + End Method +End Type + +Type TPiece_SpecialBomb Extends TSpecial + Method Init() + map[0,0]=TWire.Create([TWire.SPECIAL_BOMB]) + offx=[0,0,0,0] + offy=[0,0,0,0] + End Method + + Method DoSpecial:Int(gm:TGameMap) + Draw() + + Local l:TWireList=New TWireList + + If y0 And gm.map[x-1,y] + AddToList(gm,l,gm.map[x-1,y].t) + EndIf + + If x0 + map[x,y]=map[x,y-1] + y:-1 + Wend + map[x,0]=Null + End Method + + Method AnyAbove:Int(x:Int, y:Int) + While y>=0 + If map[x,y] + Return True + EndIf + y:-1 + Wend + + Return False + End Method + + Method Flatten() + For Local x:Int=0 Until Pit.WIDTH + Local y:Int=Pit.HEIGHT-1 + Local drop:Int=False + + While y>0 And AnyAbove(x,y) + If map[x,y] + If drop + Particles.AddDust(Pit.X(x)+16,Pit.Y(y)+32) + EndIf + drop=False + y:-1 + Else + DropColumn(x,y) + drop=True + EndIf + Wend + Next + 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(trode_col,trode_col,0) + DrawImage(map[x,y].Image(),Pit.X(x),Pit.Y(y)) + EndIf + Next + Next + + If special + If Not special.DoSpecial(Self) + special=Null + EndIf + EndIf + + 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 + map[e.x,e.y]=Null + Next + EndIf + l.Remove() + check=True + EndIf + Wend + + If check + Sound.Path() + Flatten() + CheckWires() + EndIf + + 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 diff --git a/hardwire.bmx b/hardwire.bmx index f1f8997..577552f 100644 --- a/hardwire.bmx +++ b/hardwire.bmx @@ -1,374 +1,396 @@ -' Hardwire -' -' Copyright 2005 Ian Cowburn -' -' $Id$ -' -Strict -Framework brl.basic -Import brl.max2d -Import brl.glmax2d -?Win32 -Import brl.d3d7max2d -? - -Import noddybox.bitmapfont -Import noddybox.keysyms -Import noddybox.gfxmenu - -Import "types.bmx" -Import "gametypes.bmx" -Import "game.bmx" -Import "particle.bmx" -Import "help.bmx" - -' =================================== -' Initialise -' =================================== -' -SeedRnd(MilliSecs()) - -?Win32 -If Switch("--directx") - SetGraphicsDriver D3D7Max2DDriver() -Else - SetGraphicsDriver GLMax2DDriver() -EndIf -? - -Graphics 800,600,32,HERTZ -HideMouse - -SetBlend(ALPHABLEND) -SetAlpha(1.0) - - -' =================================== -' Globals -' =================================== -' -GameGFX.Init() ' MUST be first - -Lookup.Init() -GameConfig.Load() -TWire.Init() -Particles.Init() -TextParticles.Init() -ExplosionParticles.Init() -Sound.Init() - -Global bdrop:TMenuBdrop=New TMenuBdrop -Global quit:Int=False -Global last_score:Int=0 - - -' =================================== -' Main -' =================================== -' -Menu() - -While Not quit - Local game:TGame=New TGame - game.SetInitLevel(GameConfig.start_level) - - While game.Play() - Wend - - TFadeScreen.DoFadeOut() - - GameConfig.Save() - last_score=game.score - - Menu() -Wend - -EndGraphics -End - - -' =================================== -' Argument Routines -' =================================== -' -Function Switch:Int(s:String) - For Local a:String=EachIn AppArgs - If a=s - Return True - EndIf - Next - - Return False -End Function - - -' =================================== -' Menu Routines -' =================================== -' -Function Menu() - Const MENU_PLAY:Int=1 - Const MENU_QUIT:Int=2 - Const MENU_RULES:Int=3 - Const MENU_KEYS:Int=4 - Const MENU_LEFT:Int=5 - Const MENU_RIGHT:Int=6 - - Local fade:TFadeScreen=TFadeScreen.FadeIn() - Local done:Int=False - 'Local menu:TGfxMenu=TGfxMenu.Create(255,0,0,255,255,255,25,bdrop,1) - Local menu:TGfxMenu=TGfxMenu.Create(255,0,0,255,255,255,15,bdrop,1) - Local sel:Int - - Local defkey:Int=0 - - Local x1:Int=GraphicsWidth()/3-ImageWidth(GameGFX.play_button)/2 - Local x2:Int=GraphicsWidth()/3*2-ImageWidth(GameGFX.play_button)/2 - - menu.Add(x1,150,GameGFX.play_button,MENU_PLAY) - menu.Add(x2,150,GameGFX.rules_button,MENU_RULES) - menu.Add(x1,250,GameGFX.keys_button,MENU_KEYS) - menu.Add(x2,250,GameGFX.quit_button,MENU_QUIT) - menu.Add(x1,350,GameGFX.left_button,MENU_LEFT) - menu.Add(x2+ImageWidth(GameGFX.play_button)-ImageWidth(GameGFX.right_button),350,GameGFX.right_button,MENU_RIGHT) - - Local tx1:Int=(GraphicsWidth()-GameGFX.large.TextWidth("START LEVEL 1"))/2 - Local tx2:Int=tx1+GameGFX.large.TextWidth("START LEVEL ") - - Local col:Int=128 - Local coli=1 - - TextParticles.Clear() - - While Not done - Cls - SetColor(col,col,255) - DrawImage(GameGFX.title,0,0) - SetColor(255,255,255) - -?debug - If KeyHit(KEY_D) - DebugCode() - EndIf -? - - col:+coli - - If col=128 Or col=255 - coli=-coli - EndIf - - sel=menu.Render(defkey>0) - - If defkey>0 - - If defkey=7 - GameGFX.large.Centre("PRESS A KEY TO GO BACK TO THE MENU",150) - Else - GameGFX.large.Centre("DEFINE KEYS",150) - GameGFX.large.Centre("PRESS ESCAPE TO CANCEL",380) - EndIf - - Local c1:Int=128+128*(defkey=1) - Local c2:Int=128+128*(defkey=2) - Local c3:Int=128+128*(defkey=3) - Local c4:Int=128+128*(defkey=4) - Local c5:Int=128+128*(defkey=5) - Local c6:Int=128+128*(defkey=6) - - GameGFX.large.Draw("Left",250,180,c1,c1,0) - GameGFX.large.Draw("Right",250,210,c2,c2,0) - GameGFX.large.Draw("Rotate Right",250,240,c3,c3,0) - GameGFX.large.Draw("Rotate Left",250,270,c4,c4,0) - GameGFX.large.Draw("Drop",250,300,c5,c5,0) - GameGFX.large.Draw("Pause",250,330,c6,c6,0) - GameGFX.large.Draw(KeySym(GameConfig.kleft),500,180,c1,c1,0) - GameGFX.large.Draw(KeySym(GameConfig.kright),500,210,c2,c2,0) - GameGFX.large.Draw(KeySym(GameConfig.krotright),500,240,c3,c3,0) - GameGFX.large.Draw(KeySym(GameConfig.krotleft),500,270,c4,c4,0) - GameGFX.large.Draw(KeySym(GameConfig.kdrop),500,300,c5,c5,0) - GameGFX.large.Draw(KeySym(GameConfig.kpause),500,330,c6,c6,0) - - - Local k:Int=-1 - - For Local f:Int=0 To 255 - If KeyHit(f) - k=f - Continue - EndIf - Next - - If k=KEY_ESCAPE - GameConfig.Load() - defkey=0 - FlushKeys() - ElseIf k<>-1 - Select defkey - Case 1 - GameConfig.kleft=k - Case 2 - GameConfig.kright=k - Case 3 - GameConfig.krotright=k - Case 4 - GameConfig.krotleft=k - Case 5 - GameConfig.kdrop=k - Case 6 - GameConfig.kpause=k - End Select - - defkey:+1 - - If defkey=7 - GameConfig.Save() - defkey=0 - FlushKeys() - EndIf - EndIf - Else - If KeyHit(KEY_ESCAPE) - done=True - quit=True - EndIf - - TextParticles.Draw() - - GameGFX.large.Draw("START LEVEL ",tx1,356) - GameGFX.large.Draw(GameConfig.start_level,tx2,356,255,255,0) - - GameGFX.large.CentreOn("LAST SCORE",200,500) - GameGFX.large.CentreOn("HIGH SCORE",600,500) - GameGFX.large.CentreOn(last_score,200,520,255,col,0) - GameGFX.large.CentreOn(GameConfig.hiscore,600,520,255,col,0) - EndIf - - Select sel - Case MENU_PLAY - done=True - FlushKeys() - Case MENU_RULES - FlushKeys() - Local help:THelp=New THelp - TFadeScreen.DoFadeOut() - help.Show() - TFadeScreen.DoFadeOut() - fade=TFadeScreen.FadeIn() - Case MENU_KEYS - FlushKeys() - defkey=1 - Case MENU_QUIT - done=True - quit=True - Case MENU_LEFT - GameConfig.start_level=Max(1,GameConfig.start_level-1) - GameConfig.Save() - Case MENU_RIGHT - GameConfig.start_level=Min(10,GameConfig.start_level+1) - GameConfig.Save() - End Select - - Rem - SetScale(2,2) - GameGFX.font.Centre("HARDWIRE",0,255,255,0) - - SetScale(1,1) - GameGFX.font.Centre("Copyright (c) 2005 Ian C",20,255,0,0) - EndRem - - SetColor(255,255,255) - DrawImage(GameGFX.pointer,MouseX(),MouseY()) - - If fade - If fade.Fade() - fade.Draw() - Else - fade=Null - EndIf - EndIf - - Flip - Wend - - TextParticles.Clear() - - TFadeScreen.DoFadeOut() -End Function - - -' =================================== -' Debug -' =================================== -' -?debug -Function DebugCreate:TPiece(t:Int) - Local p:TPiece=TPiece.CreateSpecific(t) - p.x=8 - p.y=-3 - Return p -End Function - -Function DebugCode() - Local done:Int=False - Local gm:TGameMap=New TGameMap - Local t:Int=0 - Local p:TPiece=DebugCreate(t) - - While Not done - Cls - - If gm.overflow - GameGFX.large.Centre("OVERFLOW!",0) - EndIf - - gm.Draw() - - p.Draw() - - Local k:Int=-1 - - For Local f:Int=0 To 255 - If KeyHit(f) - k=f - Continue - EndIf - Next - - Select k - Case KEY_ESCAPE - done=True - - Case KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9 - t=k-KEY_0 - p=DebugCreate(t) - - Case KEY_LEFT - p.x:-1 - - Case KEY_RIGHT - p.x:+1 - - Case KEY_DOWN - p.y:+1 - - Case KEY_UP - p.y:-1 - - Case KEY_SPACE - p.RotateRight() - - Case KEY_ENTER - p.AddToMap(gm) - p=DebugCreate(t) - End Select - - Particles.Draw() - ExplosionParticles.Draw() - TextParticles.Draw() - Sound.Process() - Flip - Wend -End Function -? - +' Hardwire +' +' Copyright (C) 2005 Ian Cowburn (ianc@noddybox.co.uk) +' +' This program is free software; you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation; either version 2 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY; without even the implied warranty of +' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +' GNU General Public License for more details. +' +' You should have received a copy of the GNU General Public License +' along with this program; if not, write to the Free Software +' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +' +' ------------------------------------------------------------------------- +' +' $Id$ +' +Strict +Framework brl.basic +Import brl.max2d +Import brl.glmax2d +?Win32 +Import brl.d3d7max2d +? + +Import noddybox.bitmapfont +Import noddybox.keysyms +Import noddybox.gfxmenu + +Import "types.bmx" +Import "gametypes.bmx" +Import "game.bmx" +Import "particle.bmx" +Import "help.bmx" + +' =================================== +' Initialise +' =================================== +' +SeedRnd(MilliSecs()) + +?Win32 +If Switch("--directx") + SetGraphicsDriver D3D7Max2DDriver() +Else + SetGraphicsDriver GLMax2DDriver() +EndIf +? + +Graphics 800,600,32,HERTZ +HideMouse + +SetBlend(ALPHABLEND) +SetAlpha(1.0) + + +' =================================== +' Globals +' =================================== +' +GameGFX.Init() ' MUST be first + +Lookup.Init() +GameConfig.Load() +TWire.Init() +Particles.Init() +TextParticles.Init() +ExplosionParticles.Init() +Sound.Init() + +Global bdrop:TMenuBdrop=New TMenuBdrop +Global quit:Int=False +Global last_score:Int=0 + + +' =================================== +' Main +' =================================== +' +Menu() + +While Not quit + Local game:TGame=New TGame + game.SetInitLevel(GameConfig.start_level) + + While game.Play() + Wend + + TFadeScreen.DoFadeOut() + + GameConfig.Save() + last_score=game.score + + Menu() +Wend + +EndGraphics +End + + +' =================================== +' Argument Routines +' =================================== +' +Function Switch:Int(s:String) + For Local a:String=EachIn AppArgs + If a=s + Return True + EndIf + Next + + Return False +End Function + + +' =================================== +' Menu Routines +' =================================== +' +Function Menu() + Const MENU_PLAY:Int=1 + Const MENU_QUIT:Int=2 + Const MENU_RULES:Int=3 + Const MENU_KEYS:Int=4 + Const MENU_LEFT:Int=5 + Const MENU_RIGHT:Int=6 + + Local fade:TFadeScreen=TFadeScreen.FadeIn() + Local done:Int=False + 'Local menu:TGfxMenu=TGfxMenu.Create(255,0,0,255,255,255,25,bdrop,1) + Local menu:TGfxMenu=TGfxMenu.Create(255,0,0,255,255,255,15,bdrop,1) + Local sel:Int + + Local defkey:Int=0 + + Local x1:Int=GraphicsWidth()/3-ImageWidth(GameGFX.play_button)/2 + Local x2:Int=GraphicsWidth()/3*2-ImageWidth(GameGFX.play_button)/2 + + menu.Add(x1,150,GameGFX.play_button,MENU_PLAY) + menu.Add(x2,150,GameGFX.rules_button,MENU_RULES) + menu.Add(x1,250,GameGFX.keys_button,MENU_KEYS) + menu.Add(x2,250,GameGFX.quit_button,MENU_QUIT) + menu.Add(x1,350,GameGFX.left_button,MENU_LEFT) + menu.Add(x2+ImageWidth(GameGFX.play_button)-ImageWidth(GameGFX.right_button),350,GameGFX.right_button,MENU_RIGHT) + + Local tx1:Int=(GraphicsWidth()-GameGFX.large.TextWidth("START LEVEL 1"))/2 + Local tx2:Int=tx1+GameGFX.large.TextWidth("START LEVEL ") + + Local col:Int=128 + Local coli=1 + + TextParticles.Clear() + + While Not done + Cls + + SetColor(col,col,255) + DrawImage(GameGFX.title,0,0) + SetColor(255,255,255) + +?debug + If KeyHit(KEY_D) + DebugCode() + EndIf +? + + col:+coli + + If col=128 Or col=255 + coli=-coli + EndIf + + sel=menu.Render(defkey>0) + + If defkey>0 + + If defkey=7 + GameGFX.large.Centre("PRESS A KEY TO GO BACK TO THE MENU",150) + Else + GameGFX.large.Centre("DEFINE KEYS",150) + GameGFX.large.Centre("PRESS ESCAPE TO CANCEL",380) + EndIf + + Local c1:Int=128+128*(defkey=1) + Local c2:Int=128+128*(defkey=2) + Local c3:Int=128+128*(defkey=3) + Local c4:Int=128+128*(defkey=4) + Local c5:Int=128+128*(defkey=5) + Local c6:Int=128+128*(defkey=6) + + GameGFX.large.Draw("Left",250,180,c1,c1,0) + GameGFX.large.Draw("Right",250,210,c2,c2,0) + GameGFX.large.Draw("Rotate Right",250,240,c3,c3,0) + GameGFX.large.Draw("Rotate Left",250,270,c4,c4,0) + GameGFX.large.Draw("Drop",250,300,c5,c5,0) + GameGFX.large.Draw("Pause",250,330,c6,c6,0) + GameGFX.large.Draw(KeySym(GameConfig.kleft),500,180,c1,c1,0) + GameGFX.large.Draw(KeySym(GameConfig.kright),500,210,c2,c2,0) + GameGFX.large.Draw(KeySym(GameConfig.krotright),500,240,c3,c3,0) + GameGFX.large.Draw(KeySym(GameConfig.krotleft),500,270,c4,c4,0) + GameGFX.large.Draw(KeySym(GameConfig.kdrop),500,300,c5,c5,0) + GameGFX.large.Draw(KeySym(GameConfig.kpause),500,330,c6,c6,0) + + + Local k:Int=-1 + + For Local f:Int=0 To 255 + If KeyHit(f) + k=f + Continue + EndIf + Next + + If k=KEY_ESCAPE + GameConfig.Load() + defkey=0 + FlushKeys() + ElseIf k<>-1 + Select defkey + Case 1 + GameConfig.kleft=k + Case 2 + GameConfig.kright=k + Case 3 + GameConfig.krotright=k + Case 4 + GameConfig.krotleft=k + Case 5 + GameConfig.kdrop=k + Case 6 + GameConfig.kpause=k + End Select + + defkey:+1 + + If defkey=7 + GameConfig.Save() + defkey=0 + FlushKeys() + EndIf + EndIf + Else + If KeyHit(KEY_ESCAPE) + done=True + quit=True + EndIf + + TextParticles.Draw() + + GameGFX.large.Draw("START LEVEL ",tx1,356) + GameGFX.large.Draw(GameConfig.start_level,tx2,356,255,255,0) + + GameGFX.large.CentreOn("LAST SCORE",200,500) + GameGFX.large.CentreOn("HIGH SCORE",600,500) + + GameGFX.large.CentreOn(Number.Format(last_score),200,520,255,col,0) + GameGFX.large.CentreOn(Number.Format(GameConfig.hiscore),600,520,255,col,0) + EndIf + + Select sel + Case MENU_PLAY + done=True + FlushKeys() + Case MENU_RULES + FlushKeys() + Local help:THelp=New THelp + TFadeScreen.DoFadeOut() + help.Show() + TFadeScreen.DoFadeOut() + fade=TFadeScreen.FadeIn() + Case MENU_KEYS + FlushKeys() + defkey=1 + Case MENU_QUIT + done=True + quit=True + Case MENU_LEFT + GameConfig.start_level=Max(1,GameConfig.start_level-1) + GameConfig.Save() + Case MENU_RIGHT + GameConfig.start_level=Min(10,GameConfig.start_level+1) + GameConfig.Save() + End Select + + Rem + SetScale(2,2) + GameGFX.font.Centre("HARDWIRE",0,255,255,0) + + SetScale(1,1) + GameGFX.font.Centre("Copyright (c) 2005 Ian C",20,255,0,0) + EndRem + + SetColor(255,255,255) + DrawImage(GameGFX.pointer,MouseX(),MouseY()) + + If fade + If fade.Fade() + fade.Draw() + Else + fade=Null + EndIf + EndIf + + Flip + Wend + + TextParticles.Clear() + + TFadeScreen.DoFadeOut() +End Function + + +' =================================== +' Debug +' =================================== +' +?debug +Function DebugCreate:TPiece(t:Int) + Local p:TPiece=TPiece.CreateSpecific(t) + p.x=8 + p.y=-3 + Return p +End Function + +Function DebugCode() + Local done:Int=False + Local gm:TGameMap=New TGameMap + Local t:Int=0 + Local p:TPiece=DebugCreate(t) + + While Not done + Cls + + If gm.overflow + GameGFX.large.Centre("OVERFLOW!",0) + EndIf + + gm.Draw() + + GameGFX.small.CentreOn(Number.Format(MilliSecs()),200,590) + GameGFX.small.CentreOn(Number.Format(MilliSecs()*2),600,590) + GameGFX.small.Centre(Number.Format(MilliSecs()*100),590) + + p.Draw() + + Local k:Int=-1 + + For Local f:Int=0 To 255 + If KeyHit(f) + k=f + Continue + EndIf + Next + + Select k + Case KEY_ESCAPE + done=True + + Case KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9 + t=k-KEY_0 + p=DebugCreate(t) + + Case KEY_LEFT + p.x:-1 + + Case KEY_RIGHT + p.x:+1 + + Case KEY_DOWN + p.y:+1 + + Case KEY_UP + p.y:-1 + + Case KEY_SPACE + p.RotateRight() + + Case KEY_ENTER + p.AddToMap(gm) + p=DebugCreate(t) + End Select + + Particles.Draw() + ExplosionParticles.Draw() + TextParticles.Draw() + Sound.Process() + Flip + Wend +End Function +? + diff --git a/help.bmx b/help.bmx index ccf3aaa..479bc6a 100644 --- a/help.bmx +++ b/help.bmx @@ -1,289 +1,309 @@ -' Hardwire -' -' Copyright 2005 Ian Cowburn -' -' $Id$ -' -Strict -Import brl.pngloader - -Import noddybox.bitmapfont -Import noddybox.gfxmenu - -Import "types.bmx" - - -' Included binaries -' -Incbin "HELP/help.txt" -Incbin "HELP/pit.png" -Incbin "HELP/piece.png" -Incbin "HELP/wire1.png" -Incbin "HELP/wire2.png" -Incbin "HELP/wire3.png" -Incbin "HELP/loop1.png" -Incbin "HELP/bomb.png" -Incbin "HELP/twister.png" -Incbin "HELP/nuke.png" -Incbin "HELP/cross.png" - -Type THelp - Const TOP:Int=50 - Const BOTTOM:Int=550 - Field list:TList - Field pos:Int - Field item:TLink - Field del:Int - - Method New() - Local str:TStream=ReadStream("incbin::HELP/help.txt") - - Assert str,"Unable to open help file" - - list=CreateList() - - While Not str.Eof() - Local line:String=str.ReadLine() - - If line.length - Select line[0] - Case Asc("#") - list.AddLast(THelpImage.Create(line[1..])) - Case Asc("$") - list.AddLast(THelpAnimImage.Create(line[1..],False)) - Case Asc("~~") - list.AddLast(THelpAnimImage.Create(line[1..],True)) - Default - list.AddLast(THelpText.Create(line)) - End Select - Else - list.AddLast(THelpBlankLine.Create(line)) - EndIf - Wend - - item=list.LastLink() - pos=TOP-Current().Height() - End Method - - Method Draw() - Local y:Int=pos - Local i:TLink=item - - While yTOP - item=item.PrevLink() - If Not item - item=list.LastLink() - EndIf - pos:-Current().Height() - Wend - ElseIf KeyHit(KEY_ESCAPE) - FlushKeys() - done=True - Else - del=0 - EndIf - - If fade - If fade.Fade() - fade.Draw() - Else - fade=Null - EndIf - EndIf - - Flip - Wend - - SetColor(255,255,255) - End Method -End Type - -Type THelpItem Abstract - Method Height:Int() Abstract - Method Draw(y:Int) Abstract -End Type - -Type THelpText Extends THelpItem - Field txt:String - Field r:Int - Field g:Int - Field b:Int - Field sc:Int - - Function Create:THelpItem(txt:String) - Local o:THelpText=New THelpText - - Select txt[0] - Case Asc("@") - o.sc=2 - o.r=255 - o.g=255 - o.b=0 - o.txt=txt[1..] - Case Asc("!") - o.sc=1 - o.r=255 - o.g=255 - o.b=0 - o.txt=txt[1..] - Default - o.sc=1 - o.r=255 - o.g=255 - o.b=255 - o.txt=txt - End Select - - Return THelpItem(o) - End Function - - Method Height:Int() - Return GameGFX.large.MaxHeight()*sc - End Method - - Method Draw(y:Int) - SetScale(sc,sc) - GameGFX.large.Centre(txt,y,r,g,b) - SetScale(1,1) - End Method -End Type - - -Type THelpBlankLine Extends THelpItem - Function Create:THelpItem(txt:String) - Local o:THelpBlankLine=New THelpBlankLine - Return THelpItem(o) - End Function - - Method Height:Int() - Return GameGFX.large.MaxHeight() - End Method - - Method Draw(y:Int) - End Method -End Type - - -Type THelpImage Extends THelpItem - Field img:TImage - Field x:Int - - Function Create:THelpItem(url:String) - Local o:THelpImage=New THelpImage - o.img=LoadImage(url) - Assert o.img,"Failed to load help image " + url - o.x=(GraphicsWidth()-ImageWidth(o.img))/2 - Return THelpItem(o) - End Function - - Method Height:Int() - Return ImageHeight(img) - End Method - - Method Draw(y:Int) - SetColor(255,255,255) - DrawImage(img,x,y) - End Method -End Type - - -Type THelpAnimImage Extends THelpItem - Field img:TImage - Field x:Int - Field frame:Int - Field framei:Int - Field framed:Int - Field pong:Int - - Function Create:THelpItem(url:String,pong:Int) - Local o:THelpAnimImage=New THelpAnimImage - o.img=LoadAnimImage(url,32,32,0,4) - Assert o.img,"Failed to load help anim image " + url - o.x=(GraphicsWidth()-32)/2 - o.frame=0 - o.framed=5 - o.framei=1 - o.pong=pong - Return THelpItem(o) - End Function - - Method Height:Int() - Return ImageHeight(img) - End Method - - Method Draw(y:Int) - SetColor(255,255,255) - DrawImage(img,x,y,frame) - framed:-1 - If framed=0 - framed=5 - If pong - frame:+framei - If frame=0 Or frame=3 - framei=-framei - EndIf - Else - frame=(frame+1) Mod 4 - EndIf - EndIf - End Method -End Type \ No newline at end of file +' Hardwire +' +' Copyright (C) 2005 Ian Cowburn (ianc@noddybox.co.uk) +' +' This program is free software; you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation; either version 2 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY; without even the implied warranty of +' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +' GNU General Public License for more details. +' +' You should have received a copy of the GNU General Public License +' along with this program; if not, write to the Free Software +' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +' +' ------------------------------------------------------------------------- +' +' $Id$ +' +Strict +Import brl.pngloader + +Import noddybox.bitmapfont +Import noddybox.gfxmenu + +Import "types.bmx" + + +' Included binaries +' +Incbin "HELP/help.txt" +Incbin "HELP/pit.png" +Incbin "HELP/piece.png" +Incbin "HELP/wire1.png" +Incbin "HELP/wire2.png" +Incbin "HELP/wire3.png" +Incbin "HELP/loop1.png" +Incbin "HELP/bomb.png" +Incbin "HELP/twister.png" +Incbin "HELP/nuke.png" +Incbin "HELP/cross.png" + +Type THelp + Const TOP:Int=50 + Const BOTTOM:Int=550 + Field list:TList + Field pos:Int + Field item:TLink + Field del:Int + Field bd:TGameBackdrop + + Method New() + Local str:TStream=ReadStream("incbin::HELP/help.txt") + + Assert str,"Unable to open help file" + + list=CreateList() + + While Not str.Eof() + Local line:String=str.ReadLine() + + If line.length + Select line[0] + Case Asc("#") + list.AddLast(THelpImage.Create(line[1..])) + Case Asc("$") + list.AddLast(THelpAnimImage.Create(line[1..],False)) + Case Asc("~~") + list.AddLast(THelpAnimImage.Create(line[1..],True)) + Default + list.AddLast(THelpText.Create(line)) + End Select + Else + list.AddLast(THelpBlankLine.Create(line)) + EndIf + Wend + + bd=New TGameBackdrop + item=list.LastLink() + pos=TOP-Current().Height() + End Method + + Method Draw() + bd.Draw() + + Local y:Int=pos + Local i:TLink=item + + While yTOP + item=item.PrevLink() + If Not item + item=list.LastLink() + EndIf + pos:-Current().Height() + Wend + ElseIf KeyHit(KEY_ESCAPE) + FlushKeys() + done=True + Else + del=0 + EndIf + + If fade + If fade.Fade() + fade.Draw() + Else + fade=Null + EndIf + EndIf + + Flip + Wend + + SetColor(255,255,255) + End Method +End Type + +Type THelpItem Abstract + Method Height:Int() Abstract + Method Draw(y:Int) Abstract +End Type + +Type THelpText Extends THelpItem + Field txt:String + Field r:Int + Field g:Int + Field b:Int + Field sc:Int + + Function Create:THelpItem(txt:String) + Local o:THelpText=New THelpText + + Select txt[0] + Case Asc("@") + o.sc=2 + o.r=255 + o.g=255 + o.b=0 + o.txt=txt[1..] + Case Asc("!") + o.sc=1 + o.r=255 + o.g=255 + o.b=0 + o.txt=txt[1..] + Default + o.sc=1 + o.r=255 + o.g=255 + o.b=255 + o.txt=txt + End Select + + Return THelpItem(o) + End Function + + Method Height:Int() + Return GameGFX.large.MaxHeight()*sc + End Method + + Method Draw(y:Int) + SetScale(sc,sc) + GameGFX.large.Centre(txt,y,r,g,b) + SetScale(1,1) + End Method +End Type + + +Type THelpBlankLine Extends THelpItem + Function Create:THelpItem(txt:String) + Local o:THelpBlankLine=New THelpBlankLine + Return THelpItem(o) + End Function + + Method Height:Int() + Return GameGFX.large.MaxHeight() + End Method + + Method Draw(y:Int) + End Method +End Type + + +Type THelpImage Extends THelpItem + Field img:TImage + Field x:Int + + Function Create:THelpItem(url:String) + Local o:THelpImage=New THelpImage + o.img=LoadImage(url,0) + Assert o.img,"Failed to load help image " + url + o.x=(GraphicsWidth()-ImageWidth(o.img))/2 + Return THelpItem(o) + End Function + + Method Height:Int() + Return ImageHeight(img) + End Method + + Method Draw(y:Int) + SetColor(255,255,255) + DrawImage(img,x,y) + End Method +End Type + + +Type THelpAnimImage Extends THelpItem + Field img:TImage + Field x:Int + Field frame:Int + Field framei:Int + Field framed:Int + Field pong:Int + + Function Create:THelpItem(url:String,pong:Int) + Local o:THelpAnimImage=New THelpAnimImage + o.img=LoadAnimImage(url,32,32,0,4,0) + Assert o.img,"Failed to load help anim image " + url + o.x=(GraphicsWidth()-32)/2 + o.frame=0 + o.framed=5 + o.framei=1 + o.pong=pong + Return THelpItem(o) + End Function + + Method Height:Int() + Return ImageHeight(img) + End Method + + Method Draw(y:Int) + SetColor(255,255,255) + DrawImage(img,x,y,frame) + framed:-1 + If framed=0 + framed=5 + If pong + frame:+framei + If frame=0 Or frame=3 + framei=-framei + EndIf + Else + frame=(frame+1) Mod 4 + EndIf + EndIf + End Method +End Type diff --git a/particle.bmx b/particle.bmx index 40a9c24..6e8d469 100644 --- a/particle.bmx +++ b/particle.bmx @@ -1,318 +1,334 @@ -' Hardwire -' -' Copyright 2005 Ian Cowburn -' -' $Id$ -' -Strict -Import "types.bmx" - -Type TParticle - Field life:Int - Field i:TImage - Field x:Double - Field y:Double - Field a:Double - Field dx:Double - Field dy:Double - Field ai:Double - Field s:Double - Field si:Double - - Function Dust:TParticle(x:Int, y:Int) - Local o:TParticle=New TParticle - o.life=50 - o.x=x - o.y=y - o.a=1 - o.ai=-0.05 - o.dx=0 - o.dy=0 - o.s=1 - o.si=0.1 - o.i=GameGFX.dust - Return o - End Function - - Function Image:TParticle(i:TImage, x:Int, y:Int) - Local o:TParticle=New TParticle - o.life=120 - o.x=x - o.y=y - o.a=1 - o.ai=-0.01 - o.dx=0 - o.dy=-0.1 - o.s=1 - o.si=0 - o.i=i - Return o - End Function - - Method Update:Int() - SetAlpha(a) - SetScale(s,s) - DrawImage(i,x,y) - x:+dx - y:+dy - life:-1 - a:+ai - s:+si - Return life>0 - End Method -End Type - -Type Particles - Global plist:TList - - Function Init() - plist=CreateList() - End Function - - Function Clear() - plist.Clear() - End Function - - Function AddDust(x:Int, y:Int) - plist.AddLast(TParticle.Dust(x,y)) - End Function - - Function AddImage(i:TImage, x:Int, y:Int) - plist.AddLast(TParticle.Image(i,x,y)) - End Function - - Function Draw() - SetColor(255,255,255) - Local l:TEasyLink=TEasyLink.Create(plist) - - While l.Value() - Local p:TParticle=TParticle(l.Value()) - - If (p.Update()) - l.MoveNext() - Else - l.Remove() - EndIf - Wend - SetAlpha(1) - SetScale(1,1) - End Function -End Type - -Type TTextParticle - Field txt:String - Field x:Double - Field y:Double - Field a:Double - Field dx:Double - Field dy:Double - Field ai:Double - Field s:Double - Field si:Double - Field r:Int - Field g:Int - Field b:Int - Field fnt:TBitmapFont - - Function Create:TTextParticle(fnt:TBitmapFont, txt:String, x:Double, y:Double, dx:Double, dy:Double, r:Int, g:Int, b:Int, a:Double, ai:Double, s:Double, si:Double) - Local o:TTextParticle=New TTextParticle - - If x=-1 - x=GraphicsWidth()/2 - EndIf - - o.x=x - o.y=y - o.a=a - o.ai=ai - o.dx=dx - o.dy=dy - o.s=s - o.si=si - o.txt=txt - o.r=r - o.g=g - o.b=b - o.fnt=fnt - Return o - End Function - - Method Update:Int() - SetAlpha(a) - SetScale(s,s) - fnt.CentreOn(txt,x,y,r,g,b) - x:+dx - y:+dy - a:+ai - s:+si - Return a>0 - End Method -End Type - -Type TextParticles - Global plist:TList - Global sy:Int - Const sx:Int=646 - - Function Init() - plist=CreateList() - sy=300 - End Function - - Function Clear() - plist.Clear() - sy=300 - End Function - - Function Big(txt:String, r:Int=-1, g:Int=-1, b:Int=-1) - If r=-1 Then r=Rand(128,255) - If g=-1 Then g=Rand(128,255) - If b=-1 Then b=Rand(128,255) - plist.AddLast(TTextParticle.Create(GameGFX.font,txt,-1,GraphicsHeight()-GameGFX.font.MaxHeight()/2,0,0,r,g,b,1,-0.01,1,0)) - plist.AddLast(TTextParticle.Create(GameGFX.font,txt,-1,GraphicsHeight()-GameGFX.font.MaxHeight()/2,0,0,r,g,b,1,-0.02,1,0.1)) - End Function - - Function Score(txt:String) - Local r:Int=Rand(128,255) - Local g:Int=Rand(128,255) - Local b:Int=Rand(128,255) - - plist.AddLast(TTextParticle.Create(GameGFX.font,txt,sx,sy,0,0,r,g,b,1,-0.01,1,0)) - plist.AddLast(TTextParticle.Create(GameGFX.font,txt,sx,sy,0,0,r,g,b,1,-0.02,1,0.1)) - - sy:+GameGFX.font.MaxHeight() - - If sy>GraphicsHeight()-20 - sy=300 - EndIf - End Function - - Function Draw() - Local l:TEasyLink=TEasyLink.Create(plist) - - While l.Value() - Local p:TTextParticle=TTextParticle(l.Value()) - - If (p.Update()) - l.MoveNext() - Else - l.Remove() - EndIf - Wend - SetColor(255,255,255) - SetAlpha(1) - SetScale(1,1) - End Function -End Type - - -Type TExplosionBase - Field p:TPixmap[4] - - Function Create:TExplosionBase(base:TImage) - Local o:TExplosionBase=New TExplosionBase - o.p=New TPixmap[4] - o.p[0]=GrabFrom(base,0,0) - o.p[1]=GrabFrom(base,16,0) - o.p[2]=GrabFrom(base,0,16) - o.p[3]=GrabFrom(base,16,16) - Return o - End Function - - Function GrabFrom:TPixmap(i:TImage,x:Int, y:Int) - Local p:TPixmap=LockImage(i) - Local ret:TPixmap=p.Copy() - ret=ResizePixmap(ret,16,16) - For Local cx:Int=0 Until 16 - For Local cy:Int=0 Until 16 - ret.WritePixel(cx,cy,p.ReadPixel(x+cx,y+cy)) - Next - Next - UnlockImage(i) - Return ret - End Function -End Type - -Type TExplosion_Old - Field x:Double - Field y:Double - Field dy:Double - Field dx:Double - Field p:TPixmap - - Function Create:TExplosion(p:TPixmap,x:Double,y:Double,dx:Double,dy:Double) - Local o:TExplosion=New TExplosion - o.x=x - o.y=y - o.dx=dx - o.dy=dy - Return o - End Function - - Method Update:Int() - DrawPixmap(p,x,y) - x:+dx - y:+dy - dy:+0.05 - Return dx>-16 And dx-16 And dx0 + End Method +End Type + +Type Particles + Global plist:TList + + Function Init() + plist=CreateList() + End Function + + Function Clear() + plist.Clear() + End Function + + Function AddDust(x:Int, y:Int) + plist.AddLast(TParticle.Dust(x,y)) + End Function + + Function AddImage(i:TImage, x:Int, y:Int) + plist.AddLast(TParticle.Image(i,x,y)) + End Function + + Function Draw() + SetColor(255,255,255) + Local l:TEasyLink=TEasyLink.Create(plist) + + While l.Value() + Local p:TParticle=TParticle(l.Value()) + + If (p.Update()) + l.MoveNext() + Else + l.Remove() + EndIf + Wend + SetAlpha(1) + SetScale(1,1) + End Function +End Type + +Type TTextParticle + Field txt:String + Field x:Double + Field y:Double + Field a:Double + Field dx:Double + Field dy:Double + Field ai:Double + Field s:Double + Field si:Double + Field r:Int + Field g:Int + Field b:Int + Field fnt:TBitmapFont + + Function Create:TTextParticle(fnt:TBitmapFont, txt:String, x:Double, y:Double, dx:Double, dy:Double, r:Int, g:Int, b:Int, a:Double, ai:Double, s:Double, si:Double) + Local o:TTextParticle=New TTextParticle + + If x=-1 + x=GraphicsWidth()/2 + EndIf + + o.x=x + o.y=y + o.a=a + o.ai=ai + o.dx=dx + o.dy=dy + o.s=s + o.si=si + o.txt=txt + o.r=r + o.g=g + o.b=b + o.fnt=fnt + Return o + End Function + + Method Update:Int() + SetAlpha(a) + SetScale(s,s) + fnt.CentreOn(txt,x,y,r,g,b) + x:+dx + y:+dy + a:+ai + s:+si + Return a>0 + End Method +End Type + +Type TextParticles + Global plist:TList + Global sy:Int + Const sx:Int=646 + + Function Init() + plist=CreateList() + sy=300 + End Function + + Function Clear() + plist.Clear() + sy=300 + End Function + + Function Big(txt:String, r:Int=-1, g:Int=-1, b:Int=-1) + If r=-1 Then r=Rand(128,255) + If g=-1 Then g=Rand(128,255) + If b=-1 Then b=Rand(128,255) + plist.AddLast(TTextParticle.Create(GameGFX.font,txt,-1,GraphicsHeight()-GameGFX.font.MaxHeight()/2,0,0,r,g,b,1,-0.01,1,0)) + plist.AddLast(TTextParticle.Create(GameGFX.font,txt,-1,GraphicsHeight()-GameGFX.font.MaxHeight()/2,0,0,r,g,b,1,-0.02,1,0.1)) + End Function + + Function Score(txt:String) + Local r:Int=Rand(128,255) + Local g:Int=Rand(128,255) + Local b:Int=Rand(128,255) + + plist.AddLast(TTextParticle.Create(GameGFX.font,txt,sx,sy,0,0,r,g,b,1,-0.01,1,0)) + plist.AddLast(TTextParticle.Create(GameGFX.font,txt,sx,sy,0,0,r,g,b,1,-0.02,1,0.1)) + + sy:+GameGFX.font.MaxHeight() + + If sy>GraphicsHeight()-20 + sy=300 + EndIf + End Function + + Function Draw() + Local l:TEasyLink=TEasyLink.Create(plist) + + While l.Value() + Local p:TTextParticle=TTextParticle(l.Value()) + + If (p.Update()) + l.MoveNext() + Else + l.Remove() + EndIf + Wend + SetColor(255,255,255) + SetAlpha(1) + SetScale(1,1) + End Function +End Type + + +Type TExplosionBase + Field p:TPixmap[4] + + Function Create:TExplosionBase(base:TImage) + Local o:TExplosionBase=New TExplosionBase + o.p=New TPixmap[4] + o.p[0]=GrabFrom(base,0,0) + o.p[1]=GrabFrom(base,16,0) + o.p[2]=GrabFrom(base,0,16) + o.p[3]=GrabFrom(base,16,16) + Return o + End Function + + Function GrabFrom:TPixmap(i:TImage,x:Int, y:Int) + Local p:TPixmap=LockImage(i) + Local ret:TPixmap=p.Copy() + ret=ResizePixmap(ret,16,16) + For Local cx:Int=0 Until 16 + For Local cy:Int=0 Until 16 + ret.WritePixel(cx,cy,p.ReadPixel(x+cx,y+cy)) + Next + Next + UnlockImage(i) + Return ret + End Function +End Type + +Type TExplosion_Old + Field x:Double + Field y:Double + Field dy:Double + Field dx:Double + Field p:TPixmap + + Function Create:TExplosion(p:TPixmap,x:Double,y:Double,dx:Double,dy:Double) + Local o:TExplosion=New TExplosion + o.x=x + o.y=y + o.dx=dx + o.dy=dy + Return o + End Function + + Method Update:Int() + DrawPixmap(p,x,y) + x:+dx + y:+dy + dy:+0.05 + Return dx>-16 And dx-16 And dx0 And a<1 - End Method - - Method Draw() - Local r:Int,g:Int,b:Int - Local oa:Double=GetAlpha() - GetColor(r,g,b) - SetAlpha(a) - SetColor(0,0,0) - DrawRect(0,0,GraphicsWidth(),GraphicsHeight()) - SetColor(r,g,b) - SetAlpha(oa) - End Method -End Type - -Type TGameBackdropStar - Field x:Double - Field y:Double - Field dy:Double - Field r:Int - Field g:Int - Field b:Int - Field frame:Int - Field cnt:Int - - Method New() - x=Rnd(0,GraphicsWidth()) - y=Rnd(0,GraphicsHeight()) - dy=Rnd(0.1,2) - r=Rand(128,255) - g=Rand(128,255) - b=Rand(128,255) - frame=Rand(0,5) - cnt=5 - End Method - - Method Draw(anim:Int) - If anim - frame=(frame+1) Mod 6 - EndIf - - y:+dy - If y>GraphicsHeight()+8 - y=-8 - EndIf - SetColor(r,g,b) - DrawImage(GameGFX.bdropstar,x,y,frame) - End Method -End Type - - -Type TGameBackdrop - Field num:Int - Field star:TGameBackdropStar[] - Field cnt:Int - - Method New() - num=100 - star=New TGameBackdropStar[num] - cnt=5 - - For Local f:Int=0 Until num - star[f]=New TGameBackdropStar - Next - End Method - - Method Draw() - For Local f:Int=0 Until num - star[f].Draw(cnt=0) - Next - cnt:-1 - If cnt=-1 - cnt=5 - EndIf - End Method -End Type \ No newline at end of file +' Hardwire +' +' Copyright (C) 2005 Ian Cowburn (ianc@noddybox.co.uk) +' +' This program is free software; you can redistribute it and/or modify +' it under the terms of the GNU General Public License as published by +' the Free Software Foundation; either version 2 of the License, or +' (at your option) any later version. +' +' This program is distributed in the hope that it will be useful, +' but WITHOUT ANY WARRANTY; without even the implied warranty of +' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +' GNU General Public License for more details. +' +' You should have received a copy of the GNU General Public License +' along with this program; if not, write to the Free Software +' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +' +' ------------------------------------------------------------------------- +' +' $Id$ +' +' +' This should really be called Global.bmx probably... +' +Strict +Import brl.pngloader + +Import noddybox.bitmapfont +Import noddybox.gfxmenu + + +' Included binaries +' +Incbin "GFX/font.bmf" +Incbin "GFX/small.bmf" +Incbin "GFX/large.bmf" +Incbin "GFX/pointer.png" +Incbin "GFX/play_button.png" +Incbin "GFX/quit_button.png" +Incbin "GFX/keys_button.png" +Incbin "GFX/rules_button.png" +Incbin "GFX/left_button.png" +Incbin "GFX/right_button.png" +Incbin "GFX/copper.png" +Incbin "GFX/copperslice.png" +Incbin "GFX/dust.png" +Incbin "GFX/title.png" +Incbin "GFX/gameover.png" +Incbin "GFX/bdropstar.png" + +Incbin "TILES/tile.png" +Incbin "TILES/pit_top.png" +Incbin "TILES/pit_bottomleft.png" +Incbin "TILES/pit_bottomright.png" +Incbin "TILES/pit_bottom.png" +Incbin "TILES/pit_side.png" +Incbin "TILES/trode_left.png" +Incbin "TILES/trode_right.png" +Incbin "TILES/trode_bottom.png" +Incbin "TILES/top_bottom.png" +Incbin "TILES/left_right.png" +Incbin "TILES/cross.png" +Incbin "TILES/top_left.png" +Incbin "TILES/top_right.png" +Incbin "TILES/bottom_left.png" +Incbin "TILES/bottom_right.png" + +Incbin "TILES/special_bomb.png" +Incbin "TILES/special_twister.png" +Incbin "TILES/special_nuke.png" +Incbin "TILES/special_cross.png" + +Const HERTZ:Int=60 + +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 small:TBitmapFont + Global large:TBitmapFont + + Global title:TImage + Global gameover:TImage + + Global pointer:TImage + Global copper:TImage + Global copperslice:TImage + Global dust:TImage + + Global play_button:TImage + Global quit_button:TImage + Global left_button:TImage + Global right_button:TImage + Global rules_button:TImage + Global keys_button:TImage + + Global tile:TImage + + Global pit_top:TImage + Global pit_bottomleft:TImage + Global pit_bottomright:TImage + Global pit_bottom:TImage + Global pit_side:TImage + + Global trode_left:TImage + Global trode_right:TImage + Global trode_bottom:TImage + + Global top_bottom:Timage + Global left_right:Timage + Global cross:Timage + Global top_left:Timage + Global top_right:Timage + Global bottom_left:Timage + Global bottom_right:Timage + + Global special_bomb:TImage + Global special_twister:TImage + Global special_nuke:TImage + Global special_cross:TImage + + Global bdropstar:TImage + + Function SafeLoadImage:TImage(p:String, mode:Int) + Local i:TImage=LoadImage(p,mode) + Assert i,"Failed to load " + p + Return i + End Function + + Function SafeLoadAnimImage:TImage(p:String, w:Int, h:Int, f:Int, c:Int, mode:Int) + Local i:TImage=LoadAnimImage(p,w,h,f,c,mode) + Assert i,"Failed to load " + p + Return i + End Function + + Function Init() + font=TBitmapFont.Load("incbin::GFX/font.bmf",0) + small=TBitmapFont.Load("incbin::GFX/small.bmf",0) + large=TBitmapFont.Load("incbin::GFX/large.bmf",0) + + Assert font,"Failed to load incbin::GFX/font.bmf" + Assert small,"Failed to load incbin::GFX/small.bmf" + Assert large,"Failed to load incbin::GFX/large.bmf" + + title=SafeLoadImage("incbin::GFX/title.png",0) + gameover=SafeLoadImage("incbin::GFX/gameover.png",0) + MidHandleImage(gameover) + + pointer=SafeLoadImage("incbin::GFX/pointer.png",0) + + copper=SafeLoadImage("incbin::GFX/copper.png",0) + copperslice=SafeLoadImage("incbin::GFX/copperslice.png",0) + + dust=SafeLoadImage("incbin::GFX/dust.png",FILTEREDIMAGE) + MidHandleImage(dust) + + play_button=SafeLoadImage("incbin::GFX/play_button.png",0) + quit_button=SafeLoadImage("incbin::GFX/quit_button.png",0) + rules_button=SafeLoadImage("incbin::GFX/rules_button.png",0) + keys_button=SafeLoadImage("incbin::GFX/keys_button.png",0) + left_button=SafeLoadImage("incbin::GFX/left_button.png",0) + right_button=SafeLoadImage("incbin::GFX/right_button.png",0) + + tile=SafeLoadImage("incbin::TILES/tile.png",0) + + pit_top=SafeLoadImage("incbin::TILES/pit_top.png",0) + pit_bottom=SafeLoadImage("incbin::TILES/pit_bottom.png",0) + pit_bottomleft=SafeLoadImage("incbin::TILES/pit_bottomleft.png",0) + pit_bottomright=SafeLoadImage("incbin::TILES/pit_bottomright.png",0) + pit_side=SafeLoadImage("incbin::TILES/pit_side.png",0) + + trode_left=SafeLoadImage("incbin::TILES/trode_left.png",0) + trode_right=SafeLoadImage("incbin::TILES/trode_right.png",0) + trode_bottom=SafeLoadImage("incbin::TILES/trode_bottom.png",0) + + top_bottom=SafeLoadImage("incbin::TILES/top_bottom.png",0) + left_right=SafeLoadImage("incbin::TILES/left_right.png",0) + cross=SafeLoadImage("incbin::TILES/cross.png",0) + top_left=SafeLoadImage("incbin::TILES/top_left.png",0) + top_right=SafeLoadImage("incbin::TILES/top_right.png",0) + bottom_left=SafeLoadImage("incbin::TILES/bottom_left.png",0) + bottom_right=SafeLoadImage("incbin::TILES/bottom_right.png",0) + + special_bomb=SafeLoadAnimImage("incbin::TILES/special_bomb.png",32,32,0,4,DYNAMICIMAGE) + special_twister=SafeLoadAnimImage("incbin::TILES/special_twister.png",32,32,0,4,DYNAMICIMAGE) + special_nuke=SafeLoadAnimImage("incbin::TILES/special_nuke.png",32,32,0,4,DYNAMICIMAGE) + special_cross=SafeLoadAnimImage("incbin::TILES/special_cross.png",32,32,0,4,DYNAMICIMAGE) + + bdropstar=SafeLoadAnimImage("incbin::GFX/bdropstar.png",8,8,0,6,0)'FILTEREDIMAGE) + End Function +End Type + +Type GameConfig + Global kleft:Int + Global kright:Int + Global krotright:Int + Global krotleft:Int + Global kdrop:Int + Global kpause:Int + Global start_level:Int + Global hiscore:Int + + Function Load() + Local s:TStream=ReadStream("hardwire.config") + + If s=Null + kleft=KEY_LEFT + kright=KEY_RIGHT + krotright=KEY_UP + krotleft=KEY_DOWN + kdrop=KEY_SPACE + kpause=KEY_P + start_level=1 + hiscore=0 + Return + EndIf + + s=LittleEndianStream(s) + + kleft=s.ReadInt() + kright=s.ReadInt() + krotright=s.ReadInt() + krotleft=s.ReadInt() + kdrop=s.ReadInt() + kpause=s.ReadInt() + start_level=s.ReadInt() + hiscore=s.ReadInt() + + s.Close() + End Function + + Function Save() + Local s:TStream=WriteStream("hardwire.config") + + If s=Null + Return + EndIf + + s=LittleEndianStream(s) + + s.WriteInt(kleft) + s.WriteInt(kright) + s.WriteInt(krotright) + s.WriteInt(krotleft) + s.WriteInt(kdrop) + s.WriteInt(kpause) + s.WriteInt(start_level) + s.WriteInt(hiscore) + + s.Close() + End Function +EndType + +Type TEasyLink + Field l:TLink + + Function Create:TEasyLink(l:TList) + Local o:TEasyLink=New TEasyLink + o.l=l.FirstLink() + Return o + End Function + + Method Value:Object() + If l + Return l.Value() + Else + Return Null + EndIf + End Method + + Method MoveNext() + If l + l=l.NextLink() + EndIf + End Method + + Method Remove() + Local ol:TLink=l + MoveNext() + ol.Remove() + End Method +End Type + + +Type TMenuBdrop Extends TGfxMenuBackdrop + Field msg:String + Field msgp:Int + Field msgx:Int + Field msgy:Int + + Method New() + msg=" " + msg=" " + msg:+"Welcome to Hardwire. " + msg:+"Hardwire was written using BlitzMax -- http://www.blitzbasic.com/ -- and a variety of tools available at " + msg:+"http://www.noddybox.demon.co.uk/ Please feel free to forward this game to whoever you hate enough " + msg:+"to inflict this monstrosity upon. Enjoy. This game written under the influence of Slay Radio -- http://www.slayradio.org" + + msgx=0 + msgp=0 + msgy=560 + End Method + + Method Create:TGfxMenuBackdrop() + Return Self + End Method + + Method Update() + GameGFX.large.Draw(msg[..80],msgx,msgy) + + msgx:-2 + If msgx<-GameGFX.large.TextWidth(msg[0..1]) + msgx:+GameGFX.large.TextWidth(msg[0..1]) + msg=msg[1..]+msg[0..1] + EndIf + End Method +End Type + +Type TFadeScreen + Field a:Double + Field ai:Double + + Function Create:TFadeScreen(a:Double, ai:Double) + Local o:TFadeScreen=New TFadeScreen + o.a=a + o.ai=ai + Return o + End Function + + Function FadeOut:TFadeScreen() + Return Create(0,0.05) + End Function + + Function FadeIn:TFadeScreen() + Return Create(1,-0.05) + End Function + + Function DoFadeOut() + Local fade:TFadeScreen=TFadeScreen.FadeOut() + Local pm:TPixmap=GrabPixmap(0,0,GraphicsWidth(),GraphicsHeight()) + + While fade.Fade() + Cls + DrawPixmap(pm,0,0) + fade.Draw() + Flip + Wend + End Function + + Method Fade:Int() + a:+ai + Return a>0 And a<1 + End Method + + Method Draw() + Local r:Int,g:Int,b:Int + Local oa:Double=GetAlpha() + GetColor(r,g,b) + SetAlpha(a) + SetColor(0,0,0) + DrawRect(0,0,GraphicsWidth(),GraphicsHeight()) + SetColor(r,g,b) + SetAlpha(oa) + End Method +End Type + +Type TGameBackdropStar + Field x:Double + Field y:Double + Field dy:Double + Field r:Int + Field g:Int + Field b:Int + Field frame:Int + Field cnt:Int + + Method New() + x=Rnd(0,GraphicsWidth()) + y=Rnd(0,GraphicsHeight()) + dy=Rnd(0.1,2) + r=Rand(128,255) + g=Rand(128,255) + b=Rand(128,255) + frame=Rand(0,5) + cnt=5 + End Method + + Method Draw(anim:Int) + If anim + frame=(frame+1) Mod 6 + EndIf + + y:+dy + If y>GraphicsHeight()+8 + y=-8 + EndIf + SetColor(r,g,b) + DrawImage(GameGFX.bdropstar,x,y,frame) + End Method +End Type + + +Type TGameBackdrop + Field num:Int + Field star:TGameBackdropStar[] + Field cnt:Int + + Method New() + num=100 + star=New TGameBackdropStar[num] + cnt=5 + + For Local f:Int=0 Until num + star[f]=New TGameBackdropStar + Next + End Method + + Method Draw() + For Local f:Int=0 Until num + star[f].Draw(cnt=0) + Next + cnt:-1 + If cnt=-1 + cnt=5 + EndIf + End Method +End Type + + +Type Number + Function Format:String(num:Int) + Local c:Int=0 + Local ret:String="" + Local a:String=String.FromInt(num) + + For Local f:Int=a.length-1 To 0 Step -1 + If ret.length And (c Mod 3)=0 + ret=","+ret + EndIf + ret=a[f..f+1]+ret + c:+1 + Next + Return ret + End Function +End Type -- cgit v1.2.3