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 :)
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?
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.
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.
By Cassy
Date 2014-11-19 19:09
Thanks to both, that made thing clearer, and gave me a few ideas :)
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