gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

ASM > Single tiles that the player can walk behind

#177708 - chickendude - Wed Dec 05, 2012 2:55 pm

I was just wondering if there was an easy way to handle tiles (like, say, a sign) that will cover the player when they walk behind it but which will be drawn behind the player when the player is in front. Here's a screenshot of what i mean:
http://www.mirari.fr/2PFu
There i drew all tiles up until the player's Y position, then drew the player, then the rest of the tiles. So tiles behind the player get drawn below and tiles in front get drawn on top. But on the GBA that's all done by hardware. I've got different layers and priorities working (more or less):
http://www.mirari.fr/VAU7
But now i'd like to add another layer. That sign in the middle, for example, i'd like to be able to walk behind it and in front of it. Any ideas/tips?

EDIT: I've got an idea. I could check the tiles the top of the player is in and if it's a tile in the foreground layer, i can change the player sprite's priority to draw on top. This has some limitations, as it wouldn't let me put another foreground tile directly below it, and some tiles should always be drawn on top. I guess that means another layer is needed: a ground/background layer, an "objects"/foreground layer, and lastly a "bridge" layer that always gets drawn on top.

#177709 - sverx - Wed Dec 05, 2012 5:31 pm

You just need two backgrounds. One for everything 'under' the sprite, the other for everything 'over' the sprite. If there's something that can be either 'under' or 'over' you've just got to move it to the appropriate background.
_________________
libXM7|NDS programming tutorial (Italiano)|Waimanu DS / GBA|A DS Homebrewer's Diary

#177710 - chickendude - Wed Dec 05, 2012 5:49 pm

What about a sign? If i'm moving it to the background layer, it'll overwrite whatever tile was there before, probably a ground tile. Since individual tiles can't change priorities, only the full mapset, wouldn't it be easier to change the player's priority? Or how would you move it to the other background? You'd remove the tile(s) from one screenblock, then copy it into the other. It seems pretty complicated to keep track of which tiles need to be where when... Though that seems like a useful idea for things like bridges where sometimes you go under them and other times you go across them, since you can make the change when you detect the player going up some stairs, a ladder, etc.

#177711 - sverx - Thu Dec 06, 2012 10:41 am

What about using sprites instead? I mean, if you haven't got an huge amount of such 'objects', you can use sprites, simply sorting them according to the Y coordinate.
Of course you can keep on using two separates backgrounds for everything that is always 'behind' the player and for everything that is always 'above' the player, such as roofs for instance...
_________________
libXM7|NDS programming tutorial (Italiano)|Waimanu DS / GBA|A DS Homebrewer's Diary

#177713 - chickendude - Thu Dec 06, 2012 8:10 pm

That's definitely an option, as in each map i don't think there will be that many tiles like that, most will fit cleanly into foreground/background. Again it's just a little more complicated since sprite coordinates are handled differently from map coordinates (they're based on screen position). But i guess as i'll already have to handle things like NPCs or enemies onscreen it'd be more or less the same as having a static NPC.

Thanks for the suggestions :)

I rewrote my tilemapper again today and it just amazes me how short the code is (and my code is definitely not very optimized!). It breaks a 512x512 map using 32x32 "metatiles" into its individual tiles (tile 0 really = tiles 0-15, tile 1 = tiles 16-31, etc.).
Code:
@ r0 = map
@ r2 = destination
drawMapScroll:
   ldr r11, =0x03020100
   mov r9, #16               @ 16 rangs
drawMapOutterLoop:
   mov r8, #16               @ 16 colonnes
drawMapRowLoop:
   ldrb r3, [r0],#1
   mov r3, r3, LSL #4         @ tileId*16
   mov r10, #4
drawMapSpriteLoop:
   and r3,r3,#0xFF
   add r3,r3,LSL #8         @ $01+$0100 = $0101
   add r3,r3,LSL #16         @ $0101+ $01010000 = $01010101
   add r3,r3,r11            @ $01010101 + $03020100 = $04030201 :) (les tiles qu'il faut inserter)
   str r3, [r2],#64
   add r3, #4
   subs r10, r10, #1
   bne drawMapSpriteLoop

   sub r2, r2, #256-4         @ Le -4 est pour aller à la prochaine colonne
   subs r8, r8, #1
   bne drawMapRowLoop
   add r2,r2,#256-64
   subs r9, r9, #1
   bne drawMapOutterLoop
   bx lr

#177719 - ScottLininger - Thu Dec 13, 2012 5:25 pm

I always used sprites for that. Since you can then place those objects at exact pixel locations instead of being "fixed" to the tile grid, you can give your worlds a more organic feel, too.

-Scott
_________________
Some of my GBA projects

#177720 - chickendude - Fri Dec 14, 2012 8:03 am

But every time the camera shifts you've got to update all their coordinates, right? I'm still not quite sure what the GBA is capable of (with my lousy code) so i'll try a few things out. I just realized the pain of larger maps for text backgrounds and how they're stored (32x32 segments) so now i'm trying to update my tilemapper to handle wider maps.

#177721 - gauauu - Fri Dec 14, 2012 4:12 pm

+1 on using sprites. That's what I've done as well. Sure you have to track them and move them when the camera moves, but you have to do that with any sprites, so you should already have code to handle that.

#177722 - Miked0801 - Mon Dec 17, 2012 6:33 pm

We've used sprites when possible and mixed 2BG layers when that wasn't possible due to color, VRAM, or sprites on a line restrictions. With BGs, you also need to tag the area in front of the 2nd BG such that you can dynamically change the priority of the actor sprite when it icould need to sort. There are always going to be cases where this will break if you place objects to close together - say a table right next to a chair where the hero sprite is sorting on top of one and behind another. We always just made sure to avoid these cases when placing actors. If you have 3 or 4 or 5 sprites all walking in the same area sorting with BG and not, you will get sorting issues.

Sprites are the way to go if at all possible...

#177725 - chickendude - Thu Dec 20, 2012 8:02 pm

I had initially thought that putting all static things into the background would be more efficient/quicker, but i'll rethink it after everything you've all said. It just feels weird to treat the base of a tree as an object rather than part of the background, but maybe you all are right.

Btw, i just got a linker today (an Elink2) and sent my little program to the GBA. It's pretty cool seeing it run on actual hardware :) Strangely, though, the program (the ROM takes up about 14 kb with the GBA header and all) somehow takes up 7 MB on the cartridge.

Thanks for all the input.

#177728 - sverx - Fri Dec 21, 2012 10:14 am

Of course you don't have to use sprites for each object or for the whole objects, I would use them just for those parts where it's not possible to use a BG tile at all.

As for the linker... I have a SuperCardSD and I think that it's actually easier to copy my files onto a SD and put them into the SuperCard. :)
_________________
libXM7|NDS programming tutorial (Italiano)|Waimanu DS / GBA|A DS Homebrewer's Diary