[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.
meowman9000
Prole
Posts: 15
Joined: Thu Mar 10, 2016 3:47 pm

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

Post by meowman9000 »

I've got bump drawing the visible parts of my level, though it aint pretty. :ultrahappy:

Code: Select all

  --Create Map
 function createMap(bumpWorldRef)
  wholeMap = {}
  wholeMap[10000] = 0
	rowIndex = 0
	columnIndex = 0
	for index=1, #mymap.layers[1].data do
				if columnIndex == 40 then
						columnIndex=0
						rowIndex=rowIndex+1
				end
				local xpos = (columnIndex)*90
				local ypos = (rowIndex)*30
				
        	wholeMap[index] = {index,xpos,ypos}
        	bumpworldRef:add(index,xpos,ypos,tileWidth,tileHeight)
				columnIndex=columnIndex+1
	end
end

--draw map
function levelUpdate(bumpworldRef)
	local visibleItems, len = bumpworldRef:queryRect(0,0,800,600)
  for i=1, len do
    love.graphics.draw(tileset, Quads[mymap.layers[1].data[wholeMap[visibleItems[i]][1]]],wholeMap[visibleItems[i]][2],wholeMap[visibleItems[i]][3])
  end
I then use Gamera to split the level into two windows. Any tips on improving this mess would be a nice help.
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 - v1.0.1 is out

Post by kikito »

@endlesstravel: There are several things wrong with your code. Let me explain:
  • You are "reusing" the same camera (the variable called cam) to display two viewports. That is not a good idea. Instead, use two cameras, one called cam1 and another called cam2 (or camLeft and camRight). One will be used for the left "window" and the other for the right "window" (these are called "viewports" in gamera).
  • It seems you don't understand what the "world" is in gamera: The world is your "how many pixels does your whole level have" (with a 1:1 scale). I think in your case it is (0, 0, 1800, 800). And it should be that for both cameras, since they are on the same world. You don't need to "set it up" on every frame, just use that instead of (0,0,800,600) when creating the cameras.
  • Since your game world does not change in size while you play with it, you don't need to "reset" the world on every frame - you can leave it "fixed" when you create both cameras.
  • The same happens with the viewport and the scale. Since they don't change, you can set them once right after create the cameras. There is no need to do it on every frame.

@meowman9000:

Your life would be much easier if your tiles were organized in a two-dimensional table, instead of using a monodimensional one. I have an article which explains both of them here: https://github.com/kikito/love-tile-tut ... /0b-tables

There are several things on this line:

Code: Select all

love.graphics.draw(tileset, Quads[mymap.layers[1].data[wholeMap[visibleItems[i]][1]]],wholeMap[visibleItems[i]][2],wholeMap[visibleItems[i]][3])
  • First, you could make it easier to read (and also faster) if you used local variables for the repeated parts. wholeMap[visibleItems, is a good candidate.
  • Second, your drawing function is called levelUpdate. Yet it doesn't update anything. That's quite misleading. It also has a comment right before it which says "draw map". I strongly suggest you rename it to drawMap and remove that comment.
  • Third, the name bumpworldRef is very inconsistent. The uppercase/lowercase rule is broken (it should be bumpWorldRef, not bumpworldRef), and also you don't use "Ref" for other tables in your code, so you might as well remove that part, and leave it in bumpWorld.
  • Last, using "magical numbers" like [1], [2] and [3] makes the code less clear. If you can, organize your tables so that you use names instead - like "quadName", "x" and "y". The drawing code would look like this:


Code: Select all

function drawLevel(bumpWorld)
   local visibleItems, len = bumpWorld:queryRect(0,0,800,600)
   for i=1, len do
     local tile = wholeMap[visibleItems[i]]
     local quad = Quads[mymap.layers[1].data[tile.quadName]]
     love.graphics.draw(tileset, quad, tile.x, tile.y)
   end
 end
When I write def I mean function.
meowman9000
Prole
Posts: 15
Joined: Thu Mar 10, 2016 3:47 pm

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

Post by meowman9000 »

Thanks again for the great advice. After profiling the code it does seem like bump has a ton more overhead, but I cant seem to understand why.

Code: Select all

--Create Map
  wholeMap = {}
  wholeMap[10000] = 0
	rowIndex = 0
	columnIndex = 0
	for index=1, #mymap.layers[1].data do
				if columnIndex == 40 then
						columnIndex=0
						rowIndex=rowIndex+1
				end
				local xpos = (columnIndex)*90
				local ypos = (rowIndex)*30
				
          --love.graphics.draw(tileset, Quads[mymap.layers[1].data[index]], xpos,ypos)
        wholeMap[index] = {quadName=index,x=xpos,y=ypos}
        bumpworld:add(index,xpos,ypos,tileWidth,tileHeight)
				columnIndex=columnIndex+1
	end
end


function levelUpdate()
	local visibleItems, len = bumpworld:queryRect(0,0,800,600)
  for i=1, len do
    local tile = wholeMap[visibleItems[i]]
    local quad = Quads[mymap.layers[1].data[tile.quadName]]
    love.graphics.draw(tileset, quad, tile.x, tile.y)
  end
end
Looking at Bump.lua it should only be running a single comparison for almost every tile, I must have done something wrong.
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 - v1.0.1 is out

Post by kikito »

@meowman: No idea of why you are experiencing that. Another thing - you would be using the l,t,w,h parameters from gamera when calling queryRect, instead of 0,0,800,600
When I write def I mean function.
User avatar
endlesstravel
Prole
Posts: 12
Joined: Fri Apr 01, 2016 10:38 am

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

Post by endlesstravel »

@kikito Sorry for late to reply. I am use two camera in the game and set the world to the suit size.
Everything is ok now. It really convenience to use gamera for my game !
Thanks for your time :awesome:
- Is life always this hard,or is it just when you're a kid?
- Always like this.
Zireael
Party member
Posts: 139
Joined: Fri Sep 02, 2016 10:52 am

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

Post by Zireael »

If I want a viewport system for a 2D tile-based game, would gamera be the way to go? I'm having trouble getting the HUMP camera not to scroll my map under the HUD.
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 - v1.0.1 is out

Post by kikito »

Zireael wrote:would gamera be the way to go? I'm having trouble getting the HUMP camera not to scroll my map under the HUD.
I don't know if it is the way to go. It is a way to go. I don't believe in "a one true way" of doing things.

In your case, if you are already using hump, and assuming that you don't need any of the extra features gamera provides, then it might be better that you use hump's camera. Vrld's libraries are good. They are tested by a lot of people, and having less dependencies in your project is nice. If it doesn't work the way you expect, it is probably that you misunderstood something or wrote a typo somewhere.

EDIT: Previously I wrote "bump", when I meant "hump". Force of habit :). Fixed now.
When I write def I mean function.
Zireael
Party member
Posts: 139
Joined: Fri Sep 02, 2016 10:52 am

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

Post by Zireael »

Are you saying that vrld's libraries are better than yours? I still can't make the camera behave properly with his library, but this post isn't clear to me. How do I draw the map so that I can use gamera with my game?
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 - v1.0.1 is out

Post by kikito »

Zireael wrote:Are you saying that vrld's libraries are better than yours?
What I am saying is that they are different - not necessarily better or worse.

Last time I checked, gamera does more things than hump.camera. This can be a good or a bad thing, depending on whether you need the extra features or not. Hump.camera (usually) comes bundled inside hump, while gamera is stand-alone. You might want or not want that. It depends on your needs. No one is "better" than the other one.
Zireael wrote:I still can't make the camera behave properly with his library, but this post isn't clear to me. How do I draw the map so that I can use gamera with my game?
That post is about optimization. Let me try to explain.

Gamera (and hump.camera, as far as I know) assume that your level "doesn't move" in order to make scroll work; There is a constant system of reference which is independent of the camera - this is called "world coordinates" in gamera. These world coordinates are usually in pixels. On this system, the top-left corner of the tile on row 1, column 1 is usually at 0,0. If the tiles are 32x32, then the corner of tile to the left is at 32,0. And so on. The important thing is that, unless these tiles are moving platforms or something like that, these coordinates never change - even if they "seem to move to the right" when the camera moves to the left. No one is doing "tile.x = tile.x + speed * dt".

Instead, the camera moves its position, and then makes transformations to the graphics pipeline before things are drawn. If the camera has moved 100 pixels to the right, the tiles will look as if they have moved 100 pixels to the left (even if they have not moved at all). This way, the camera can be thought of as a rectangle which moves around in the world.

The demo on the first post illustrates this. The world gray tiles never move, even when the cameras move, following the player. It's just that gamera does clever transformations before drawing the rectangles (before entering each camera's :draw method). The "blue rectangle" visible in the demo represents "the part of the world that cam1 can see". It is a rectangle in the "world coordinates".

