Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

TileMap Creation

Alright, I have a new question...I'm looking into programming my own Tilemap script so that I can draw maps using 8x8 tiles instead of 32x32. Also for the experience. Anyways, as I am drawing up concepts for how I want everything to work, like how the map data will be set up and everything, I started to think on how I should display the Tilemap on the screen. I'm alittle confused on how RMXP does it. I'm trying to think of an efficient way to display the screen and allow scrolling on the pixel level(not tile). I've programmed two pixel movement scripts for RMXP, so I've worked a good deal with the maps and some with scrolling...but I haven't worked with the tilemap before...at least not much :P. So I'm just looking for suggestions and possibly an explanation on how they do it in RMXP. Thanks guys! You've been a big help thus far!
 
hey thanks! I'll go through it now and let you know if I have any questions. ^^

EDIT: So from what I can tell, you set up the layers as either Planes or Sprites and then draw all of the tiles for the whole map onto the right layer's bitmap, right? That is what I was thinking of doing. I just wasn't sure if that was really doable, or if it would lag up the game to no end. Thanks again for showing me that. I helps clarify a few things I was uncertain about.
 
I´more to the point of creating a controlled array/table of sprites covering all the screen, and in each sprite we put the tileset bitmap with the correct src_rect (and so it will show only the portion of the bitmap that corresponds to the tile itself). That way, we can avoid the over-time-consuming bitmap operations (even more for 8x8 px tiles), and the overuse of bitmap objects (the greatest processor resource eater ever! xD). I would also suggest you to use the Resolution´s Script from Selwyn, or reduce the quantity of tiles in the screen, because RMXP is lazy to the point that a number of 2500~3000 sprites in the screen makes the game lag very bad (counting the default sprites, for events, pictures, planes, windows, etc), depending A LOT on your system environment.

BTW, I think that 8x8 tiles are waaay so small. Why do you need them to be so small that way?
 
I think I get what you are tying to say Linkin_T. What I recently did as an atempt to speed it up do to the auto-tiles was when you set the tile data, it creates an array of sprites for each layer, for each priority. Then when the frame reset is suppose to be set, it just redraws from the array of complete bitmaps. Sadly, this is even slower than what I have done. The way it is now, when the frame resets, it checks every tile data and redraws only autotiles (then regular tiles on top of that). I may still have this trial on my exHD. If I can find it, I will post it.

The only thing I can think of to speed this process up is currently, it draws autotiles in 4 sections. If I were to draw all tiles onto a bitmap from the getgo, it would only need to use 1 blt transfer per autotile instead of 4.

I also made it so it would only update tiles currently on screen instead of every autotile.
 
Sadly, I've been busy today so I wasn't able to the Tilemap until just now. Anyways, in the last hour or whatever, I got the basic Tilemap down and working. I have the map at the smallest size possible so I cant really tell, but it isn't displaying any lag right now. I have my screen resolution set at 240x160(GBA size) with the option to enlarge it to 480x320(x2). So that is why my tiles are 8x8. I have my graphics set up similar to how the GBA is set up for mode 0. So I have 4 BGs and an array for sprites, an 'OAM.' So I only have usually about 40-50 sprites at a time on the map at most really. Probably less. Since I'm working on the tilemap right now, I have obviously not gotten to map a real map yet and see how many sprites I'm actually using. I'll see how things go though!
 
Hmm seems a good progress Baskinein. I just wonder... Do you make the map tile'ing inside Bitmaps? Because 50 sprites is just a small number for sprite-based tilemaps, and way too much for bitmap-based. And well the size helps a bunch too, this is small enough to make your game run very smooth, by reducing the area to be covered by the tilemap (i just think it´s so small ^^). Looking forward to see what will come up Baskinein. Any doubt/suggestion/whatever, you can PM me too if you want.

And SS, i was thinking on something like that, the sprites can not just change their contents, but their position too. I can set their OX and OY with a defined tile localization on the screen, and control their position via X and Y (to make the scroll of the tilemap). When that scroll value changes to a determined reference value (says, half of the tile´s size), it "redraws" the sprites' contents, in a better way than making blt. And of course, the autotiles will be updated on each frame too. No need to check for it on each frame, it´ll be done at the time the script messes up with Tilemap#ox and Tilemap#oy. And the sprites doesn´t have to be updated too, just those ones that has some kind of effect in it.

All those sprites will have the same viewport, and with it we can flash them and even define a basic Z position. This viewport will be the Tilemap´s viewport, and even if the tilemap is not created with one, they will have one (just for organization facility). The only difficulty will be to control all the sprites in the map. The number of sprites in the screen will be proportional to the window client´s size (be it 640x480, or 320x240, or whatever), the tile´s size and the number of layers (in this case, 3). We´ll need one more row and column of sprites to make it possible to scroll the map without cutting it. For instance, for a 640x480 window size and a 32x32 tile...
Code:
number of rows = 480 / 32 = 15
number of columns = 640 / 32 = 20
Add one more row and column, and we´ll have, for each layer...
(15 + 1) * (20 + 1) = 336 sprites
Total number of sprites = 336 * 3 = [b]1008 sprites[/b]

