Roland_Yonaba wrote:First, are you thinking of multiple layers ?
Ah, interesting question. Yes, I have thought about those. I could not think of a way to support them, because although there is a "usual case" (parallax scrolling) there are exceptions and edge cases that I could not handle with a straightforward interface.
In "regular" parallax scrolling, the "background words" are smaller, and the ones "near the observer" are bigger. When the player moves, this movement is translated "proportionally". So when the player moves 10px in a 1000px foreground, the 100px bacground only moves 1px (And if anything is even nearer to the viewer, it moves faster; see the rocks near the bottom in the following video):
In other occasions, the background moves completely independently from what happens in the foreground. For example, Psylocke's stage in "X-Men: Children of the Atom" takes place in a submarine that moves around in the ocean, more or less independently of what happens in the fight:
This of course gets worse once you consider rotation and scaling. (Does rotation in the foreground affect the background, too? If so, how much?).
At the end, the only thing I could do to support multiple "layers" was, paradoxically, not supporting them explicitly. gamera does not mention them, but you can do them with it, since it's a relatively simple library. The trick is using several cameras (one per layer) and translating movement from one to the other. These two functions are all you need to do the "usual" parallax scrolling:
Code: Select all
local function getRelativePosition(cam)
local x,y = cam:getPosition()
local _,_,w,h = cam:getWorld()
if x ~= 0 then x = w/x end
if y ~= 0 then y = h/y end
return x,y
end
local function seRelativePosition(cam,x,y)
local _,_,w,h = cam:getWorld()
cam:setPosition(w*x,h*y)
end
And here's how you use them:
Code: Select all
local bgCam = gamera.new(0,0,1000,1000)
local fgCam = gamera.new(0,0,2000,3000) -- The fg world is twice as wide and 3 times as high as the background
...
function love.update(dt)
...
fgCam:setPosition(player:getPosition())
setRelativePosition(bgCam, getRelativePosition(fgCam)) -- usage of get/setRelativePosition here
...
end
function love.draw()
bgCam:draw(drawBackground)
fgCam:draw(drawForeground)
end
So, that was my conclusion; every game might want to do layers a bit differently, so I made it possible, but not "fixed".
Roland_Yonaba wrote:And, second, what would you think of a slideTo or (scrollTo) method ?
I have thought about those. I have even devised an interface that I liked. Instead of having separate methods, make setPosition accept more params.
Code: Select all
gamera:setPosition(x,y,time,interpolation)
And make time default to 0 and interpolation default to 'linear'. I then could use
tween.lua to move the camera relatively easily.
... But that also comes with a cost. The library would have one (possibly optional) dependency, and would be more difficult to understand and setup.
Then,
kexisse mentioned that he was thinking about using gamera to build a camera system similar to this (awesome) one:
I answered to him that I think it would be possible to build something "on top of" gamera (a "cameraman" of sorts) in order to achieve this, but extending gamera to have all that functionality might be counter-productive (it would make gamera too complex).
And that's kindof how I feel about gamera at the moment. I think it has the right balance between functionality and flexibility. Adding more stuff (layers, or interpolations) is better done "outside". It's game-specific, so I would not include it in gamera by default (I'm still not decided about tween though; If I find a way to include it without being too intrusive, I might do so)
Sorry about the long wall of text. That's what you get for asking such good questions