Omnimaga

Calculator Community => TI Calculators => Axe => Topic started by: Munchor on May 29, 2011, 04:47:55 pm

Title: Axe Tilemapping 4*4
Post by: Munchor on May 29, 2011, 04:47:55 pm
I have never tried tilemapping in Axe, mainly because the two tutorials made on it are not appropriate for me. The one that works with platformers is too complex and the other one doesn't work with platformers, I think. Either way, I read bits of both, but both seem too complex for a pure beginner.

So I need some pure beginning introduction text (with code, even better), just something really small that lets me move on to the other tutorials, that helps me creating a 4*4 tilemapped map, because I have absolutely no idea of how to.

Thanks :)
Title: Re: Axe Tilemapping 4*4
Post by: Ashbad on May 29, 2011, 05:04:43 pm
basically, what you would want for a simple 4x4 tilemapper would be extremely similar to an 8x8 one:

Code: [Select]
For(B,0,15
For(A,0,23
Pt-On(A*4,B*4,{B*24+A+Data_Pointer}*8+Tile_Data_Pointer
End
End

All you need to define is a pointer to map and tile data ;)
Title: Re: Axe Tilemapping 4*4
Post by: tloz128 on May 29, 2011, 05:05:27 pm
Well, I'll try to help you out here.

To put it simply, a tilemap is a grid of numbers, like a matrix. Depending on the number of each element of that grid, a different tile is drawn. For example, here's what a 4 x 4 grid would look like:

1111
1001
1001
2222

'2' might represent a ground tile, while '1' would maybe represent a regular block, and '0' would be air (so nothing would be drawn).

The tiles can be read by a for() loop. Then, they would be drawn to the screen based on the modulus of the width (remainder of division by the width (for example, 13 modulus 8 would be 5)), and the and the floored (rounded down) division of the number that the for() loop is on and the width. These numbers are then multiplied by the dimensions of the block.

Here's an example: let's use the above grid again.

1111
1001
1001
2222

Let's say in this hypothetical situation that we have a screen that has dimensions of 32 x 32, and we are using 8 x 8 blocks (for simplicity's sake). Let's figure out the coordinates for the second block on the second row. That would be the 5th block out of 15 (since it starts with 0 and goes to 15) in the for() loop. The x value would be 8, because the modulus of 5 and 4 is one, and multiplied by 8 is 8. The y value would also be 8, because the floored division of 5 and 4 is one, and multiplied by 8 is 8. Although, nothing would be drawn, since the value of that block is 0.

For scrolling, an offset is just subtracted from the x and y values. I use the variables z and theta to do this.

Please let me know if I can clarify anything. :)
Title: Re: Axe Tilemapping 4*4
Post by: shmibs on May 29, 2011, 05:24:08 pm
hey scout =D
here is the basic idea explained in as much detail as i can manage:

firstly, your data needs to be in a readable format. if you have 4*4 tiles it doesn't seem like you'd need a full byte to designate which tile is to be drawn, but, for simplicity's sake, we'll do just that. there are plenty of half-byte tutorials out there for you to read once you have the basic idea.

take the map you want to draw, assign a unique one byte value to each type of tile you are going to be drawing, and, reading from left to right, top to bottom, convert your map into a string of those byte values.
for example, if   O.O is assigned to 00,  <_< to 01, and :P to 02, and you had the following map:
 O.O O.O <_<
 :P <_< :P
 O.O :P  :P