Not counting the default RMXP´s sprites, just the Tilemap´s sprites
Not impossible, just a bit of hard-working and it can be done. Unluckily, i´m not that kind of person lol -_-

Better patience for all of those ppl trying that out. I gave up for a while to work in other scripts. I wonder i could have more time in my hands now... T.T
 
Right now I have the tiles being displayed using bitmap.blt, which works fine...but I think once I get the map being a little bit larger it starts to lag. I need to mess with it some more. After I got a basic map being displayed, I went onto displaying character sprites and getting the walking down. I am actually now going to investigate on displaying the tilemap in an effective manner. I am interested in your concept Linkin_T. I might give that a try. For my map setup it would be something like this...
Code:
number of rows = 240 / 8 = 30
number of columns = 160 / 8 = 20
(30 + 1) * (20 + 1) = 651 sprites
Total number of sprites = 651 * 3 = 1953 sprites

1953...that's a great amount of sprites. Now would updating these sprites every frame be faster than drawing onto a single bitmap using .blt? Now that I think about it, it matters how big the map is. Using an array of sprites is a constant demand, while the bigger the map is the more demanding it is. I dont know...maybe I'm alittle confused on how it is all suppose to be setup. I'm trying to conceptualize it all in my head...and I just finished physics homework...so my brain is fried. I'll work on it tomorrow probably. Alright thanks guys for the ideas, keep them coming. I'll update tomorrow.
 
Baskinein;152298 said:
1953...that's a great amount of sprites. Now would updating these sprites every frame be faster than drawing onto a single bitmap using .blt?

No.

I'm currently working on a script that turns every pixel of a bitmap into a sprite, allowing explosion effects and various other things.
I have tried it with a character (~64*20 pixels), not counting the transparent pixels, I had approx. 400 sprites. And it lagged a lot so you'd better forget about 2000 sprites Ugh...
 
Haha, yeah. Allocating and accessing that much memory for all of those sprites would be pretty demanding I'd imagine. It would be really sad to write that tilemap script using the array of sprites concept and then having it just lag up and leaving you the only choice of starting over. Very sad. It is however a very cool concept and could quite possibly be altered slightly and used...maybe not in the tilemap script, but something else. I'm going to continue to think about it, see if I can come up with anything else.
 
Code:
class TiledMap
  ANIMATIONTIME = 12
  TILESIZE = 8
  ANIMETILEFRAMES = [4]
  attr_accessor :ox
  attr_accessor :oy
  def initialize
    @tileset = RPG::Cache.tileset("Test")
    @animetileset = RPG::Cache.tileset("AnimeTiles")
    $screen.mapSize($gameMap.width, $gameMap.height)
    @animeTiles = []
    @ox = 0
    @oy = 0
    update
  end
  def update
    if $gameMap.redraw
      refresh
    end
    for i in 0..3
      $screen.BG[i].realox = @ox
      $screen.BG[i].realoy = @oy
    end
    if Graphics.frame_count % ANIMATIONTIME == 0
      updateAnimeTiles
    end
  end
  def refresh
    $gameMap.redraw = false
    @tileWidth = $gameMap.data.xsize
    @tileHeight = $gameMap.data.ysize
    for z in 0...$gameMap.data.zsize
      for x in 0...$gameMap.data.xsize
        for y in 0...$gameMap.data.ysize
          id = $gameMap.data[x, y, z]
          next if id == 0x0
          id < 0xFF ? drawTile(x, y, z, id) : drawAnimeTile(x, y, z, id)
        end
      end
    end
  end
  def drawTile(x, y, z, id)
    rect = Rect.new((id % 0xF) * TILESIZE, (id / 0xF) * TILESIZE, TILESIZE, TILESIZE)
    x *= TILESIZE
    y *= TILESIZE
    $screen.BG[z].bitmap.blt(x, y, @tileset, rect)
  end
  def drawAnimeTile(x, y, z, id)
    rect = Rect.new(0, (id - 0x100) * TILESIZE, TILESIZE, TILESIZE)
    x *= TILESIZE
    y *= TILESIZE
    $screen.BG[z].bitmap.blt(x, y, @animetileset, rect)
    @animeTiles.push(AnimeTile.new(x, y, z, id))
  end
  def updateAnimeTiles
    for tile in @animeTiles
      rect = Rect.new(tile.frame * TILESIZE, (tile.id - 0x100) * TILESIZE, TILESIZE, TILESIZE)
      $screen.BG[tile.z].bitmap.blt(tile.x, tile.y, @animetileset, rect)
      frames = ANIMETILEFRAMES[tile.id - 0x100]
      tile.frame = (tile.frame + 1) % frames
    end
  end
end

class AnimeTile
  attr_reader    :x
  attr_reader    :y
  attr_reader    :z
  attr_reader    :id
  attr_accessor :frame
  def initialize(x, y, z, id)
    @x = x
    @y = y
    @z = z
    @id = id
    @frame = 0
  end
end

Well, thats what I have for my TileMap script. Nothing too special. I'm sure I will make a few advancements as time goes on, but for now it draws the map and plays animated tiles. That's all I need at the current moment. I'll probably add in some code to make it so that it wont waste time animating tiles that are not on the screen. Thanks again for your guys' help. ^^
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top