[bmx] Tower Defense by Baystep Productions [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:38

Previous topic - Next topic

BlitzBot

Title : Tower Defense
Author : Baystep Productions
Posted : 1+ years ago

Description : So here's the simple makings of a tower defense game, I'm sure a lot can be added to make it better. But this is for the code archives, so I don't care.

The map files are composed of 2 image files, the background, and the "collision" image, which is black and white. Then the final dat file containing the image names and a series of x,y coordinates marking way points in the path.

Press SPACE to buy towers, they cost $10.
Press D to upgrade damage on selected tower.
Press R to upgrade range on selected tower.
Press F to upgrade fire rate on selected tower.
Press ENTER to deselect tower.


Code :
Code (blitzmax) Select
Strict
Import "ScriptReader.bmx"

'WRITEN BY CHRIS PIKUL
'---------------------
'FREE TO USE/PUBLIC DOMAIN
SetGraphicsDriver D3D7Max2DDriver()
Graphics 1024,768,0,60,GRAPHICS_ALPHABUFFER

Global bg_FileName$,bg_Image:TImage
Global brd_FileName$,brd_Image:TPixmap
Global map_FileName$ = "SimpleTest" '|<-------------- MAP FILE NAME! WILL LOOK IN MAPS DIRECTORY AND WILL ADD .DAT EXTENSION
Global startX%,startY%,endX%,endY%
Global starting:Point
Global ending:Point
Global money%=25,health%=25
Global sinceLastWave%,waveNumber%=1,waveCount%=1,waveMode%,waveCreated%
Global mouseMode%,mouseSel:Tower,permSel:Tower

Global tower1:TImage = LoadAnimImage("ResTower1.png",25,25,0,3) '|<-------------- YOUR TOWER IMAGE! First frame is the base, 2 is barrel, 3 is barrel firing
MidHandleImage(tower1)

Global path:TList = New TList
Type Point
Field x%,y%
Field mode%
Function Create(x%,y%,mode%=0)
Local pnt:Point = New Point
pnt.x = x%
pnt.y = y%
pnt.mode% = mode%
path.AddLast pnt
EndFunction
EndType

LoadMap()

starting:Point = Point(path.First())
ending:Point = Point(path.Last())

Global towers:TList = New TList
Type Tower
Field x%,y%
Field damage#
Field range#
Field fireRate%
Field lastFire%
Field target:Enemy
Field targetDist#
Field imageMode%
Field rot#
Function Create(setX%,setY%)
Local newTower:Tower = New Tower
newTower.x = setX%
newTower.y = setY%
newTower.fireRate%=20
newTower.damage# = 1
newTower.range# = 75
towers.AddLast newTower
EndFunction
EndType

Global wave:TList = New TList
Type Enemy
Field x#,y#
Field pointIndex%
Field nextPoint:Point
Field health#,speed#
Function Create()
Local newEnemy:Enemy = New Enemy
newEnemy.x = starting.x
newEnemy.y = starting.y - 25
newEnemy.health# = 1+(waveNumber%*0.4)
newEnemy.speed# = 0.9+(waveNumber%*0.2)
newEnemy.pointIndex% = 0
newEnemy.nextPoint:Point = starting
wave.AddLast newEnemy
EndFunction
EndType
Enemy.Create()

SetBlend ALPHABLEND
While Not KeyHit(KEY_ESCAPE)
Cls
DrawImage(bg_Image,0,0)
For Local enmy:Enemy = EachIn wave
DrawOval(enmy.x-5,enmy.y-5,10,10)
If enmy.x<enmy.nextPoint.x
If (enmy.nextPoint.x-enmy.x)<enmy.speed#
enmy.x = enmy.nextPoint.x
Else
enmy.x = enmy.x+enmy.speed#
EndIf
ElseIf enmy.x>enmy.nextPoint.x
If (enmy.x-enmy.nextPoint.x)<enmy.speed#
enmy.x = enmy.nextPoint.x
Else
enmy.x = enmy.x-enmy.speed#
EndIf
EndIf
If enmy.y<enmy.nextPoint.y
If (enmy.nextPoint.y-enmy.y)<enmy.speed#
enmy.y = enmy.nextPoint.y
Else
enmy.y = enmy.y+enmy.speed#
EndIf
ElseIf enmy.y>enmy.nextPoint.y
If (enmy.y-enmy.nextPoint.y)<enmy.speed#
enmy.y = enmy.nextPoint.y
Else
enmy.y = enmy.y-enmy.speed#
EndIf
EndIf
If enmy.x<=(enmy.nextPoint.x+enmy.speed) And enmy.x>=(enmy.nextPoint.x-enmy.speed) And enmy.y<=(enmy.nextPoint.y+enmy.speed) And enmy.y>=(enmy.nextPoint.y-enmy.speed)
enmy.pointIndex% = enmy.pointIndex%+1
If enmy.nextPoint = ending
wave.Remove enmy
waveCount = waveCount-1
health = health - 1
Else
enmy.nextPoint = Point(path.ValueAtIndex(enmy.pointIndex%))
EndIf
EndIf
If enmy.health<=0
wave.Remove enmy
money=money+1
wave.Remove enmy
waveCount% = waveCount%-1
EndIf
Next
For Local twr:Tower = EachIn towers
twr.lastFire% = twr.lastFire%+1
For Local enmy:Enemy = EachIn wave
Local dist# = Sqr((enmy.x-twr.x)^2+(enmy.y-twr.y)^2)
If twr.target
If dist#<twr.targetDist#
twr.targetDist#=dist#
twr.target = enmy
EndIf
Else
If dist#<twr.range
twr.targetDist#=dist#
twr.target=enmy
EndIf
EndIf
Next
If twr.target
twr.targetDist# = Sqr((twr.target.x-twr.x)^2+(twr.target.y-twr.y)^2)
twr.rot# = ATan2((twr.y-twr.target.y),(twr.x-twr.target.x))
If twr.lastFire%>=twr.fireRate%
twr.imageMode%=5
twr.lastFire%=0
twr.target.health = twr.target.health-twr.damage#
If twr.target.health<=0
twr.target = Null
EndIf
EndIf
If twr.targetDist#>twr.range#
twr.target = Null
EndIf
EndIf
If MouseX()>=(twr.x-10) And MouseX()<=(twr.x+10) And MouseY()>=(twr.y-10) And MouseY()<=(twr.y+10)
mouseSel = twr
ElseIf mouseSel=twr
mouseSel = Null
EndIf
DrawImage(tower1,twr.x,twr.y)
SetRotation(twr.rot#)
If twr.imageMode%>0
twr.imageMode% = twr.imageMode%-1
DrawImage(tower1,twr.x,twr.y,2)
Else
DrawImage(tower1,twr.x,twr.y,1)
EndIf
SetRotation(0)
Rem
SetAlpha(0.1)
SetColor(255,0,0)
DrawOval(twr.x-twr.range,twr.y-twr.range,twr.range*2,twr.range*2)
SetColor(255,255,255)
SetAlpha(1)
EndRem
Next
If KeyHit(KEY_SPACE) And money>=10 Then mouseMode% = 1
Select mouseMode%
Case 0
If mouseSel
SetAlpha(0.1)
SetColor(255,0,0)
DrawOval(mouseSel.x-mouseSel.range,mouseSel.y-mouseSel.range,mouseSel.range*2,mouseSel.range*2)
SetColor(255,255,255)
SetAlpha(1)
If MouseHit(1)
mouseMode%=2
permSel = mouseSel
EndIf
EndIf
Case 1 'Building crap
SetAlpha(0.1)
SetColor(255,0,0)
DrawOval(MouseX()-75,MouseY()-75,150,150)
SetColor(255,255,255)
SetAlpha(1)
If MouseHit(1)
Local pix = brd_Image.ReadPixel(MouseX(),MouseY())
Local pixRed = (pix Shr 16) & $FF
Local pixGreen = (pix Shr 8) & $FF
Local pixBlue = pix & $FF
If pixRed=0 And pixGreen=0 And pixBlue=0
tower.Create(MouseX(),MouseY())
EndIf
money=money-10
mouseMode%=0
EndIf
Case 2 'Selecting crap
DrawText("Damage: "+permSel.damage#+" upgrade cost $"+(2*Int(permSel.damage)),705,55)
DrawText("Range: "+permSel.range#+" upgrade cost $"+Int(Int(permSel.range)*0.026),705,65)
DrawText("Fire Rate: "+permSel.fireRate%+" upgrade cost $"+Int(100-(Int(permSel.fireRate%)*4.75)),705,75)
If KeyHit(KEY_D) And money>=(2*Int(permSel.damage))
money = money - (2*Int(permSel.damage))
permSel.damage# = permSel.damage#+(permSel.damage#*0.25)
EndIf
If KeyHit(KEY_R) And money>=Int(Int(permSel.range)*0.026)
money = money - Int(Int(permSel.range)/0.026)
permSel.range# = permSel.range#+(permSel.range#*0.25)
EndIf
If KeyHit(KEY_F) And money>=Int(100-(Int(permSel.fireRate%)*4.75))
money = money - Int(100-(Int(permSel.fireRate%)*4.75))
permSel.fireRate% = permSel.fireRate%-(permSel.fireRate%*0.10)
EndIf
If KeyHit(KEY_RETURN)
mouseMode% = 0
permSel = Null
FlushKeys()
FlushMouse()
EndIf
EndSelect
DrawText("Cash: $"+money,705,5)
DrawText("Health: "+health,705,15)
DrawText("Wave: #"+waveNumber+"/"+waveCount,705,25)
DrawText("Enemy: Health="+(1+(waveNumber%*0.4))+", Speed="+(0.9+(waveNumber%*0.2)),705,35)
Flip

If waveCount<=0 And waveMode=0
waveNumber = waveNumber+1
sinceLastWave=MilliSecs()
waveMode=1
EndIf
Select waveMode
Case 1
If MilliSecs()>=sinceLastWave+3000
waveMode = 2
waveCreated = 0
EndIf
Case 2
Enemy.Create()
waveCount=waveCount+1
waveCreated = waveCreated+1
sinceLastWave = MilliSecs()
waveMode = 3
Case 3
If MilliSecs()>=sinceLastWave+200
waveMode = 2
If waveCreated>=(waveNumber*2)
waveMode=0
EndIf
EndIf
EndSelect
If AppSuspended() Or KeyHit(KEY_P)
SetAlpha(0.5)
SetColor(0,0,0)
DrawRect(0,0,1024,768)
SetAlpha(1)
SetColor(255,255,255)
DrawText("[PAUSED]",500,300)
Flip
While Not KeyHit(KEY_P)
DrawText "PAUSED",0,0
Wend
FlushKeys()
FlushMouse()
EndIf
If AppTerminate()
If Confirm("Are you sure you want to quit?") Then Exit
EndIf
Wend
End

Function LoadMap()
Local file:TStream = ReadFile("Maps"+map_FileName$+".dat")
If Not file Then RuntimeError("Could not load map file!")
bg_FileName$ = file.ReadLine()
brd_FileName$ = file.ReadLine()
Local points% = file.ReadByte()
For Local temp% = 1 To points%
Local tempX% = file.ReadInt()
Local tempY% = file.ReadInt()
Local tempM% = file.ReadByte()
Point.Create(tempX%,tempY%,tempM%)
Next
CloseFile(file)
bg_Image:TImage = LoadImage("Maps"+bg_FileName$)
brd_Image:TPixmap = LoadPixmap("Maps"+brd_FileName$)
EndFunction

'WRITEN BY CHRIS PIKUL
'---------------------
'FREE TO USE/PUBLIC DOMAIN


Comments :


Baystep Productions(Posted 1+ years ago)

 A simple map editor to go with it!
Strict

Global bg_FileName$,bg_Image:TImage
Global brd_FileName$,brd_Image:TPixmap
Global map_FileName$ = "SimpleTest"
Global lastR%,lastG%,lastB%,lastX%,lastY%
Global startX%,startY%,endX%,endY%

Global cursors:TImage = LoadAnimImage("ResMapEditor_Cursors.png",25,25,0,3)
MidHandleImage(cursors)
Global curMode% = 0
Global editorMode% = 0

Global path:TList = New TList
Global vect:Waypoint
Type Waypoint
Field x,y
Field mode%
Function Create(x%,y%,mode%=0)
Local pnt:Waypoint = New Waypoint
pnt.x = x%
pnt.y = y%
pnt.mode% = mode%
path.AddLast pnt
EndFunction
EndType

Global start:Waypoint,ending:Waypoint


Local leaveLoop=False
Repeat
Print "Tower War, Map Builder Utility"
Print "=============================="
Print "[N]ew file, or [L]oad previous? ([E] to quit application)"
Select Lower(Input())
Case "n" 'New File
Print "Note: All image files should be in the Maps directory, therefor, the directory is not needed in the file name."
bg_FileName$ = Input("Background Image File>")
bg_Image:TImage = LoadImage("Maps"+bg_FileName$)
If Not bg_Image Then Print "Could not locate the image file (or unreadable format) ~q"+bg_FileName$+"~q!"
brd_FileName$ = Input("Boundry Image File>")
brd_Image:TPixmap = LoadPixmap("Maps"+brd_FileName$)
If Not brd_Image Then Print "Could not locate the image file (or unreadable format) ~q"+bg_FileName$+"~q!"
leaveLoop=True
Case "l" 'Load File
Print "Note: All map files are in the Maps directory, therefor, the directory is not needed in the file name."
map_FileName$ = Input("File name>")
LoadMap()
leaveLoop=True
Case "e"
End
Default
Print "Unrecongnized command, try again"
EndSelect
Until leaveLoop
LoadMap()

Graphics 1024,768,0
SetBlend ALPHABLEND
While Not KeyHit(KEY_ESCAPE)
Cls
If KeyHit(KEY_S)
If Not map_FileName$ Then map_FileName$=Input("Map file name>")
SaveMap()
EndIf
If KeyHit(KEY_P)
If editorMode%
editorMode% = 0
If start And ending
If start.x>start.y
start.y=0
Else
start.x=0
EndIf
If ending.x>ending.y
ending.x = 700
Else
ending.y = 700
EndIf
EndIf
Else
editorMode% = 1
EndIf
FlushKeys()
EndIf

If MouseX()<700 And MouseY()<700
Local pix% = brd_Image.ReadPixel(MouseX(),MouseY())
lastR% = (pix% Shr 16) & $FF
lastG% = (pix% Shr 8) & $FF
lastB% = pix% & $FF
EndIf

DrawImage(bg_Image,0,0)
DrawImage(cursors,MouseX(),MouseY(),curMode%)
DrawText("Mouse: "+MouseX()+","+MouseY(),705,10)
DrawText("RGB Values: "+lastR+","+lastG+","+lastB,705,20)
lastX = 0
lastY = 0
For vect:Waypoint = EachIn path
DrawImage(cursors,vect.x,vect.y,2)
If (lastX>0) Or (lastY>0)
DrawLine(lastX,lastY,vect.x,vect.y)
Else
startX% = vect.x
startY% = vect.y
start = vect
EndIf
lastX=vect.x
lastY=vect.y
Next
If vect
endX% = vect.x
endY% = vect.y
ending = vect
EndIf

Select editorMode%
Case 1
DrawText("Drawing Path...",705,30)
If lastR% = 255 And lastG% = 255 And lastB% = 255%
curMode% = 2
Else
curMode% = 1
EndIf
If (lastX>0) Or (lastY>0)
DrawLine(lastX,lastY,MouseX(),MouseY())
EndIf
If MouseHit(1) Then Waypoint.Create(MouseX(),MouseY())

Default
If lastR% = 255 And lastG% = 255 And lastB% = 255%
curMode% = 1
Else
curMode% = 0
EndIf
DrawText("Waiting...",705,30)
EndSelect
DrawText("START",startX,startY)
DrawText("END",endX,endY)

If AppSuspended() Then DrawText "PAUSED",0,0
Flip
If AppTerminate()
If Confirm("Are you sure you want to quit?") Then Exit
EndIf
Wend
End

Function SaveMap()
Local file:TStream = WriteFile("Maps"+map_FileName$+".dat")
If Not file Then RuntimeError("Could not write map file!")
file.WriteLine(bg_FileName$)
file.WriteLine(brd_FileName$)
file.WriteByte(path.Count())
For Local pnt:Waypoint = EachIn path
file.WriteInt(pnt.x%)
file.WriteInt(pnt.y%)
file.WriteByte(pnt.mode%)
Next
CloseFile(file)
EndFunction

Function LoadMap()
Local file:TStream = ReadFile("Maps"+map_FileName$+".dat")
If Not file Then RuntimeError("Could not load map file!")
bg_FileName$ = file.ReadLine()
brd_FileName$ = file.ReadLine()
Local points% = file.ReadByte()
For Local temp% = 1 To points%
Local tempX% = file.ReadInt()
Local tempY% = file.ReadInt()
Local tempM% = file.ReadByte()
Waypoint.Create(tempX%,tempY%,tempM%)
Next
CloseFile(file)
bg_Image:TImage = LoadImage("Maps"+bg_FileName$)
brd_Image:TPixmap = LoadPixmap("Maps"+brd_FileName$)
EndFunction