it would translate to:
[000001
[020102
[000202

once that's done, you need to take the images to be used for your tiles, convert them to hex data, and store them in order. although it makes the tile images take up four times what they would as 4*4 images, the absolute easiest way to handle this is to convert your images as if they were 8*8 images instead, leaving a four pixel buffer of blank both to the right of and beneath your desired image. this will make each of your images take up 8 bytes of data.


i bet you know that much already, though, and the real question is how to draw any arbitrary 24 wide by 16 tall chunk of this map on the screen.
that can be done with the following code:
Code: [Select]
:for(L,0,23
:for(M,0,15
:PtOff(L*4,M*4,{M+[the y offset, in tiles, of the spot in the map you want to draw, starting from the uppermost tile row in the map being zero]*[the total width of your map, in tiles]+L+[the x offset, in tiles, of the spot in the map you want to begin drawing at, starting with the leftmost tile collumn in the map being 0]+[a pointer, like GDB1 for example, to where you stored the tilemap you converted earlier]}*8+[the pointer to your tile image data]
:end
:end

or, with real arguments inserted:

Code: [Select]
:for(L,0,23
:for(M,0,15
:PtOff(L*4,M*4,{M+B*N+L+A+GDB1}*8+Pic1
:end
:end

where:
A= xoffset
B= yoffset
N= total map width, in tiles
GDB1= tilemap data
Pic1= tile image data

this method is simple, but it can be optimised a good deal (and there are plenty of threads showing how for that as well which you should be able to understand once you get the basic idea).
good luck!
Title: Re: Axe Tilemapping 4*4
Post by: Munchor on May 30, 2011, 02:50:19 am
I sort of got that, my problem is assigning a byte to an image.

In the example

1111
1001
1001
2222

How do I say 1 is [FFFFFFFF] and 0 is [00000000] and 2 is something else? And what kind of variable should I set it all to?

[1111
1001
1001
2222]→GDB

Is it a GDB?

Thanks.
EDIT: Thank you all a lot :)
Title: Re: Axe Tilemapping 4*4
Post by: aeTIos on May 30, 2011, 03:08:35 am
No. You are doing wrong. If you arrange the bytes that way, the pointer (GDB1) is pointing to the last 2 bytes of the map.
///
Quick tutorial on tilemapping
///
A tilemap is exactly what the name says: a map full of tiles. In the classic z80 tilemap, you can have up to 255 tiles (There is always one white tile, that you don't need to draw)
Now, lets go to some code. (Scout, for 4*4 tiles, you need to adjust some values, I'll comment in which values)
Code: (Most basic tilemapper I can make up) [Select]
.TILEMAPR
.Tile data:
[FFFFFFFFFFFFFFFF->Pic1  ; Or any variable (StrX,PicX,GDBX)
[F0F0F0F0F0F0F0F0
.Those are 8x8, for 4x4 just add 4x4 tiles (Wow thats hard to understand :D)
.Tilemap data (4x4 tilemap)
[00000001->Pic1TL  ; Or any variable (StrX,PicX,GDBX)
[01010102              ; Each tile takes a byte. Make sure to get the right hex code!
[02010201
[00010002
.Draw the tilemap
For(A,0,3)    ; Change the 3 to the height of the map minus 1
For(B,0,3)    ; Change the 3 to the width of the map minus 1
If {Pic1TL+(A*4)+B}->C ; Change the 4 to the width of the map
-1->C
Pt-On(B*8,A*8,Pic1+(C*8));Change the 8 in the coordinates to the width and height of the tiles
End
End
End
I hope this is clear enough. Now you have a tilemap drawn on the buffer. Add a dispgraph and... voila, your tilemap is there!

Title: Re: Axe Tilemapping 4*4
Post by: ztrumpet on May 30, 2011, 10:56:34 am
Is it a GDB?
Most people use GDB to refer to it, but it actually doesn't matter.  You can have [00010203]->Pic1D3 if you want to, or even "STRING"->GDB1.  In Axe, Pic, GDB, and Str are all interchangeable and serve no purpose other than being a name for a variable.  You can mix "types" all you want. :)
Title: Re: Axe Tilemapping 4*4
Post by: Munchor on May 31, 2011, 02:53:56 am
So, I got some more of it and started coding, based on aeTIo's sample.

Code: [Select]
.TILEMAPR
.Tile data:
[FFFFFFFFFFFFFFFF->Pic1
[F0F0F0F0F0F0F0F0
[22222222->Pic1TL
[20000002
[20000002
[22222222

Repeat getKey(15)
.Draw the tilemap
For(A,0,3)
For(B,0,3)
If {Pic1TL+(A*4)+B}->C
-1->C
Pt-On(B*8,A*8,Pic1+(C*8))
End
End
DispGraph
End
End

But why is this code a lot of dots and two blocks on the right. I don't really get how changing Pic1TL affects the code.

EDIT: I actually think I got it, I'm changing half of a byte, and not an entire byte.

Yeah, changing bytes worked better.
Title: Re: Axe Tilemapping 4*4
Post by: Munchor on June 01, 2011, 01:31:41 pm
Bump.
Title: Re: Axe Tilemapping 4*4
Post by: shmibs on June 01, 2011, 02:19:22 pm
the issue there was, as you realised, using half bytes rather than full bytes in your map data, so instead of
[22222222
[20000002
[20000002
[22222222
i think what you were trying to have it draw was
[02020202
[02000002
[02000002
[02020202
for which your tilemap code would work just fine.
two other things:
the code you have here will work, but will run more quickly when there are lots of 00 tiles and more slowly when there aren't, whereas the one i posted above has a stable draw speed regardless of what it's drawing.
also, instead of doing things like
Pic1+(C*8)
you should use
C*8+Pic1
because fewer parentheses means less space taken up and greater speed.
Title: Re: Axe Tilemapping 4*4
Post by: Munchor on June 01, 2011, 03:24:49 pm
Oh yeah, it's not 22 it's 02. Thanks a lot shmibs.

Code: [Select]
.TILEMAPR
.Tile data:
[FFFFFFFFFFFFFFFF->Pic1
[F0F0F0F0F0F0F0F0
[01010101->Pic1TL
[01000001
[01000001
[01010101

Repeat getKey(15)
.Draw the tilemap
For(A,0,3)
For(B,0,3)
If {Pic1TL+(A*4)+B}->C
-1->C
Pt-On(B*8,A*8,Pic1+(C*8))
End
End
DispGraph
End
End

I made this, but this is 8*8 isn't it? How can I make it 4*4? Thanks.
Title: Re: Axe Tilemapping 4*4
Post by: Munchor on June 03, 2011, 02:51:46 am
Bump, I really need help with this for the contest, thanks.
Title: Re: Axe Tilemapping 4*4
Post by: FinaleTI on June 03, 2011, 05:41:38 am
Oh yeah, it's not 22 it's 02. Thanks a lot shmibs.

Code: [Select]
.TILEMAPR
.Tile data:
[FFFFFFFFFFFFFFFF->Pic1
[F0F0F0F0F0F0F0F0
[01010101->Pic1TL
[01000001
[01000001
[01010101

Repeat getKey(15)
.Draw the tilemap
For(A,0,3)
For(B,0,3)
If {Pic1TL+(A*4)+B}->C
-1->C
Pt-On(B*8,A*8,Pic1+(C*8))
End
End
DispGraph
End
End

I made this, but this is 8*8 isn't it? How can I make it 4*4? Thanks.
Code: [Select]
.TILEMAPR
.Tile data:
[F0F0F0F000000000->Pic1
[C0C0C0C000000000
[01010101->Pic1TL
[01000001
[01000001
[01010101

Repeat getKey(15)
.Draw the tilemap
For(A,0,3)
For(B,0,3)
If {Pic1TL+(A*4)+B}->C
-1->C
Pt-On(B*4,A*4,Pic1+(C*8))
End
End
DispGraph
End
End
Give this a try. I haven't tested it, but I believe it should work.
Title: Re: Axe Tilemapping 4*4
Post by: Munchor on June 03, 2011, 09:19:29 am
FinaleTI, yeah it worked =) The only problem is that I still need all the 0s in the end of the hex code of a sprite, but it's cool anyway.

Thanks :)

Anybody know how to add greyscale to this?

Code: [Select]
.TILEMAPR
.Tile data:
[F0F0F0F000000000->Pic1
[C0C0C0C000000000
[01010101->Pic1TL
[01000001
[01000001
[01010101

Repeat getKey(15)
.Draw the tilemap
For(A,0,3)
For(B,0,3)
If {Pic1TL+(A*4)+B}->C
-1->C
Pt-On(B*4,A*4,Pic1+(C*8))
End
End
DispGraph
End
End
Title: Re: Axe Tilemapping 4*4
Post by: leafy on June 03, 2011, 11:27:39 am
For one, you'd need to have greyscale sprites. A greyscale sprite consists of 2 sprites, one of which will be drawn on the front buffer and one which will be drawn to the back buffer.

Code: [Select]
.TILEMAPR
.Tile data:
[F0F0F0F000000000FFFFFFFFFFFFFFFF->Pic1
[C0C0C0C000000000FFFFFFFFFFFFFFFF
[01010101->Pic1TL
[01000001
[01000001
[01010101

Repeat getKey(15)
.Draw the tilemap
For(A,0,3)
For(B,0,3)
If {A*4+B+Pic1TL}->C-1->C
Pt-On(B*4,A*4,C*16+Pic1->C)
Pt-On(B*4,A*4,C+8){r}
End:End
DispGraph{r}
End:End

I also did some minor optimizations.
(The {r} is the superscript r, located in like angle or something)
Title: Re: Axe Tilemapping 4*4
Post by: Runer112 on June 03, 2011, 12:46:50 pm
Fixing a few errors. Also, some reformatting and optimizations. :hyper:

Code: [Select]
.TILEMAPR

.Tileset
[]→Pic0T
[F0F0F0F0]Zeros(4)[F0F0F0F0]Zeros(4)
[C0C0C0C0]Zeros(4)[00000000]Zeros(4)

.Tilemap
[]→Pic0M
[01010101]
[01000001]
[01000001]
[01010101]

While 1
 4*4+Pic0M→C
 16
 While 1
  -4→B
  16
  While 1
   -4→A
   If {C-1→C}
    *16+Pic0T→D
    Pt-On(A,B,D)
    Pt-On(A,B,D+8)ʳ
   End
  End!If A
 End!If B
 DispGraphʳ
EndIf getKey(15)