﻿ [Tutorial] Tilemaps in Axe Basic
21 May, 2013, 11:46:26
 OmnomIRC You must Register, be logged in and have at least 40 posts to use this shout-box! If it still doesn't show up afterward, it might be that OmnomIRC is disabled for your group or under maintenance.Note: You can also use an IRC client like mIRC, X-Chat or Mibbit to connect to an EFnet server and #omnimaga.

 Pages: [1] 2 3 ... 7   Go Down
 Author Topic: [Tutorial] Tilemaps in Axe Basic -  (Read 8224 times) 0 Members and 1 Guest are viewing this topic.
SirCmpwn
Guest
 « on: 07 April, 2010, 17:26:39 » +8

Hey, I wanted to do something special for my 400th post, so I wrote a quick tutorial.

Tilemaps are a very important part of many, many games.  For more information on what a tilemap is and how it relates to games, see this: http://en.wikipedia.org/wiki/Tile_engine  So, let's jump right in:

Getting started: The Data
The tilemap data actually defines which tiles go where.  Now, in Axe, we use the [] tokens to store hex data.  If you are not clear on what hex is, go here: http://vlaurie.com/computers2/Articles/hexed.htm.  A hex pair consists of two digits.  Now, we want to compress our map data, and using a special routine from BuilderBoy, we can cut our map data in half.  We have to limit ourselves to 16 tiles per map, but I'll address how to get around that later.  Anyways, here is an example map, 4x4 for the purposes of the demonstration:
 1234 [1111->GDB1[1001[1001[1111
Let's explain this.  How can we store 4 tiles to two bytes?  Well, we use each digit to store a tile.  We will talk about how to get each digit alone later.  Let me explain, however, why I put "->GDB1" at the top as opposed to the bottom, like you would do for a sprite.  GDB1 is just a pointer.  You see, Axe is going to add this data to the bottom of the program output.  It also will set GDB1 to point at the very first one.  However, if we were to re-arrange the code like so:
 1234 [1111[1001[1001[1111->GDB1
Then we would have GDB1 point to the 7th byte after the start of the map data.  This would be bad because it would make the first row all "1" tiles, and the rest of the rows the random gibberish sitting in the memory after the last row.  Not good.  So, we put "->GDB1" on the first line.  Also, for the sake of demonstration, please have your sprites in Pic1.

Drawing the Tile Map
Having the data is nice and all, but at some point you want to show it off.  So, we have a simple method to draw it.  The following method uses a 14x9 tile map with 7x7 tiles (hmm, isn't that what Half-Life 2: OC uses? ).  However, it should be easily customizable to fit with your needs.
 1234567891011121314 ClrDrawFor(I,0,7  // Start at zero, and go until your tile map width diveded by two (because we store two tiles for every one byte)For(J,0,8  // The Y axis has one byte to each tile, so you can just use the height minus one here.{J*9+I+GDB1->A  // J*9 gets us the row offset (see below) and we just add the X value.A^16->B // Get the second digit of the hex into BA/16->A // And the first digit into AIf APt-On(I*14,J*7,Pic1+A-8  // I*14 because of the two tiles to a byte, J*7 because of 7 pixel tilesEndIf BPt-On(I*14+7,J*7,Pic1+B-8EndEndEnd
Spoiler for Cool Optimization:
If you have more sprites than just what is needed for the tilemap, you can optimize away the "-8" subtraction in the Pt-On lines.  You also need to have Pic1 point to the sprite before the first tile map sprite in the data.
A^16?!? A/16?!?  How is that supposed to get each digit?!?  Honestly, I don't know.  Ask BuilderBoy.  It vaugely makes sense in my mind, but I haven't put a lot of brainpower towards it.  Anyway, this routine will draw your tilemap on-screen, without updating the screen.  It's your job to call DispGraph eventually, but you can still draw a character or something without having to worry about flicker.
Now, this line: "{J*9+I+GDB1->A" is weird.  Let me explain.  If you have a tilemap that looks like this:
11111111111111
10000000000001
10000000000001
10000000000001
10000000000001
10000000000001
10000000000001
10000000000001
11111111111111
It doesn't get stored in memory looking nice and layed out for you.  It gets stored like this:
111111111111111000000000000110000000000001100000000000011000000000000110000000000001100000000000011 000000000000111111111111111
So, what we can do to find the correct tile is this.  We start with the row.  We know each row is 7 bytes wide (2 tiles to a byte, remember?), so we can multipy J by seven.  So if we have J=2, then we get J=14.  That gives us an offset of 14 bytes.  So, we have eliminated tiles and we have a current estimate of which byte we are going to draw: (X for an eliminated tile)
XXXXXXXXXXXX
XXXXXXXXXXXX
10000000000001
10000000000001
10000000000001
10000000000001
10000000000001
10000000000001
11111111111111
Now, we just add the I value to get the current X offset, getting us the actual byte we need (I=3):
XXXXXXXXXXXX
XXXXXXXXXXXX
XXXXX00000001
10000000000001
10000000000001
10000000000001
10000000000001
10000000000001
11111111111111
Ta-da!  We have the correct byte. Now we can use voodoo magic to extract each individual digit from the byte, and draw it on-screen.

Getting a Tile
Hooray!  You drew a tilemap!  Congradulations!  Now, if you want to use something better than Pxl-Test to check collisions with it, you need to be able to get the value of a single tile.  I won't bother explaining this routine in detail, but just know I spent a half hour on it so you don't have to:
 123456789 Lbl GT  ; X position in S, Y position in T.  Returns tileS/7->S  // Swap 7 for the size of your tilesT/7*7->T  // Yes, I know it is /7*7.  Leave it that way.  Unless you don't have 7x7 tiles, in which case you should change the values accordinglyIf S^2{(S/2)+T+GDB1}^16ReturnEnd{(S/2)+T+GDB1}/16Return

More Than 16 Tiles
You may get to here and realize that, using this method, you can only have up to 16 tiles, one for each digit 0-F.  This is true.  However, you can have different tiles for different maps.  What?  You can only have 16 tiles per map, but you can have 16 unique tiles per map.  So, you can have different "themes" for each map.  It's easy.  Here is a revised draw method:
 1234567891011121314 ClrDrawFor(I,0,7  // Start at zero, and go until your tile map width diveded by two (because we store two tiles for every one byte)For(J,0,8  // The Y axis has one byte to each tile, so you can just use the height here.{J*9+I+GDB1->A  // J*9 gets us the row offset (see below) and we just add the X value.A^16->B // Get the second digit of the hex into BA/16->A // And the first digit into AIf APt-On(I*14,J*7,O*8+Pic1+A-8  // I*14 because of the two tiles to a byte, J*7 because of 7 pixel tiles.  O is the offsetEndIf BPt-On(I*14+7,J*7,O*8+Pic1+B-8EndEndEnd

You'll notice we added "O*8+" to the Pt-On lines.  This will make it so that you can specify O as an offset sprite.  So, if you wanted an entirely new set of tiles, you can specify O as 16, which would point to the sprites after the first set.  If you wanted to add one new sprite and lose the first old sprite, you could specify 1.  If you want the original sprites, specify O=0.

If you have any questions, feel free to post them, and I will do my best to answer.

Also, 400th post!
 « Last Edit: 08 April, 2010, 04:58:15 by SirCmpwn » Logged
Eeems
THE GAME

Offline

Gender:
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5074

Total Post Ratings: +230

 « Reply #1 on: 07 April, 2010, 17:33:19 » 0

sweet! this could come in handy for my mario game....if you want I can style this with my tutorial style I had in my tutorial.
 Logged

SirCmpwn
Guest
 « Reply #2 on: 07 April, 2010, 17:34:26 » 0

Can you email me your idea for the format before you do?
 Logged
Eeems
THE GAME

Offline

Gender:
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5074

Total Post Ratings: +230

 « Reply #3 on: 07 April, 2010, 17:39:31 » 0

I could just PM you actually, you can edit it for yourself and then I'll actually apply the post so it will work.
 Logged

SirCmpwn
Guest
 « Reply #4 on: 07 April, 2010, 17:39:55 » 0

 Logged
Eeems
THE GAME

Offline

Gender:
Date Registered: 14 March, 2009, 03:32:57
Location: Edmonton, Alberta
Posts: 5074

Total Post Ratings: +230

 « Reply #5 on: 07 April, 2010, 17:44:59 » 0

done, also, I'll have to apply it later today, class ended
 Logged

DJ Omnimaga
Retired Omnimaga founder (Site issues must be PM'ed to Netham45, Eeems, Shmibs, Deep Thought and AngelFish, not me.)
Editor
LV15 Omnimagician (Next: --)

Offline

Gender:
Date Registered: 25 August, 2008, 07:00:21
Posts: 50208

Total Post Ratings: +2613

 « Reply #6 on: 07 April, 2010, 18:29:53 » 0

Thanks a lot, I think I am getting the grasp of tilemapping in Axe, but I haven't messed around with them as much yet. Hopefully this should be very useful if I get problems or missed something.

Nice tutorial
 Logged

Retired 83+ coder, Omnimaga/TIMGUL founder. Now doing power metal music (formerly did electronica)

SirCmpwn
Guest
 « Reply #7 on: 07 April, 2010, 18:33:39 » 0

Thanks.  I have been thinking about releasing this one for a while, it was just finally prompted by my lack of respect on this forum.  It's down to 1 :O, I want to restore some of my credibility.
 Logged
DJ Omnimaga
Retired Omnimaga founder (Site issues must be PM'ed to Netham45, Eeems, Shmibs, Deep Thought and AngelFish, not me.)
Editor
LV15 Omnimagician (Next: --)

Offline

Gender:
Date Registered: 25 August, 2008, 07:00:21
Posts: 50208

Total Post Ratings: +2613

 « Reply #8 on: 07 April, 2010, 18:36:26 » 0

mhmm strange it has been a while since I actually saw it drop a lot :O. It was at 9 then dropped to 0 a few weeks ago, though, but since then I think it remained kinda stable

projects updates/tutorials/helping can help increase it, though (unless activity is ridiculously high, like last night around 11PM-1AM of my time)
 Logged

Retired 83+ coder, Omnimaga/TIMGUL founder. Now doing power metal music (formerly did electronica)

SirCmpwn
Guest
 « Reply #9 on: 07 April, 2010, 19:08:11 » 0

Yeah, I just need less complex projects to get more frequent updates
HL2: OC, LinTIx, and Mosaic are my major projects, and they are all pretty hefty.
 Logged
meishe91
Super Ninja
Members
LV11 Super Veteran (Next: 3000)

Offline

Gender:
Last Login: 02 May, 2013, 23:54:14
Date Registered: 05 March, 2010, 05:39:48
Posts: 2965

Total Post Ratings: +102

 « Reply #10 on: 07 April, 2010, 23:22:47 » 0

Nice tutorial. I'm not sure if I followed it all but that's just from lack of Axe knowledge.

(By the way, as a tip for the future. BBCode doesn't work inside the [code ][/code ] command (I just noticed the [b ][/b] to try to bold and thought I'd let ya know for the future.).)
 « Last Edit: 07 April, 2010, 23:24:39 by meishe91 » Logged

For the 51st time, that is not my card! (Magic Joke)
DJ Omnimaga
Retired Omnimaga founder (Site issues must be PM'ed to Netham45, Eeems, Shmibs, Deep Thought and AngelFish, not me.)
Editor
LV15 Omnimagician (Next: --)

Offline

Gender:
Date Registered: 25 August, 2008, 07:00:21
Posts: 50208

Total Post Ratings: +2613

 « Reply #11 on: 07 April, 2010, 23:35:43 » 0

What I do if I need bbcode is

 123 [quote][font=monospace]textgoeshere[/font][/quote]

Then check the "Don't use smileys" box.
 Logged

Retired 83+ coder, Omnimaga/TIMGUL founder. Now doing power metal music (formerly did electronica)

meishe91
Super Ninja
Members
LV11 Super Veteran (Next: 3000)

Offline

Gender:
Last Login: 02 May, 2013, 23:54:14
Date Registered: 05 March, 2010, 05:39:48
Posts: 2965

Total Post Ratings: +102

 « Reply #12 on: 08 April, 2010, 00:03:29 » -1

@DJ What do you mean exactly? What you said just isn't making sense to me is all, sorry.
 « Last Edit: 08 April, 2010, 00:03:44 by meishe91 » Logged

For the 51st time, that is not my card! (Magic Joke)
DJ Omnimaga
Retired Omnimaga founder (Site issues must be PM'ed to Netham45, Eeems, Shmibs, Deep Thought and AngelFish, not me.)
Editor
LV15 Omnimagician (Next: --)

Offline

Gender:
Date Registered: 25 August, 2008, 07:00:21
Posts: 50208

Total Post Ratings: +2613

 « Reply #13 on: 08 April, 2010, 00:42:48 » 0

Could someone else explain for me? I don't really have the patience to explain stuff like this this evening when I alerady done enough effort to do so. No offense intended.
 Logged

Retired 83+ coder, Omnimaga/TIMGUL founder. Now doing power metal music (formerly did electronica)

meishe91
Super Ninja
Members
LV11 Super Veteran (Next: 3000)

Offline

Gender:
Last Login: 02 May, 2013, 23:54:14
Date Registered: 05 March, 2010, 05:39:48
Posts: 2965

Total Post Ratings: +102

 « Reply #14 on: 08 April, 2010, 01:03:21 » 0

Oh, sorry, DJ. I wasn't trying to be rude or anything. When I read what you said it just wasn't making sense in my head for some reason (probably my lack of sleep). I think I get it now though. Did you mean that instead of using "code" to have a box around it you use "quote" when you still need BBCode inside (since BBCode doesn't work in "code")? Sorry again, wasn't trying to aggravate you or anything like that.
 Logged

For the 51st time, that is not my card! (Magic Joke)
 Pages: [1] 2 3 ... 7   Go Up