diff options
author | Ian C <ianc@noddybox.co.uk> | 2006-05-27 23:24:02 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2006-05-27 23:24:02 +0000 |
commit | 26c98ba56e72beaf8a99eafbedd2b0c64ac13954 (patch) | |
tree | 6460c30f185bfdf0647055a9a32af111b8f87894 | |
parent | 0129dc56ba73e43f148b779d9ff549f286e66f1d (diff) |
-rw-r--r-- | GFX/small.bmf | bin | 9888 -> 24544 bytes | |||
-rw-r--r-- | HELP/help.txt | 162 | ||||
-rw-r--r-- | game.bmx | 676 | ||||
-rw-r--r-- | gametypes.bmx | 1937 | ||||
-rw-r--r-- | hardwire.bmx | 770 | ||||
-rw-r--r-- | help.bmx | 598 | ||||
-rw-r--r-- | particle.bmx | 652 | ||||
-rw-r--r-- | sounds.bmx | 124 | ||||
-rw-r--r-- | types.bmx | 886 |
9 files changed, 2973 insertions, 2832 deletions
diff --git a/GFX/small.bmf b/GFX/small.bmf Binary files differindex 16d8db4..b2f51f5 100644 --- a/GFX/small.bmf +++ b/GFX/small.bmf 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. + + +* * * * * * * * * * * * * + @@ -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 y<Pit.HEIGHT-1
- Local t:Int=gm.map[x,y+1].t
-
- For Local px:Int=0 Until Pit.WIDTH
- For Local py:Int=0 Until Pit.HEIGHT
- If gm.map[px,py] And gm.map[px,py].t=t
- l.Add(px,py,gm.map[px,py])
- EndIf
- Next
- Next
- EndIf
-
- If l.Count()=0
- TextParticles.Big("WHAT A WASTE!",255,0,0)
- Else
- TextParticles.Big("SMART BOMB!",255,255,0)
- gm.path.AddLast(l)
- EndIf
-
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
-
- Return False
- End Method
-End Type
-
-Type TPiece_SpecialTwister Extends TSpecial
- Field rot:Int
- Field rotd:Int
-
- Method Init()
- rot=0
- rotd=0
- special_pulse=True
- map[0,0]=TWire.Create([TWire.SPECIAL_TWISTER])
- offx=[0,0,0,0]
- offy=[0,0,0,0]
- End Method
-
- Method DoSpecial:Int(gm:TGameMap)
- Draw()
-
- If gm.path.Count()
- Return True
- EndIf
-
- If rotd=0
- rotd=60
- rot:+1
- If rot=5
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
- Return False
- EndIf
- TextParticles.Big("TWIST!")
- Else
- rotd:-1
- Return True
- EndIf
-
- For Local px:Int=0 Until Pit.WIDTH
- For Local py:Int=0 Until Pit.HEIGHT
- If gm.map[px,py]
- gm.map[px,py].RotateRight()
- Particles.AddDust(Pit.X(px)+16,Pit.Y(py)+32)
- EndIf
- Next
- Next
-
- Sound.Click()
-
- If Not gm.CheckWires()
- gm.Flatten()
- gm.CheckWires()
- EndIf
-
- Return True
- End Method
-End Type
-
-Type TPiece_SpecialNuke Extends TSpecial
- Method Init()
- special_pulse=True
- map[0,0]=TWire.Create([TWire.SPECIAL_NUKE])
- offx=[0,0,0,0]
- offy=[0,0,0,0]
- End Method
-
- Method AddToList(gm:TGameMap, l:TWireList, t:Int)
- For Local px:Int=0 Until Pit.WIDTH
- For Local py:Int=0 Until Pit.HEIGHT
- If gm.map[px,py] And gm.map[px,py].t=t
- l.Add(px,py,gm.map[px,py])
- EndIf
- Next
- Next
- End Method
-
- Method DoSpecial:Int(gm:TGameMap)
- Draw()
-
- Local l:TWireList=New TWireList
-
- If y<Pit.HEIGHT-1 And gm.map[x,y+1]
- AddToList(gm,l,gm.map[x,y+1].t)
- EndIf
-
- If x>0 And gm.map[x-1,y]
- AddToList(gm,l,gm.map[x-1,y].t)
- EndIf
-
- If x<Pit.WIDTH-1 And gm.map[x+1,y]
- AddToList(gm,l,gm.map[x+1,y].t)
- EndIf
-
- If l.Count()=0
- TextParticles.Big("WHAT A WASTE!",255,0,0)
- Else
- TextParticles.Big("SMART NUKE!",255,255,0)
- gm.path.AddLast(l)
- EndIf
-
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
-
- Return False
- End Method
-End Type
-
-Type TPiece_SpecialCross Extends TSpecial
-
- Method Init()
- special_pulse=True
- pong=True
- map[0,0]=TWire.Create([TWire.SPECIAL_CROSS])
- offx=[0,0,0,0]
- offy=[0,0,0,0]
- End Method
-
- Method DoSpecial:Int(gm:TGameMap)
- Draw()
-
- TextParticles.Big("SUPER CROSS!",255,255,0)
-
- For Local px:Int=x+1 Until Pit.WIDTH
- If gm.map[px,y]
- gm.map[px,y].t=TWire.CROSS
- Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32)
- EndIf
- Next
-
- For Local px:Int=0 Until x
- If gm.map[px,y]
- gm.map[px,y].t=TWire.CROSS
- Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32)
- EndIf
- Next
-
- For Local py:Int=y+1 Until Pit.HEIGHT
- If gm.map[x,py]
- gm.map[x,py].t=TWire.CROSS
- Particles.AddDust(Pit.X(x)+16,Pit.Y(py)+32)
- EndIf
- Next
-
- If Not gm.CheckWires()
- gm.Flatten()
- gm.CheckWires()
- EndIf
-
- ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y))
-
- Return False
- 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=Min(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
-
- Method Count:Int()
- Return list.Count()
- 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 cx:Int
- Field cy:Int
- Field path:TList
- Field special:TSpecial
-
- Method New()
- trode_col=0
- trode_coli=1
- overflow=False
- path=CreateList()
- special=Null
- End Method
-
- Method BlockInteract:Int()
- Return overflow Or path.Count() Or special
- 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 And dir=TWire.DIR_RIGHT
- Return True
- EndIf
-
- Return FindLoop(l,ox,oy,x,y,dir)
- End Method
-
- Method CheckWires:Int()
- Local loop:Int=False
- Local wire:Int=False
-
- 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)
- wire=True
- 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)
- wire=True
- 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_RIGHT)
- path.AddLast(l)
- loop=True
- EndIf
- End Select
- EndIf
- Next
- Next
-
- If loop And wire
- TextParticles.Big("LOOP AND WIRE",255,0,255)
- ElseIf loop
- TextParticles.Big("LOOP",255,0,255)
- ElseIf wire
- TextParticles.Big("WIRE",255,0,255)
- EndIf
-
- Return loop Or wire
- End Method
-
- Method SetSpecial(s:TSpecial)
- special=s
- End Method
-
- Method DropColumn(x:Int, y:Int)
- While y>0
- 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 y<Pit.HEIGHT-1 + Local t:Int=gm.map[x,y+1].t + + For Local px:Int=0 Until Pit.WIDTH + For Local py:Int=0 Until Pit.HEIGHT + If gm.map[px,py] And gm.map[px,py].t=t + l.Add(px,py,gm.map[px,py]) + EndIf + Next + Next + EndIf + + If l.Count()=0 + TextParticles.Big("WHAT A WASTE!",255,0,0) + Else + TextParticles.Big("SMART BOMB!",255,255,0) + gm.path.AddLast(l) + EndIf + + ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y)) + + Return False + End Method +End Type + +Type TPiece_SpecialTwister Extends TSpecial + Field rot:Int + Field rotd:Int + + Method Init() + rot=0 + rotd=0 + special_pulse=True + map[0,0]=TWire.Create([TWire.SPECIAL_TWISTER]) + offx=[0,0,0,0] + offy=[0,0,0,0] + End Method + + Method DoSpecial:Int(gm:TGameMap) + Draw() + + If gm.path.Count() + Return True + EndIf + + If rotd=0 + rotd=60 + rot:+1 + If rot=5 + ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y)) + Return False + EndIf + TextParticles.Big("TWIST!") + Else + rotd:-1 + Return True + EndIf + + For Local px:Int=0 Until Pit.WIDTH + For Local py:Int=0 Until Pit.HEIGHT + If gm.map[px,py] + gm.map[px,py].RotateRight() + Particles.AddDust(Pit.X(px)+16,Pit.Y(py)+32) + EndIf + Next + Next + + Sound.Click() + + If Not gm.CheckWires() + gm.Flatten() + gm.CheckWires() + EndIf + + Return True + End Method +End Type + +Type TPiece_SpecialNuke Extends TSpecial + Method Init() + special_pulse=True + map[0,0]=TWire.Create([TWire.SPECIAL_NUKE]) + offx=[0,0,0,0] + offy=[0,0,0,0] + End Method + + Method AddToList(gm:TGameMap, l:TWireList, t:Int) + For Local px:Int=0 Until Pit.WIDTH + For Local py:Int=0 Until Pit.HEIGHT + If gm.map[px,py] And gm.map[px,py].t=t + l.Add(px,py,gm.map[px,py]) + EndIf + Next + Next + End Method + + Method DoSpecial:Int(gm:TGameMap) + Draw() + + Local l:TWireList=New TWireList + + If y<Pit.HEIGHT-1 And gm.map[x,y+1] + AddToList(gm,l,gm.map[x,y+1].t) + EndIf + + If x>0 And gm.map[x-1,y] + AddToList(gm,l,gm.map[x-1,y].t) + EndIf + + If x<Pit.WIDTH-1 And gm.map[x+1,y] + AddToList(gm,l,gm.map[x+1,y].t) + EndIf + + If l.Count()=0 + TextParticles.Big("WHAT A WASTE!",255,0,0) + Else + TextParticles.Big("SMART NUKE!",255,255,0) + gm.path.AddLast(l) + EndIf + + ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y)) + + Return False + End Method +End Type + +Type TPiece_SpecialCross Extends TSpecial + + Method Init() + special_pulse=True + pong=True + map[0,0]=TWire.Create([TWire.SPECIAL_CROSS]) + offx=[0,0,0,0] + offy=[0,0,0,0] + End Method + + Method DoSpecial:Int(gm:TGameMap) + Draw() + + TextParticles.Big("SUPER CROSS!",255,255,0) + + For Local px:Int=x+1 Until Pit.WIDTH + If gm.map[px,y] + gm.map[px,y].t=TWire.CROSS + Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32) + EndIf + Next + + For Local px:Int=0 Until x + If gm.map[px,y] + gm.map[px,y].t=TWire.CROSS + Particles.AddDust(Pit.X(px)+16,Pit.Y(y)+32) + EndIf + Next + + For Local py:Int=y+1 Until Pit.HEIGHT + If gm.map[x,py] + gm.map[x,py].t=TWire.CROSS + Particles.AddDust(Pit.X(x)+16,Pit.Y(py)+32) + EndIf + Next + + If Not gm.CheckWires() + gm.Flatten() + gm.CheckWires() + EndIf + + ExplosionParticles.BlowUp(Pit.X(x),Pit.Y(y)) + + Return False + 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=Min(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 + + Method Count:Int() + Return list.Count() + 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 cx:Int + Field cy:Int + Field path:TList + Field special:TSpecial + + Method New() + trode_col=0 + trode_coli=1 + overflow=False + path=CreateList() + special=Null + End Method + + Method BlockInteract:Int() + Return overflow Or path.Count() Or special + 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 And dir=TWire.DIR_RIGHT + Return True + EndIf + + Return FindLoop(l,ox,oy,x,y,dir) + End Method + + Method CheckWires:Int() + Local loop:Int=False + Local wire:Int=False + + 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) + wire=True + 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) + wire=True + 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_RIGHT) + path.AddLast(l) + loop=True + EndIf + End Select + EndIf + Next + Next + + If loop And wire + TextParticles.Big("LOOP AND WIRE",255,0,255) + ElseIf loop + TextParticles.Big("LOOP",255,0,255) + ElseIf wire + TextParticles.Big("WIRE",255,0,255) + EndIf + + Return loop Or wire + End Method + + Method SetSpecial(s:TSpecial) + special=s + End Method + + Method DropColumn(x:Int, y:Int) + While y>0 + 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 +? + @@ -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 y<BOTTOM
- Local h:THelpItem=THelpItem(i.Value())
- h.Draw(y)
- y:+h.Height()
- i=i.NextLink()
- If Not i
- i=list.FirstLink()
- EndIf
- Wend
-
- SetColor(0,0,0)
- DrawRect(0,0,GraphicsWidth(),TOP)
- DrawRect(0,BOTTOM,GraphicsWidth(),GraphicsHeight()-BOTTOM)
- For Local f:Int=0 To 8
- SetAlpha(1.0-f*0.125)
- DrawLine(0,TOP+f,GraphicsWidth(),TOP+f)
- DrawLine(0,BOTTOM-f,GraphicsWidth(),BOTTOM-f)
- Next
- SetAlpha(1)
- SetColor(128,128,128)
- DrawLine(0,TOP-1,GraphicsWidth(),TOP-1)
- DrawLine(0,TOP+1,GraphicsWidth(),TOP+1)
- DrawLine(0,BOTTOM-1,GraphicsWidth(),BOTTOM-1)
- DrawLine(0,BOTTOM+1,GraphicsWidth(),BOTTOM+1)
- SetColor(255,255,255)
- DrawLine(0,TOP,GraphicsWidth(),TOP)
- DrawLine(0,BOTTOM,GraphicsWidth(),BOTTOM)
-
- GameGFX.large.Centre("HOW TO PLAY HARDWIRE",0,255,255,0)
- GameGFX.large.Centre("USE UP/DOWN CURSORS TO SCROLL",BOTTOM+10,255,255,0)
- GameGFX.large.Centre("ESCAPE TO EXIT",BOTTOM+30,255,255,0)
- End Method
-
- Method Current:THelpItem()
- Return THelpItem(item.Value())
- End Method
-
- Method Show()
- Local done:Int=False
- Local fade:TFadeScreen=TFadeScreen.FadeIn()
-
- While Not done
- Cls
-
- Draw()
-
- If KeyDown(KEY_DOWN)
- del=Min(del+1,200)
- pos:-del/4+1
- While pos<TOP-Current().Height()
- pos:+Current().Height()
- item=item.NextLink()
- If Not item
- item=list.FirstLink()
- EndIf
- Wend
- ElseIf KeyDown(KEY_UP)
- del=Min(del+1,200)
- pos:+del/4+1
- While pos>TOP
- 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 y<BOTTOM + Local h:THelpItem=THelpItem(i.Value()) + h.Draw(y) + y:+h.Height() + i=i.NextLink() + If Not i + i=list.FirstLink() + EndIf + Wend + + SetColor(0,0,0) + DrawRect(0,0,GraphicsWidth(),TOP) + DrawRect(0,BOTTOM,GraphicsWidth(),GraphicsHeight()-BOTTOM) + For Local f:Int=0 To 8 + SetAlpha(1.0-f*0.125) + DrawLine(0,TOP+f,GraphicsWidth(),TOP+f) + DrawLine(0,BOTTOM-f,GraphicsWidth(),BOTTOM-f) + Next + SetAlpha(1) + SetColor(128,128,128) + DrawLine(0,TOP-1,GraphicsWidth(),TOP-1) + DrawLine(0,TOP+1,GraphicsWidth(),TOP+1) + DrawLine(0,BOTTOM-1,GraphicsWidth(),BOTTOM-1) + DrawLine(0,BOTTOM+1,GraphicsWidth(),BOTTOM+1) + SetColor(255,255,255) + DrawLine(0,TOP,GraphicsWidth(),TOP) + DrawLine(0,BOTTOM,GraphicsWidth(),BOTTOM) + + GameGFX.large.Centre("HOW TO PLAY HARDWIRE",0,255,255,0) + GameGFX.large.Centre("USE UP/DOWN CURSORS TO SCROLL",BOTTOM+10,255,255,0) + GameGFX.large.Centre("ESCAPE TO EXIT",BOTTOM+30,255,255,0) + End Method + + Method Current:THelpItem() + Return THelpItem(item.Value()) + End Method + + Method Show() + Local done:Int=False + Local fade:TFadeScreen=TFadeScreen.FadeIn() + + While Not done + Cls + + Draw() + + If KeyDown(KEY_DOWN) + del=Min(del+1,200) + pos:-del/4+1 + While pos<TOP-Current().Height() + pos:+Current().Height() + item=item.NextLink() + If Not item + item=list.FirstLink() + EndIf + Wend + ElseIf KeyDown(KEY_UP) + del=Min(del+1,200) + pos:+del/4+1 + While pos>TOP + 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<GraphicsWidth()+16 And y<GraphicsHeight()
- End Method
-End Type
-
-Type TExplosion
- Field x:Double
- Field y:Double
- Field dy:Double
- Field dx:Double
-
- Function Create:TExplosion(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()
- SetColor(Rand(0,255),Rand(0,255),Rand(0,255))
- Plot(x,y)
- x:+dx
- y:+dy
- dy:+0.1
- Return dx>-16 And dx<GraphicsWidth()+16 And y<GraphicsHeight()
- End Method
-End Type
-
-Type ExplosionParticles
- Global plist:TList
-
- Function Init()
- plist=CreateList()
- End Function
-
- Function Clear()
- plist.Clear()
- End Function
-
- Function BlowUp(x:Int, y:Int)
- For Local cx:Int=0 Until 32
- For Local cy:Int=0 Until 32
- plist.AddLast(TExplosion.Create(x+cx,y+cy,Rnd(-2,2),Rnd(-2,2)))
- Next
- Next
- End Function
-
- Function Draw()
- Local l:TEasyLink=TEasyLink.Create(plist)
-
- While l.Value()
- Local p:TExplosion=TExplosion(l.Value())
-
- If (p.Update())
- l.MoveNext()
- Else
- l.Remove()
- EndIf
- Wend
- End Function
-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 "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<GraphicsWidth()+16 And y<GraphicsHeight() + End Method +End Type + +Type TExplosion + Field x:Double + Field y:Double + Field dy:Double + Field dx:Double + + Function Create:TExplosion(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() + SetColor(Rand(0,255),Rand(0,255),Rand(0,255)) + Plot(x,y) + x:+dx + y:+dy + dy:+0.1 + Return dx>-16 And dx<GraphicsWidth()+16 And y<GraphicsHeight() + End Method +End Type + +Type ExplosionParticles + Global plist:TList + + Function Init() + plist=CreateList() + End Function + + Function Clear() + plist.Clear() + End Function + + Function BlowUp(x:Int, y:Int) + For Local cx:Int=0 Until 32 + For Local cy:Int=0 Until 32 + plist.AddLast(TExplosion.Create(x+cx,y+cy,Rnd(-2,2),Rnd(-2,2))) + Next + Next + End Function + + Function Draw() + Local l:TEasyLink=TEasyLink.Create(plist) + + While l.Value() + Local p:TExplosion=TExplosion(l.Value()) + + If (p.Update()) + l.MoveNext() + Else + l.Remove() + EndIf + Wend + End Function +End Type @@ -1,54 +1,70 @@ -' Hardwire
-'
-' Copyright 2005 Ian Cowburn
-'
-' $Id$
-'
-Strict
-Import brl.audio
-Import brl.freeaudioaudio
-Import brl.wavloader
-
-Incbin "SFX/pop.wav"
-Incbin "SFX/click.wav"
-Incbin "SFX/path.wav"
-
-Type Sound
- Global popsfx:TSound
- Global clicksfx:TSound
- Global pathsfx:TSound
-
- Global play_pop:Int
- Global play_click:Int
- Global play_path:Int
-
- Function Init()
- popsfx=LoadSound("incbin::SFX/pop.wav")
- clicksfx=LoadSound("incbin::SFX/click.wav")
- pathsfx=LoadSound("incbin::SFX/path.wav")
- play_pop=False
- play_click=False
- play_path=False
- End Function
-
- Function Pop()
- play_pop=True
- End Function
-
- Function Click()
- play_click=True
- End Function
-
- Function Path()
- play_path=True
- End Function
-
- Function Process()
- If play_pop Then popsfx.Play()
- If play_click Then clicksfx.Play()
- If play_path Then pathsfx.Play()
- play_pop=False
- play_click=False
- play_path=False
- End Function
-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 brl.audio +Import brl.freeaudioaudio +Import brl.wavloader + +Incbin "SFX/pop.wav" +Incbin "SFX/click.wav" +Incbin "SFX/path.wav" + +Type Sound + Global popsfx:TSound + Global clicksfx:TSound + Global pathsfx:TSound + + Global play_pop:Int + Global play_click:Int + Global play_path:Int + + Function Init() + popsfx=LoadSound("incbin::SFX/pop.wav") + clicksfx=LoadSound("incbin::SFX/click.wav") + pathsfx=LoadSound("incbin::SFX/path.wav") + play_pop=False + play_click=False + play_path=False + End Function + + Function Pop() + play_pop=True + End Function + + Function Click() + play_click=True + End Function + + Function Path() + play_path=True + End Function + + Function Process() + If play_pop Then popsfx.Play() + If play_click Then clicksfx.Play() + If play_path Then pathsfx.Play() + play_pop=False + play_click=False + play_path=False + End Function +End Type @@ -1,426 +1,460 @@ -' Hardwire
-'
-' Copyright 2005 Ian Cowburn
-'
-' $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
\ 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 |