This means that you could draw the whole world on each frame. If you make a draw call for every tile and every object on the level inside cam:draw, it will work - but that will be very inefficient (usually, most of the tiles and most levels are not visible, so there would be lots of unnecessary draw calls).

That's what those 4 parameters in camera:draw are for. They give you a "rectangle" in your world coordinates representing the screen (or a rectangle encompassing that, if you are using rotation). You don't need to draw anything outside that rectangle, because it would fall out of the screen anyway. How you reduce the draw calls to accomodate this depends on how you represent stuff in your game. The post you mention explains how to do this "trimming" on tile-based games (I think it applies to yours). It's an ideal scenario because it is relatively easy because changing from "draw all the world" to "draw only a rectangle of the world" is easy.

EDIT: I have attached a modified demo file. On this one, both cameras (cam1 and cam2) draw the same rectangles (the ones visible for cam1). Hopefully this will help you understand how the optimization works - cam1:getVisible() returns a rectangle which can be used to limit the tiles.
Attachments
gamera-demo-optimization.love
(5.87 KiB) Downloaded 424 times
Last edited by kikito on Wed Oct 19, 2016 12:27 pm, edited 1 time in total.
When I write def I mean function.
Zireael
Party member
Posts: 139
Joined: Fri Sep 02, 2016 10:52 am

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

Post by Zireael »

I attempted to switch my game from hump camera to gamera. For some reason, this caused pink outlines around most of my actor/item tiles... (I've tried changing the filter and note this doesn't happen with hump camera and I'm not scaling or rotating) Also it's possible to walk out of the visible window. I've verified that the updateCamera function is being called (with the proper coords), so why the camera doesn't center on the player?

Also half-tiles sometimes appear even though I've set my window size parameters to 0,0, 640, 640. 640 being a multiple of 32 shouldn't cause any non-full tiles to be drawn??

Any help?
Attachments
gamera.love
(1.33 MiB) Downloaded 356 times
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 46 guests