Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / How does the Map Class in Captain Ruby work?
- - By max_n_ruby Date 2016-11-14 23:41 Edited 2016-11-15 02:58
How does Gosu get the tiles on the screen?
While trying to write my own map class I use some code to assign every tile a pixel coordinate. Gosu then draws the tile where I want it.
But in Captain Ruby game, the Map class reads an array full of either ones or zeros and somehow knows where to put the tiles on the screen.
Here's where it creates the array the maps are in.

@tiles = Array.new(@width) do |x|
      Array.new(@height) do |y|
        case lines[y][x, 1]
        when '"'
          Tiles::Grass
        when '#'
          Tiles::Earth
        when 'x'
          @gems.push(CollectibleGem.new(gem_img, x * 50 + 25, y * 50 + 25))
          nil
        else
          nil
        end
      end
    end


Here we get the multi-dimensional array. It's full of 1's and 0's and nil. (I'm ignoring the gems for right now. Trying to keep things simple.)
This array becomes the raw material for the draw method:

def draw
    # Very primitive drawing function:
    # Draws all the tiles, some off-screen, some on-screen.
    @height.times do |y|
      @width.times do |x|
        tile = @tiles[x][y]
        if tile
          # Draw the tile with an offset (tile images have some overlap)
          # Scrolling is implemented here just as in the game objects.
          @tileset[tile].draw(x * 50 - 5, y * 50 - 5, 0)
        end
      end
    end
    @gems.each { |c| c.draw }
  end


This draw method is hard for me to understand. I don't know enough about ruby to decipher what's going on here.
What I do know:
I know the .times method. We do 'something' @height and @width times. Where height and width are the values taken from the map text file.
I get a little fuzzy when it creates the tile variable.
Then we get to the Gosu draw method.
The method parameters x * 50 -5 & y * 50 -5 decide where the tiles are drawn in the window.(I think.) But I don't understand what the x and y are and why you times them by 50. I mean, I know that x and y represent items in the @tiles array but... I'm confused :)
Any help to clarify would be appreciated.
Parent - - By bestguigui Date 2016-11-15 15:44 Edited 2016-11-15 15:52
Hi !

I suggest you to IRB any portion of code you don't get.

For example, if you go like :

@width = 10
@width.times do |x|
  p x
end

you'll see in the output that you'll display 10 times the variable x, that will take from 0 to 9 values. It's just a way to handle every tile in the map, to make x and y take any possible value.

you could also do :

for x in 0...@width
  for y in 0...@height
    # handle [x][y] position
  end
end

which is the way I'm pretty much always using myself.

Then you get your coordinates in tiles unit, and you need to multiply by the tile size in pixels to get the position in the screen. This is where the "* 50" is used, to get from tiles coordinates to screen coordinates.
Parent - By max_n_ruby Date 2016-11-16 02:31
Thanks for the reply.
That helped a lot to figure it out in IRB.
Previously I was loading the entire Map class into IRB. Breaking it down to the individual methods and processes made a difference.
Parent - By jlnr (dev) Date 2016-11-16 23:21
Using .times is shorter than the for ... in loop, but I have to agree it's hard to read. Glad that you asked about it, I'll make a note to change it :)
Up Topic Gosu / Gosu Exchange / How does the Map Class in Captain Ruby work?

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill