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

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

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

Post by kikito »

Hi there!

During the last week I've been developing a camera library. It's on github, as usual:

https://github.com/kikito/gamera

Features:

It does translating, scaling, and rotation. It also transforms screen coords into world coords. That much is "usual". The special things:
  • A method, :getVisible() will give you a the region that the camera is seeing, taking into account things like scale and rotation. You can use it to optimize and don't draw anything outside that region.
  • The system tries very, very hard not to show you any "world edges". It adjusts its position and scale levels so that you never see the "world ends" by default.
  • This is a small thing, but it defines a "window" - the region of the screen where it can draw. The window can only be rectangular.
  • The getVisibleCorners method returns the 4 corners of the rotated rectangle containing the region of space visible by the camera
Demo:
gamera-demo.png
gamera-demo.png (13.17 KiB) Viewed 28558 times
I'm attaching a demo showing two different cameras displaying the game world. The left camera is the "main" one, while the other one is a "minimap" of sorts. It displays the same as the main camera, zoomed out, and the "visible area" of the first cam as a blueish rectangle. Inside it, a rotated rectangle shows the "real" visible rectangle, rotation included. The blue rectangle is cam1:getVisible(), the other one is cam1:getVisibleCorners()

Controls: Mouse moves the "target" around. Up/Down changes scale on main camera. Left/Right changes angle on main camera. Esc exits.
gamera-demo.love
updated to v1.0
(5.8 KiB) Downloaded 2762 times
You can not see it, but only the visible cells of the "world matrix" are drawn, depending on the visible zone. I think it's quite neat.

Status/Misc:
v1.0.1 fixes a buggy implemenation of toScreen()

Having vrld's hump.camera module helped me significantly on the tricky trigonometric calculations, but I feel the code is different enough from his lib to guarantee a separate license (MIT in any case). If you need a camera system and gamera doesn't meet your needs, you should check hump.camera out.
Last edited by kikito on Sun Apr 28, 2013 11:29 pm, edited 4 times in total.
When I write def I mean function.
benhumphreys
Prole
Posts: 31
Joined: Thu Sep 13, 2012 2:10 am

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

Post by benhumphreys »

Superb as always :D I like the :getVisible() function!
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

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

Post by kikito »

Thank you :) If you are thinking about using it, keep in mind that I still have to review the scaling/rotating code (I'm pretty sure they are "switched").
Last edited by kikito on Thu Dec 20, 2012 3:39 pm, edited 1 time in total.
When I write def I mean function.
User avatar
Roland_Yonaba
Inner party member
Posts: 1563
Joined: Tue Jun 21, 2011 6:08 pm
Location: Ouagadougou (Burkina Faso)
Contact:

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

Post by Roland_Yonaba »

Great job here. :awesome:
A question, though. Not to debate, but I am just wondering why the drawing operations should oblige the user to wrap things in a function ?
Maybe you could have a gamera:set() (where you push, translate, rotate then a gamera:unset() where you pop graphics, and then drawing operations should be made between those two methods.
coffee
Party member
Posts: 1206
Joined: Wed Nov 02, 2011 9:07 pm

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

Post by coffee »

Roland_Yonaba wrote:Great job here. :awesome:
A question, though. Not to debate, but I am just wondering why the drawing operations should oblige the user to wrap things in a function ?
Maybe you could have a gamera:set() (where you push, translate, rotate then a gamera:unset() where you pop graphics, and then drawing operations should be made between those two methods.
I think the same Roland! I ended doing the same some time ago (wrap it in a function) in my personal camera and I regret it a bit. Not "pretty"! I have also a viewport mini-lib that actually uses viewport:switch("name") and viewport:close() and I think I will put a similar system in my camera.

About this kikito's library (I remember previous one) have nice extra features. When I did mine one of the missing features in almost Love cameras was not have a "window" feature.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

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

Post by kikito »

Roland_Yonaba wrote:Great job here. :awesome:
A question, though. Not to debate, but I am just wondering why the drawing operations should oblige the user to wrap things in a function ?
Maybe you could have a gamera:set() (where you push, translate, rotate then a gamera:unset() where you pop graphics, and then drawing operations should be made between those two methods.
Let me start by saying that in the past I used to think similarly. In fact, the first camera system I ever implemented used set/unset methods.

But nowadays I don't think having two separate methods is advantageous in any way. I see only disadvantages.

Using set/unset methods makes it very easy to forget the "unset" part. I keep forgetting about love.graphics.pop, for example. Requiring a function rules this out, since if you forget to close it down, you get a syntax error immediately. I find that kind of "resistance to misuse" very desirable in an API.

I also think that using a function makes it more difficult "to have lots of lines between the start and the end". It "feels more wrong", than when you have set and unset. In other words, this doesn't feel too bad:

Code: Select all

function love.draw()
  cam:set()
  -- 30 lines to draw tiles
  -- 40 lines to draw player and enemies
  -- 20 lines to draw extra stuff
  cam:unset()
  -- 40 lines to draw the UI
end
But this somehow "feels worse":

Code: Select all

function love.draw()
  cam:draw(function()
    -- 30 lines to draw tiles
    -- 40 lines to draw player and enemies
    -- 20 lines to draw extra stuff
  end)
  -- 40 lines to draw the UI
end
I don't know why, but having that extra level of indentation somehow makes the code "look worse", at least to me. At the very least, there is a visual separation (an indent) between the part that is drawn by the camera and the part that isn't. But it also pushes you in the direction of splitting stuff into smaller chunks, maybe like this:

Code: Select all

function love.draw()
  cam:draw(function()
    drawTiles()
    drawEntities()
    drawExtraStuff()
  end)
  drawUI()
end
I think a code like this is preferable to the previous one, in every way. So I find it convenient that the library is pushes the user (slightly) in the right direction.
coffee wrote:Not "pretty"!
Language constructions are tools, and for tools, beauty is not an absolute thing; it's relative to the task you want to use them for. A titanium screwdriver might all shiny and have a soft designer handle, but if what I want is to drive some nails into wood, it's not good enough. I mean, I could use the driver handle to slowly hit the nails until they are in place. I'd rather use a cheap hammer.

I think a function is a better tool for this task than a couple separate methods. So I find it more beautiful.
When I write def I mean function.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

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

Post by bartbes »

I'd like to note, though, that it is easier to construct this syntax from set/unset than the other way around. (As you'll need coroutines, and even then it's a bit.. odd.) Maybe have them both?
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

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

Post by kikito »

bartbes wrote:I'd like to note, though, that it is easier to construct this syntax from set/unset than the other way around. (As you'll need coroutines, and even then it's a bit.. odd.) Maybe have them both?
Bartbes, you know I respect you a lot. But I'm not convinced that set/unset methods are good. Not having them "easily buildable" might be considered a feature.

But I've been wrong before. If someone makes a solid argument in their favour, I will add set/unset. I could find none.
When I write def I mean function.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

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

Post by Robin »

I don't thinks he means using them as such, but rather as building blocks for other, higher level, constructs (like cam:draw). Not including cam:set/unset makes it harder to build other higher level constructs (like cam:draw) that you and I haven't thought of, but someone else will.

One could imagine a for-construct:

Code: Select all

for context in cam:context() do
   -- draw stuff
end
(I know it's crazy --- this is just an example)
You could make that with cam:set/unset, but not with cam:draw.
Help us help you: attach a .love.
User avatar
qaisjp
Party member
Posts: 490
Joined: Tue Sep 04, 2012 10:49 am
Location: United Kingdom
Contact:

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

Post by qaisjp »

Wow! Looks neat!
Lua is not an acronym.
Post Reply

Who is online

Users browsing this forum: No registered users and 50 guests