DBPro Newcomers / [Tutorial] Let's make a tower defense clone! |
| Author | Message | ||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
![]() I've actually finished the tutorial! I decided to write them in a pdf file that you can download from here. Included in the file is all of the media required and the directory setup too, just unrar the package and open up the pdf. NOTE: Ignore the parts of the tutorial requesting you to download media files as these are included in this full package. Hope you all enjoy it! Please feel free to post comments or suggestions. I'll be adding updates in the future with new features for the game. If you'd like to download the entire game and try it out before you read the tutorial click here. |
||
| Back to top |
|||
|
indi
User Joined: Mon Aug 26th 2002 Location: Earth, Brisbane, Australia |
|
||
| Back to top |
|||
|
MartinS
User ![]() Joined: Thu Dec 15th 2005 Location: Rochester, NY |
Good job. It was an easy read - nicely written. Finally, some A*! G2L Coming soon... |
||
| Back to top |
|||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
Thanks, I know it's a bit wordy, but I'm trying to keep the diction as comfortable as possible. I'm updating constantly and hoping some people find this useful |
||
| Back to top |
|||
|
Kieran
User ![]() Joined: Sun Aug 6th 2006 Location: Hamilton, New Zealand |
|
||
| Back to top |
|||
|
Senkan
User ![]() Joined: Wed Jun 7th 2006 Location: Somewhere in the frozen Finland. |
Very nice tutorial indeed! The only problem that might occur is in SaveMap function when program asks permission to overwrite file and player types y -letter with Caps Lock on. The program defines that as no answer and doesn't overwrite that file. The solution is to change line IF s$ = "y" to IF LOWER$(s$) = "y" so the program changes the letter typed into lowercase. Hope this helps. "Whatever that was, I don't care." -Someone from FarCry |
||
| Back to top |
|||
|
Code Dragon
User Joined: Mon Aug 21st 2006 Location: Everywhere |
Great job! I haven't gotten through the whole tutorial yet, but I have some suggestions. EDIT: + Code Snippet with + Code Snippet and then change the else to and endif and delete the endif at the bottom of the function Keep up the good work! And I agree with Games 2 Live, finally some A* pathfinding! You never really know a person until you look at their google autocomplete entries. |
||
| Back to top |
|||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
Thanks for checking the tutorial out. I'll definitely add the LOWER$() command to the map editor. I recently found a bug where the map file size must be an even number, otherwise the tile placement doesn't work correctly. How can I go about checking if a number is even? Code dragon, thank you for the suggestions, I'll be certain to add them. I know, I'm bad about using constants, but I'll edit the code and start using some constants where applicable. Concerning the select command, you are absolutely right. I completely forgot about this, yes, it will be very handy instead of using all those IF statements. I hadn't done any programming in a long time, so about a week ago I decided to get back into it and I made this game while forgetting some very useful commands it appears. By the way, I'm sorry the updates are slow, I'm rewriting the game as I write the tutorial. There are a lot of problems with my completed game that I'm hoping to fix. I agree it would be helpful to explain and use the DEC and INC commands. By the way, is this simple enough to follow? I'm trying not to assume too much of anyone using this tutorial but I'm also trying to explain what is going on, I hope the code comments are helpful. If not, please inform me and I'll be more diligent in explaining the code. |
||
| Back to top |
|||
|
Google Ad
AdBot Joined: Aug 26th 2002 Location: Everywhere |
|||
| Back to top |
|||
|
Code Dragon
User Joined: Mon Aug 21st 2006 Location: Everywhere |
Quote: "How can I go about checking if a number is even?"
The mod command should help, it divides two numbers and returns the remainder. So x mod 2 = 0 will be true when x is even, false when odd. I think tutorial is pretty simple, you explain the commands in depth and tell why the code works. You never really know a person until you look at their google autocomplete entries. |
||
| Back to top |
|||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
Thanks, Code Dragon, I'll certainly be adding that. For now, if anyone is actually doing this tutorial, just remember to make your maps with even coordinates. Otherwise there'll be some serious issues. Also, with every post edit, I'm making sure to update the source code in the link at the top of the page if you ever want to jump on board without going through everything. If the link isn't working, be sure to inform me and I'll fix it straight away. I'm really enjoying rewriting my engine, I missed a lot of important features in Tower Defense my first time through, this time, I'm keeping that in mind. Also, the code seems much cleaner and I think it will turn out a lot better than before. |
||
| Back to top |
|||
|
Roxas
User Joined: Fri Nov 11th 2005 Location: http://forum.thegamecreators.com |
Wow! This tutorial is really good indeed. Must show it to my friend [B] - LINKIN PARK - [/B] ![]() ![]() |
||
| Back to top |
|||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
Tutorial Continued Update: Changed the tile textures to make it easier to see the edges of individual tiles Whoops, we mustn't forget to add our UpdateMouse() function to our game loop. Add this function just above the call to the ShowDebugInfo() function in our main game loop. Ok, it's time we start working on our critter logic (pathfinding, spawning, etc). When we created our map, we made sure to add a single spawn tile and a single finish tile. For our critter logic, we're going to need to know the location of these tiles. Let's add four more members to our Map type to hold these values. Going back to our Map TYPE, add the following four members. + Code Snippet Ok, now we will need to fill these members with the correct data. Where's the best place to do this? How about the CreateMap() function. Let's hop in there and see what we can do. It appears that we have a loop for texturing every tile in our matrix, this would be the perfect place to check for our spawn point and our goal point. Let's add this code to our CreateMap() function just below the SET MATRIX TILE command. + Code Snippet Remember, this code must be inside our FOR loop. All this does is check if the current tile is a 4 (spawn) tile or a 5 (goal) tile and then stores the current x and y values of our FOR loop into our Map members. Ok, to confirm that this works, let's add these four lines of code to our ShowDebugInfo() function in our Main.dba source file. + Code Snippet Double check the coordinates with your MouseTileX and MouseTileZ variables to ensure we did everything correctly. Did it work? |
||
| Back to top |
|||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
Update: Added pathfinding! Ok, I'm a little bummed out cause I just added a huge amount of tutorial as an edit to my last post but it completely lost it First, before we get any further into our pathfinding, we need to download an A* library. Go to this link. Scroll down a bit and download the zip file. Extract the zip file and copy the MapAndSearch.dba file to your project directory. Include this file with your project. Now for an important lesson for any coder. Do not rewrite what has already been written. As long as you can find something that is efficient and suits your purpose there is no other reason to write what has been written. Unless you just want to learn. I'd love to write a tutorial on how to do pathfinding but that would have to be a tutorial all on its own. For now, we're making a game and IanM has supplied the DarkBasic community with this little gem. A* pathfinding is type of pathfinding that is used in all sorts of RTS games. Please google it or search these forums for more information, but in basics, it creates a tree of possible routes and, based on a simple point system, finds the least costly route to get to the destination. Ok, now let me show you all of the functions we will be adding to our Critter.dba file. Here's they are. Add these to your Critter.dba source file. + Code Snippet Excuse me posting it like this but I don't have time right now to write it how I had it earlier. I'm going to go through each of the functions and explain what they do. First, PrepareCritters() simply loads and creates the physical critter object. Also, it clones this object as many times as we have MaxCritters set to. You'll notice immediately a jump in loading time for our game, that is because loading and clone objects requires some time and memory. Next we have our SpawnCritter() function. This is very important as it positions and actives a fresh critter at the spawn point. Go back to your UpdateSpawnList() function and uncomment the SpawnCritter() line now that we have it written. Moving on we get to our UpdateCritters() function. This will be called every game loop and updates the positions and pathfinding of each active critter (notice the FOR loop searching for 1 at each (i,0) element). Also important to notice is that we will only be updating our path for each critter when the critter reaches its destination. This will cut down on processor overhead from the pathfinding routines, plus, it's just not necessary to be constantly updating paths. Our UpdateCritterPath() function is where the real pathfinding magic happens. Look through the comments for explanation on what is going on. Then we have the UpdateCritterMove() function. The code should be easy to understand, read the comments. Essentially we are just adjusting the critter's position based on the difference between it and the target position. The distance that it moves is based on the speed member. The two final functions simply swap data between the type we created and the array storing the critters. You'll notice these are called in our UpdateCritters() function just before any logic is done and then after. That way we can easily manipulate data and then throw it back into our master critter array to store it. Fairly simple. Ok, let's step back into our Main.dba file to adjust some things and add these new functions to our game loop. First, we added a new member to our Critter type. Go to the critter type and add the following line to it. + Code Snippet This will keep track of the critter's ability to move. Now replace your current Game Loop Preparation heading and game loop with the following code. + Code Snippet We are calling our PrepareCritters() function to load our critter objects and added 2 critters to our queue. Then we are setting up our pathfinding map. And finally we add the update calls to the game loop. Now we are doing plenty of calculations, but our game loop looks nice and tidy. Go ahead and run it, you should see two little critters circling about your map, avoiding the walls (grey tiles) and heading for the goal point. Once they get to the goal point they will return to the spawn and do it all over again. We'll add some logic later to deal with this and simple destroy the critter when they reach the end. Want to make it even more crazy? On your AppendToSpawnList() function, make it spawn more critters with a shorter interval. See how easy it is to adjust settings like these? Eventually this will be controlled by the map file, but, for now, we'll do it manually. If your code doesn't compile, please check the top link and download the full source code. If you can find any errors in my tutorial, please tell me and I'll fix them as soon as possible. I feel I may be leaving some important code out after messing up my last post. |
||
| Back to top |
|||
|
Darth Vader
User ![]() Joined: Tue May 10th 2005 Location: Adelaide SA, I am the only DB user here! |
Hey Prancer. This tutorial looks really great and if it's got A* Pathfinding then that's even better! But since the computer I use for internet is the family computer and not actually my development PC it would make it so much easier of this was a .doc file! Is it possible to put it all in a .zip or .rar? Thanks! ![]() |
||
| Back to top |
|||
|
Sixty Squares
User Joined: Wed Jun 7th 2006 Location: Somewhere |
|
||
| Back to top |
|||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
Tutorial Continued Before I continue, I'll be sure to alter my last update to describe every function independently, I just ran out of time. If you are caught up on the tutorial, hopefully you've noticed that the little critters go to the goal point only to turn around and head back to the spawn in an annoying loop. Our game isn't going to allow such silliness. Any time a critter manages to reach the goal point, the player needs to lose a life. After the player loses all of his lives, then the game is over. So, let's add a player type to our game. Going into our Main.dba source file, add the following underneath your map TYPE. + Code Snippet Great, now we need to create an object of this type. Underneath your Create our Types heading, add the following line. + Code Snippet Now we have our new object. It's time to set its default values. Alter the "Set our default map name (for debugging)" heading to this: + Code Snippet Now we've given the player ten lives to deal with. Of course, this will be controlled by the map editor during the map creation process, but right now we're working with getting some game logic under our belts before moving on to details. So, we have our critters happily frolicking about our map in circles between the goal point and the spawn point. Let's add some code to handle what happens when the critter reaches the goal tile. First, jump to the CritterUpdateMove() function in our Critter.dba file. Add the following code to the bottom of this function. + Code Snippet This should be clear as to what is happening. If the critter happens to be on the goal tile, we'll take away one life and destroy that critter. Of course, we still need to add our DestroyCritter() function. Let's do this now. Add the following code to your Critter.dba file. + Code Snippet Again, this is a very small function for the time being, but it serves its purpose. All we have to do to get rid of a critter is simply change the Critter.Alive member variable to 0 and hide the actual object. If you run your code now, you should see the critters disappearing when they reach the goal. Also, using the PICK SCREEN() function, you can see that our critter spawn list is indeed working. After the critter is destroyed at the goal point, its object is reused for the next spawn. Updates will be added here, soon |
||
| Back to top |
|||
|
Prancer
User Joined: Sun Feb 6th 2005 Location: Idaho, US |
Sorry there hasn't been an update in a while guys, it has been a busy summer. Darth Vader - I created a .doc file and included it with the current build of the game and the media. I'll be sure to update that file as often as possible. You can grab it here. Keep checking back for more updates! |
||
| Back to top |
|||
Sorry, but it has been so long since anyone replied to this Thread that it has been automatically locked.
You may read it but not reply.
You may read it but not reply.
Forum Search
Enter a word or phrase to search our Forum for:
|
|




Coming soon...







