## [library] gamera - A camera system for LÖVE - v1.0.1 is out

BlackBulletIV
Inner party member
Posts: 1260
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

### Re: [library] gamera - A camera system for LÖVE - v0.8

Looks pretty awesome. I quite like the idea of camera windows (allowing multiple cameras on screen).

As for set/unset versus a callback, I prefer the former, largely due to performance. With the latter method, you're defining a function every frame. It's not a huge thing, I know, but it's something to consider. I slightly prefer the style of set/unset (at least when it comes to cameras) anyway, so it's an easy choice for me.

Roland_Yonaba
Inner party member
Posts: 1562
Joined: Tue Jun 21, 2011 6:08 pm
Contact:

### Re: [library] gamera - A camera system for LÖVE - v0.8

BlackBulletIV wrote:With the latter method, you're defining a function every frame.
Actually, I wanted to say the same thing, then I realized that it might not be a problem, as the function can be created once, wrapping everything to be drawn, even using upvalues, then passed to camera.draw

Code: Select all

function love.load()
-- vars
function draw(...)
-- all drawing operations
end
end

...

function love.draw()
--
camera:draw(draw,...)
--
end
BlackBulletIV wrote:I slightly prefer the style of set/unset (at least when it comes to cameras) anyway, so it's an easy choice for me.
But I agree with you on this, to me it is just a matter of preference.

BlackBulletIV
Inner party member
Posts: 1260
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

### Re: [library] gamera - A camera system for LÖVE - v0.8

Roland_Yonaba wrote:Actually, I wanted to say the same thing, then I realized that it might not be a problem, as the function can be created once, wrapping everything to be drawn, even using upvalues, then passed to camera.draw
Yeah I thought of that too. However, I don't about anyone else, but I find that unnecessarily ugly. You can certainly do that if you're really put off up set/unset, but I'd prefer to avoid the funception to begin with.

EDIT: I suppose that technique would be useful for when multiple cameras are involved; you could pass the same draw function to each camera.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: [library] gamera - A camera system for LÖVE - v1.0 is ou

I'm releasing gamera to v1.0.

Changes from previous version:
• I've reviewed the angle/scale setting, and to the best of my knowledge, they are fine
• New method: toScreen() (inverse of toWorld())
• New method: getVisibleCorners() returns the 4 corners of the rotated rectangle representing the visible region. This rectangle is now visible on the demo.
I've updated the OP accordingly.

Regarding the "draw in a function" vs "set + draw + unset" discussion we had the other day: I've given it much thought, but I'm still not convinced that using set/unset is better. I don't think I can be "convinced" to find anonymous functions "ugly". I think they are the best tool to use in this particular case.

I realize that many of you may not like this. I apologize. Feel free to create a fork if you are really disgusted. I will not take offense. But before forking, I ask you to please try it with a function. It's really not that bad. Trust me
When I write def I mean function.

Roland_Yonaba
Inner party member
Posts: 1562
Joined: Tue Jun 21, 2011 6:08 pm
Contact:

### Re: [library] gamera - A camera system for LÖVE - v1.0 is ou

kikito wrote:I'm releasing gamera to v1.0.
Well that's good news!
kikito wrote: Regarding the "draw in a function" vs "set + draw + unset" discussion we had the other day: I've given it much thought, but I'm still not convinced that using set/unset is better. I don't think I can be "convinced" to find anonymous functions "ugly". I think they are the best tool to use in this particular case.
To me, that was just a random thought that crossed my mind, and I just wanted to suggest. But I am fine with anonymous functions, too.
A couple of features suggestions (again) : first, are you thinking of multiple layers ?
And, second, what would you think of a slideTo or (scrollTo) method ? I've always wanted to have something like this. Lemme explain. See, there's already a camera:setPosition method, that actually makes the camera "jump" to a specified position. What if one needs the camera to scroll gently to that position, like in a cut-scene, for instance ? It might require to add a speed property to the camera, and implement a linear ease effect to achieve this.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: [library] gamera - A camera system for LÖVE - v1.0 is ou

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
Last edited by kikito on Sat Jan 26, 2013 4:03 pm, edited 1 time in total.
When I write def I mean function.

soulmata
Prole
Posts: 11
Joined: Sat Jan 26, 2013 8:14 am

### Re: [library] gamera - A camera system for LÖVE - v1.0 is ou

I registered just to say this is a really amazing library. It took me all of 60 seconds to integrate it into a project I'm working on, and it saved me hours and hours of time having to write my own camera system.

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Contact:

### Re: [library] gamera - A camera system for LÖVE - v1.0 is ou

soulmata wrote:I registered just to say this is a really amazing library. It took me all of 60 seconds to integrate it into a project I'm working on, and it saved me hours and hours of time having to write my own camera system.
Thanks for your kind words, I'm very pleased that it helped you
When I write def I mean function.

XOdysseusX
Prole
Posts: 11
Joined: Fri Apr 26, 2013 3:32 pm

### Re: [library] gamera - A camera system for LÖVE - v1.0 is ou

I gotta say, I tried making my own camera class and it was a disaster. I admire your talent, kikito.

However I'm finding a problem. I don't know if it's me or Gamera (probably me), but I can't get gamera:toScreen(x,y) to work.

I use it like this

Code: Select all


if love.mouse.isDown("r") == true then

local x,y = self.camera:toScreen(self.body:getX(), self.body:getY())
local deltaX = love.mouse:getX() - 400
local deltaY = love.mouse:getY() - 300
if love.keyboard.isDown('s') then
deltaX = love.mouse:getX() - x
deltaY = love.mouse:getY() - y
print("X: ".. math.round(x).. " Y: " .. math.round(y))
end



The local x and y values should be 400 and 300, because the player is centered on the screen, but they remain body's x and y values. Check it out. I'm sorry about the messy code, I have a game in mid development and I'm a beginner.

To see how it's supposed to work, just press the right click button and rotate the player, to see how it works with the toScreen method, hold down "s".

P.S: If you're standing on the side of the planet it will start to spin and you may start getting dizzy, so watch out.

Attachments
GaLaXe.love

kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm