Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / Scrolling Background
- - By Jeytas Date 2014-01-04 22:45
Hello,
I just wondered, how you could make a scrolling background? I took a look at the CptnRuby.rb Example, but I didn't quite understand how to use the translate thingy.
I hope you can help me

Marvin
Parent - By lol_o2 Date 2014-01-05 10:36
In CptnRuby there is scrolling map, not background. Background is static :)
Anyway, notice the camera_x and camera_y variables. They are storing the position of screen (the camera).
Normally, every image draws on coordinates you give it, so if you draw it at x = 2300 if may be out of screen. The translate thingy moves this image basing on camera position. If camera is at x = 2100 then the image draws at 2300 - 2100 = 200, so it appears on the screen.
Hope it helps :)
Parent - - By Cassy Date 2014-11-13 23:19
I know this is an old thread, but reading it made me think about something.

I didn't understand the translate function on CptnRuby example, so when I wanted to use a Scrololing Background on my game, I had to figure it out myself.

But, is the translate function only for map scrolling, or also for background scrolling?

I never thought there could be a difference at all. But maybe the translate thing could help me. In my game, I have an infinite scrolling background: 2 layers, one with the sky, and other with clouds, both running at different speeds, so it has the effect of distance. I defined a class for creating any layer of infinite scrolling:

class Layers < Gosu::Image
attr_reader :vel

  def initialize(image, imagewidht, vel, x, y, z)
        @layer2_image = Gosu::Image.new($window, image, true)
        @layer2_image2 = Gosu::Image.new($window, image, true)
        @x = x
        @xt = @x
        @yt = y
        @vel = vel
        @z = z
        @iw = imagewidht
  end

  def draw
    @layer2_image.draw(@xt, @yt, @z)
    @layer2_image2.draw(@xt + @iw, @yt, @z)
  end

  def update
    @xt -= @vel
     if @xt <= -@iw then @xt = @x end
  end
end

And you call it like this:
  @layer1 = Layers.new("bgLayer1.png", 800, 1, 0, 0, 1)
  @layer2 = Layers.new("bgLayer2.png", 800, 3, 0, 0, 2)


But now I want to put a terrain and other things that are unique, and doesn't require an infinite scrolling, so translate would be the choice then?
Parent - - By jlnr (dev) Date 2014-11-14 05:24
You are overthinking the translate function. :) All it does is add an offset to all drawing operations that happen inside the block you pass to it. So

translate(x, y) { img.draw(a, b, z) }

is the same as:

img.draw(a+x, b+y, z)

So you can't do anything with translate that you couldn't do without it, but it can be more convenient to use it.

I would recommend that you do not move the layers around, but keep a global pair of camera_x and camera_y variables around, and then in draw you calculate the position based on these two variables. The % (modulo) operator will definitely come in handy. But I don't know if there is a good tutorial on getting started with that kind of math... :( I usually sit down with a pen and paper and play with the formula until it works.
Parent - By lol_o2 Date 2014-11-14 14:08 Edited 2014-11-14 14:13
The formula looks like this: (for horizontal scrolling)
    (screen_width / background.width + 1).times{|x| (screen_height  / background.height + 1).times{|y|
     background.draw(x * background.width - camera_x % background.width, y * background.height - camera_y % background.height, z)}


Where:
background - your background image
screen_width/height - size of your window
camera_x/y - horizontal position of camera

This is for single image to be looped as you scroll vertically or horizontally. By removing second loop and replacing "y * background.height - camera_y % background.height" with your value, you can make simple paralax.

The more interesting formula is one for fitting image to a map greater than your screen, so it doesn't loop but rather scrolls to edges.
Parent - By Cassy Date 2014-11-19 19:09
Thanks to both, that made thing clearer, and gave me a few ideas :)
Parent - By RavensKrag Date 2014-12-04 09:49
Gosu::Image already allows you to read the height and width, so you don't have to save that value again.

Also, note that it might be better to save a bunch of items in an array, instead of using variable names with numbers in them.
So, you have
@layer2_image and @layer2_image2
but you could use
@images[0] and @images[1]
instead, which would also let you use any number of different images inside of your Layer class.

As another small style note, Ruby has another if style specifically for one-liners
so you wrote
if @xt <= -@iw then @xt = @x end
but it's also acceptable to write
@xt = @x if @xt <= -@iw
Up Topic Gosu / Gosu Exchange / Scrolling Background

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill