Tower Defence games

Blitz3D Forums/Blitz3D Beginners Area/Tower Defence games

Ok ive been playing a few tower defence games on my ipod and would like to know how easy or hard a TD game is to make.

Also what sort of routines do i need to be looking into.

Most of them use a 2D/3D grid to place the towers on the main play area.

Path finding routine for the enemy is used by most (tho Field Runners i think just uses some kind of avoidence routine).

A routine to select icons (towers) and drag 'n' drop them onto the main play area.

Upgrade / Sell routine for the towers

Thats all i can think of at the mo(my brains gone to sleep lol)

So does any body have ideas on whats needed, or maybe you have done a simple Tower Defence game yourelf and don't mind throwing up a few routines.

Thanks

Destroyer

That first question can't be answered. It depends on your skills.
It seems to me that you allready have a good idea about what you'll need to do. Best is, depending on your experience, to start off with several smaller experiments in which you focus on a single element of the game, pretty much the things you've summed up allready. Then, if you know how you want to setup each element, you can bring everything together in the final endproject.

Firstly, I would look into types (Type). I suppose the field runners could best be types, as well as the bullets and the towers. Each type could have fields, such as these:
creeps
-x/y location
-type/sort/kind
-energy
bullets:
-x/y location
-dx/dy direction
towers
-x/y location
-type/sort/kind
-range
First goal would be to write the creeps, as a Type. They should be able to rotate, and walk from the left to the right of the screen. For rotating images, look for prerendered rotation, since b3d can't rotate 2d images realtime.
If you don't want to prerender, use 3d to simulate 2d. 3d objects can rotate realtime.

Collision detection might be an issue to look into. RectsOverlap should be sufficient, since you don't need pixel-perfect collisions.
So, alter the program so that you can delete enemies with the mouse.

Next would be, create bullets. You could write a program in which you can fire bullets with and from the mouse. If a bullet hits the enemy, it should be deleted.

It would be good to use Functions to create/update/draw each element. CreateBullet, UpdateAndDrawBullets, CreateEnemy, UpdateAndDrawEnemy. This will result in a more flexible and more readable program.

For the grid, you could use an array (Dim). The array can be used to check if a certain position is allready filled with something, and you can use it to let the field runners determine their route. Best is to look at the way to store Types into arrays. That way, you can immediately access the type instance that is on a certain x,y location.

To convert from mouse coords to grid coords, divide by the tilesize:
gx = mousex / 32
gy = mousey / 32
Due to the fact that integers are truncated (rounded to below) by default, the fractional part will dissapear, leaving the tile location.
The other way around, from tile to x,y:
screenx = gx * 32
screeny = gy * 32

For determining their route, I think that each enemy takes the shortest path to the endpoint, with the least danger possible.
You could create a 2d grid (array), and use a number that determines that danger level for each location. If a tower is placed, all grid tiles that are in it's firing range should increase their danger value. The stronger to tower, the bigger the increase should be.
By using that system, if two towers are near each other, all tiles that are in their overlapping firing range will automatically have a bigger danger level that tiles that are in the firing range of only one tower.
If tiles are not in any towers firing range, their danger level is zero.
A creep can than scan each vertical colomn and look for the tiles with the lowest danger value. If you combine that with the distance that such a tile has from the creeps position in the row on the left side of the row you are checking, it should be able to decide which route it should take. It would most likely come round to calculating a few possible routes, sorting them on their danger and length, and then choosing the first one. (The shortest and least dangerous)
        0 0 0 0 1 0 0
        0 0 0 1 2 1 0
start-> 0 1 0 0 1 0 0 ->finish
        0 0 0 0 0 0 1
        0 0 0 0 0 1 2


Upgrading, selling and dragging seem to me less relevant to the gameplay than bullets/enemies/towers. Same goes for the game menu.
In that sence, I'd suggest to start off with the basics, and upgrade the game when the basic layer is solid enough to build upon. You should prob. best not attempt to create the game in a linear way, I mean, in terms of the creation process the starting point is not the game menu, and the endpoint is not the gameover screen. The creation process should in my opinion start with the simplest form of the game, with one type of tower, one type of enemy and one type of bullet. Also it is a good idea to save each subversion under a different name as you go along.

Here is an example program that might be helpful:
Graphics 800, 600, 0, 2
SetBuffer BackBuffer()

;starting pos
bx# = 400
by# = 300

Repeat

	If MouseHit(1) Then
		
		;choose new goal
		aimx# = MouseX()
		aimy# = MouseY()
		
		;calculate distance = number of steps
		dist# = Sqr((aimx - bx) ^ 2 + (aimy - by) ^ 2)
		;calculate direction it should take pro step
		dx# = (aimx# - bx#) / dist#
		dy# = (aimy# - by#) / dist#
		
	End If
	
	;if there are steps to take
	If dist# >= 1 Then
		
		;decrease number of steps
		dist# = dist# - 1
		;take step in chosen direction
		bx# = bx# + dx#
		by# = by# + dy#
	
	End If
		
	Cls	
	
	;draw green oval at (bx,by)
	Color 0, 255, 0
	Oval bx - 5, by - 5, 11, 11
	
	;draw red oval al (mousex,mousey)
	Color 255, 0, 0
	Oval MouseX() - 5, MouseY() - 5, 11, 11
	
	;draw info text
	Color 255, 255, 255
	Text 0, 0, "click left mousebutton"
	Text 0, 20, "dist = " + dist
	Flip

;esc=exit	
Until KeyHit(1)

End


Good Point Warner about the upgrading.

Ive got a few routines done(just simple tho), But like you said keep it simple to start with then build on it.

Ill keep it 2D for now using circles and rectangles for enemy and towers(just 1 of each) then try it with 3D

Thanks for taking the time to read my post and giving some good pointers.

Oh and ill take a look at your code :)

Thanks

Destroyer

for selecting towers and selling and placing etc it is best to use a combo of arrays and types but its kind of hard to explain in words so its best if you figure it out for yourself.

thats my 3 cents ;)

Thanks for the tip Nate the Great :)

I know a lil about types and arrays so will look into using them.

I also see that you are making a tower defence game. looking good so far :)

Thanks
Destroyer

I think I was kind of vague. here is what I was trying to say...

use an array to store where all of your towers are so the array might look like this

0,0,0,1,0,2,0
0,0,2,0,0,0,0
0,0,0,0,0,0,1
0,0,0,0,0,0,0
0,0,1,0,0,0,0

.. thats just a random array for the purpose of an example the 1s are one type of tower and the 2s are another type of tower..

anyway for each tower in the tower type, the x and y values where the tower existed on the array would be variables in the type.

I then have another array for the selected squares where only one square at a time could be selected

0,0,0,0,0,0,0
0,0,1,0,0,0,0
0,0,0,0,0,0,0
0,0,0,0,0,0,0
0,0,0,0,0,0,0

so now that I have thouroughly confused you with seemingly meaningless stuff here is how it all works together

the 2nd array starts out blank.. thus no towers are selected
the 1st array then stores all the towers.. here is what happens every loop

1. if the player clicks then check to see if he clicked on a tower by cycling through all the tower types
2. if the player clicked on a tower then set a var in that type to true and get that tower's x and y on the 2nd array, erase the second array and set a single square in the array where the tower is located to true thus there is never more than 1 thing selected
3. as the towers are updating every loop, check if the towers select var is true if so then check if it is true on the 2nd array.. if not then set the tower's selected status to false
4. now there will only be one tower selected at any one time!

if you dont understand then post and I will try to get some example code up soon it is really way simpler in coding.. you can also adapt this system for anything that requires the user to select one thing at a time good luck

here is some example code.. sorry it is so messy but it is simple and should be self explanitory with the above explanation. It has a bare minimum structure.

Graphics 640,480,0,2
SetBuffer BackBuffer()
SeedRnd(MilliSecs())

Type tower
	Field x,y ;x and y on an array
	Field selected; is the tower selected?
End Type

Dim tarray(8,6) ;size of the grid -1 in each dimension

For i = 1 To 7			;its up to you to make sure no two towers are on the same square
	t.tower = New tower
	t\x = Rand(0,8)
	t\y = i-1
	t\selected = 0
Next

While Not KeyDown(1)
Cls

drawgrid()	;draws the towers and the grid for example purposes
checkselection()


Flip
Wend


End


Function drawgrid()
Color 255,255,255
For x = 0 To 10
	Line x*64,0,x*64,448
Next

For y = 0 To 7
	Line 0,y*64,576,y*64
Next

clickflag = False
If MouseHit(1) Then clickflag = True


For t.tower = Each tower
	If t\selected = True Then
		Color 255,0,0
	Else
		Color 255,255,255
	EndIf
	Oval t\x*64,t\y*64,64,64
	If clickflag = True Then
		If MouseX() > t\x*64 And MouseX() < t\x*64+64 Then
			If MouseY() > t\y*64 And MouseY() < t\y*64+64 Then
				t\selected = True
				cleararray()
				tarray(t\x,t\y) = True
			EndIf
		EndIf
	EndIf
Next

End Function


Function checkselection()

For t.tower = Each tower
	If t\selected = True And tarray(t\x,t\y) = False Then
		t\selected = False
	EndIf
Next

End Function


Function cleararray()

For x = 0 To 8
	For y = 0 To 6
		tarray(x,y) = False
	Next
Next

End Function


Thanks for the example Nate ill look through it.

I also like the idea of using the 2 arrays for tower placments and checks


Thanks

Destroyer

You could always just have a path the enemies take. They will always follow that path. Maybe have two paths even, but keep the attack pattern the same. Each enemy will go exactly the same way as last time.

I haven't played a great deal of tower defense games, but the ones i have played (and enjoyed) the enemy paths were static.

It helps in the harder stages, as you can predict better and plan better.

Yes that is true Ross C

Field Runners seem to run from A-B, and only change direction if they collide with a tower.

Geo-Defence use a path to get from A-B.

Im thinking of using way-points for my enemy to follow(not sure if this is the best way).

But for now while im putting some routines together, Ill try the Field Runners method(i think its the simplest).

Thanks

Destroyer

Maybe it's an idea to try out a number of methods/models and see which one is the best.

An interesting thread, my son has played a number of tower defence games and is quite taken with them, might have a play with this myself in B3D. Nate the great's sample code looks interesting