Computer Science Canada [Tutorial] 2D Tile based games |
Author: | CodeMonkey2000 [ Wed Jun 13, 2007 4:13 pm ] | ||||||||
Post subject: | [Tutorial] 2D Tile based games | ||||||||
2D Tile Based Games
Before going into the tutorial, you will need to be fairly experienced with arrays (2d, flexible etc), function and procedures. How tile based games work Basically you have a text map saved in grid format. E.g. like: 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 Imagine that the screen is broken into blocks, 7 across and 3 down. Now imagine that each number in the text map represents a 10x10 tile/block on the screen. 1 means red tiles and 0 means black tiles. The position of the numbers is important, as that is going to be where the tiles are drawn. The top row in the text grid represents the top row which will be drawn on our screen (in this case the entire top row will be red, since the entire top row is 1). In the text map if I asked you what is at grid (1,3 ) you would say 1. So a red tile needs to be draw at grid 1,3 on our runtime screen. In short, the text map above should translate on screen into: *removed* Creating and drawing a map. First off let’s assume that our map is going to be 15 by 15 tiles. So our text file will have 15 numbers going across and 15 numbers going down. Now, let’s assume that each tile takes up 10 by 10 pixels. The number 1 still represents red tiles and the number 0 still represents black tiles. Here is a text file I made, save it as map.txt on your desktop: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Now we need a 2d array which will store the numbers from the text file. The array size should be as follows: 0..14, 0..14. You will see why I started the array at 0 rather than 1 when we draw the map. We want the way we call our array to be the same as how we call a coordinate in the text grid (for collision purposes). Array (0,0) will store the number at the bottom left corner, array (0,1) will store the number right above it, array(1,1) will store the number which is to the right of the previous number, array (14,14) is the top right tile (which will be a red tile)…etc. So if I look at array (10,1) I am looking at a black tile. Now we need a way of storing the number from our text file into our array. Well, first we will need to open the text file. The way we get the information is simple: for every y and for every x in the array get the number. Drawing the map will have a similar for structure; for every y and for every x in the array, if the number is 1 draw a red box at x*10,y*10 (since each tile is 10 by 10 as stated above) or else draw a black box x*10,y*10 (We started the array at 0 because 1*10 is 10, so the whole map would be off 10 pixels). Here is some code which will draw our map (save this to where you save the text file above):
If you are observant you will notice that the displayed map is upside down. Why? Well when turing reads from a file, it starts at the top line and goes to the bottom. When we read our file we assume that the first line is the bottom and goes up. We should be starting our y at the top and work our way down. So we should be doing this:
Collision detection. Finally we are into collision! First off, let’s make a moveable piece (which will be our player) and make a redraw procedure:
Collision is very easy. All we need to do is check weather or not the tile in front of us is open or not. Let all the black tiles be walk able, and red tiles are walls. So if the tile in front of the player is 1 (a red tile) we shouldn’t be able to move there. How are we going to do that? Well if ‘w’ is pressed check the tile above the player. If Array(px,py+1) = 0 then we can move. Now just do it for all keys. We get the code:
Whoa that was easy!!! And the beauty is that we can make the map larger, and all we need to change in the main program is the size of the array, and how many x’s and y’s there are (i.e. in the for loops in which we read the text file and in the for loops in which we re draw the map). But we have one small problem, this method assumes we go 10 pixels each step (ie. 1 tile a step). What if I want to go less pixels each steps so I get a smoother game play? Well I’ll cover that in the lesson after the next ![]() Next: Making a map editor and introducing a new method of detecting which tile you are in. |
Author: | LaZ3R [ Wed Jun 13, 2007 4:53 pm ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
Excellent Tutorial. Simple to understand (If you understand arrays already that is ![]() I haven't bothered trying to make a 2D Tile based game but I guess that's one of the small amount of games I can still try to make. I'm working on a slime soccer game in turing (Circular hit detection is what I'm into now ![]() Good job on this turotial. ![]() |
Author: | SNIPERDUDE [ Thu Jun 14, 2007 9:11 am ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
Yes, it was a great tutorial - simple and easy to understand. I have done 2D mapping games before (although with more advanced collision detection), but now I am into 2D isometric mapping. I have most of it working, I just want to remove some of the lag and fix some other problems (knowing which tile the mouse is on and placing objects accordingly). I hope to get enough of it working soon so I can post some of it ![]() |
Author: | DifinityRJ [ Thu Jun 14, 2007 9:41 am ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
Awesome Tutorial, thanks codemonkey! ![]() |
Author: | CodeMonkey2000 [ Thu Jun 14, 2007 7:37 pm ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
Thanks for the comments. I'm glad everyone found it easy to understand. I hope I didn't sound too redundant though... Anyway I plan to add more after exams. |
Author: | Dan [ Thu Jun 14, 2007 7:58 pm ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
Not a bad tutorial at all. This is a simple version of how alot of old 2d rpgs where made. There is alot that could be added on to this idea like how to add more propterys to a title, and making it so the world (titles move) rather then the char, so you get scorling type effect and do not have to reload the map so much. You could also add more info on how to load the titles from a image rather then just boxs. Overall tho it is a very good intro to the tile system, and is alot clearer then the current posts we have on it. + 100 bits |
Author: | CodeMonkey2000 [ Mon Jul 02, 2007 2:54 pm ] | ||||||||||||
Post subject: | Re: [Tutorial] 2D Tile based games | ||||||||||||
Changing the map size without hassle. The current way of drawing our map isn’t flexible. We can’t make the map bigger or smaller without changing the code. One possible solution to this is to use a 2 dimensional flexible array. The problem is that turing doesn’t support 2d flexible arrays. Now what? Well we could store all the information from a 2d array into a single dimensional flexible array, after all a 2d array is just another way of organizing information. (Note that the size of the array must be totalX’s times totallY’s. So if our grid was 15 by 15, our array should have 225 elements. We also we need to know the totalX’s and totallY’s beforehand). For simplicities sake, the way we will read our text file exactly how we did before, only instead of doing
In our text file we need to include the totalX’s and totalY’s, so it should be: 15 15 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Next we need to enclose the subscripts for the 2d array with Array(), and change the values in our for loop structure. Here’s what our new code looks like:
Scrolling. Yeah we are in to scrolling! There are many methods of doing this, but the one I’m going to look at is the simplest one. Save this map as map.txt: 30 30 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 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 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Let’s set the boundaries of where we should scroll. If the player’s x is more than (or less than) maxx div 2 move the map left/right depending on the direction. Similarly if the player’s y is more than (or less than) maxy div 2 move the map up/down depending on the direction the player is moving. Let’s make 2 counters that keep track of how much the map has moved (x and y displacements). This number will increase/decrease (depending on the direction that the has player moved in) and will be added to the x and y’s of both the player and tiles when we draw them. Code:
This works great, but the map should snap back to the screen when it goes off screen. What we want to happen is: If the displacementX plus the location (relative to our screen) of the very last X tile is less than maxx then the displacementX should equal maxx - totalX * 10. Or else if the displacementX plus the location (relative to our screen) of the very first X tile is more than 0 then the displacementX should equal 0 - 0 *10. And we repeat the same thing for displacementY. Code:
Editing a map. To edit a map we could change the text in the text map. But that is too tedious. Why not make program that can enable us to edit the map with ease? First we should give the user choice to create a new map, or to load an old one. If the user chooses to start a new map we should ask for the dimensions of the map and then set all the tiles to 0 (so we don’t get any “variable has to value error”). If they choose to load, we should load the map how we normally do. We can copy and paste a bunch of things from the main game onto our map editor (eg. The redraw procedure). Now if the user left clicks we should place a red tile in the tile the mouse is on (tiles in Array(mouseX, mouseY) now equals 1). If the user right clicks place a black tile in the tile the mouse is on on (tiles in Array(mouseX, mouseY) now equals 0). We can figure out what tile the mouse is on with the formula: mx div sizeOfTile (which is 10), my div sizeOfTile (which is 10). This method of detecting what tile we are on can be used for collision. It is very accurate but it can be slow. There is a trick to using it though. (Note: if we know what tile we are on, but want to find out its position on screen we do: x*10 and y*10). Moving along, if the user presses ‘q’ we should quit and save. The format to save is exactly the same as how we load, but we replace get with put. Code [Note: I added the ability to tell weather or not the mouse is within the grid. Don’t let it confuse you.]:
Now we can just start playing in the new map right away, and not worry about changing the main code. If you open the text file you will see that you now have a number per line. We don’t need to worry about organizing the text file any more. Next: I will show you how to add property to tiles, how to only draw the tiles that are on screen, change tiles during game play, how to use pictures rather than the Draw.Box procedure, and finally add enemies. I will probably use pacman as an example as it’s the simplest to understand. |
Author: | skaarj [ Sun Jul 08, 2007 10:00 am ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
Hi, I'm writing a RPG game (C++/OpenGL/OpenAL) and this map editor would be very useful, can i find binary for this tutorial? somewhere. |
Author: | CodeMonkey2000 [ Sun Jul 08, 2007 10:36 am ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
You can't find binaries for turing. If you understand the logic you probably could program your own map editor. Oh and how experienced are you with openGL? If you are new, then SDL is probably a better alternative. It's simple (hence the name Simple Direct-Media Layer). I found openGl to be very confusing and frustrating. |
Author: | skaarj [ Sun Jul 08, 2007 11:19 am ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
Im not new in OpenGL, just look at this: http://img412.imageshack.us/my.php?image=screenav2.png I'll try to write map editor. |
Author: | Sandwich [ Mon Jun 16, 2008 9:30 pm ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
Thank you very much for this tutorial. |
Author: | Aziz [ Tue Jun 17, 2008 7:43 am ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
CodeMonkey, I suggest you pic a better image host next time. I didn't know that map would translate into jailbait. |
Author: | CodeMonkey2000 [ Tue Jun 17, 2008 11:02 pm ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
Wow I just noticed that. |
Author: | evildaddy911 [ Fri Jan 06, 2012 3:52 pm ] | ||
Post subject: | Re: [Tutorial] 2D Tile based games | ||
it doesnt seem to be working for me, it highlights "get" and says "invalid integer input"... whats wrong?
|
Author: | mirhagk [ Fri Jan 06, 2012 3:56 pm ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
whatever it's getting isn't a integer (or possibly it's too large) it means your file is formatted incorrectly. |
Author: | evildaddy911 [ Fri Jan 06, 2012 4:03 pm ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
do i need to put spaces between the tiles? |
Author: | mirhagk [ Fri Jan 06, 2012 4:35 pm ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
hit the space bar? You could write a program to do it, but without experience it would take you longer than just doing it manually. |
Author: | Dreadnought [ Fri Jan 06, 2012 9:41 pm ] | ||
Post subject: | Re: [Tutorial] 2D Tile based games | ||
Alternately you can read in one character at a time and simply convert each one to an integer using ord() - 48 (since ord('0') = 48). It might look something like this.
Note that this does not reverse the rows when writing to the array. Also, if you get weird - integers then you're likely reading in the newline character ('\n' = chr(10)). |
Author: | evildaddy911 [ Sat Jan 07, 2012 10:45 am ] | ||
Post subject: | Re: [Tutorial] 2D Tile based games | ||
couldn't you just
|
Author: | Dreadnought [ Sat Jan 07, 2012 4:53 pm ] |
Post subject: | Re: [Tutorial] 2D Tile based games |
You could, and it essentially no different from the code I posted, except it seems wasteful. You declare 400 strings and use 1 out of the 255 characters for each. Also, you read the next character into a different string each time, but you never use that string anyways. It's the right idea, but you're declaring 101999 characters that you don't need. |
Author: | mirhagk [ Sat Jan 07, 2012 6:26 pm ] |
Post subject: | RE:[Tutorial] 2D Tile based games |
How about a comprimise. Read it into a temporary string variable (getting rid of the array of strings) and then use strint. |