I am making a 2D RPG game in Monogame XNA. For the moment I have 2 kinds of data in my game: sprites objects and tiles.

All the sprites are contained in a array list. I iterate over the sprites ArrayList to update and draw each sprites. Sprites objects are sort by their Y positions before each draw. This way, my character and other enemies can walk behind sprites. Sprites can be anything that require player interaction for example: chest, tree, enemy, player…

Tiles represent inanimate objects(2D array) (object that you cannot interact with) and only used for collision data and have a basic animation system.

However, for sprites collision checking I have to iterate over every sprites to do a bounding box overlap check.

My system works well, but I want to simplify things. What if I store static objects in my 2D tile array? I could just do getTile(x,y) to get the object stored in that position instead of going through my array list.

In the future I would like to have several types of objects, weapons, projectiles, and I want a consistent way to organize this.

My game

  • \$\begingroup\$ It sounds like you have an idea for how you want to handle this: "What if I store static objects in my 2D tile array ? I could just do getTile(x,y) to get the object stored in that position instead of going through my array list" - do you encounter any difficulties when you try to implement that idea? What can we help you solve? \$\endgroup\$ – DMGregory Mar 27 at 1:08
  • \$\begingroup\$ Yes, If some objects are made of multiple tiles, I don't know if this will works well \$\endgroup\$ – Nyonx Mar 27 at 4:21
  • 1
    \$\begingroup\$ Did you mean to ask "how to handle objects that span multiple tiles" then? If you don't put that prominently in your question, folks won't know to address that aspect in their answers. Or better yet, search for past tutorials and Q&A about storing multi-tile objects in a tilemap. I can assure you that you're not the first game developer to investigate this, so you can learn from what's already been written by folks who came before. \$\endgroup\$ – DMGregory Mar 27 at 12:44

Since your question is a bit vague, I'll reply with an anecdote.

In the early 2000s, there were some graphics libraries but not that many game engines, so we hobby game devs wrote that stuff ourselves. With tile-based maps and sprites/objects on top, a common hint was to store the objects as part of the tile map to limit what needs to be drawn on screen. After all, it's simple to compute the visible portion of the 2D tile map on screen as minX/Y and maxX/Y of the tile map when you multiply the scrollOffsetX/tileSize and screenWidth/tileSize.

Now imagine that NPC positions are tile-based and each map tile knows which NPC stands on it; then you can draw the visible part of the tile map as a backdrop and then all visible NPCs on top. What's not on screen is skipped.

Having this information means you can also limit the collision checks. Player moves left? Peek at the tile position left of the player and see if there's an NPC blocking the space, or a collision 'flag' set, e.g. for walls.

So all in all, relying on the tile map and storing more information for each tile than which imge needs to be painted is totally viable.

This also works when you make characters move "in between tiles". It can work with the same base approach, but needs tweaking to position sprites at tileX/tileY plus an offset relative to the tile on screen.

Example: your tiles are 16x16 pixels. Your player character starts at the tile coordinates X=10, Y=20. On the screen, that means playerX=tileX*tileSize=10*16=160 and playerY=tileY*tileSize=20*16=320. Now the player moves 8px to the right. Then you store the 8 as an offset relative to the tile origin and factor this in. playerX=tileX*tileSize+offsetX=10*16+8=168.

If the player moves 16 instead of 8 pixels, check for offsetX >= tileSize, and if true, advance one tile tileX += 1 and reset the offset offsetX = offsetX % tileSize.

So yes, it works to store everything as tile info, and it can also help keeping the logic simple.


Your Answer

