Gamera Lua Camera Library

repository·master·Indexed 43 days ago

https://github.com/kikito/gamera

A Lua camera library providing world and window boundary configuration, zooming, rotation, and coordinate transformation between world and screen space. It features a callback-based drawing system via cam:draw that handles translation, rotation, scaling, and clipping.

Tokens
1.1K
Snippets
6
Records
8
Agent score
5%

What's inside Gamera

  1. How the camera drawing works

    master

    Gamera uses a callback-based drawing system. When you call cam:draw(callback), the library applies all transformations (translation, rotation, scaling) and clipping to everything rendered inside that callback.

    The callback provides the visible bounds (l, t, w, h), which are axis-aligned. Because the camera can rotate, these bounds might be slightly larger than the actual visible area to ensure no objects are prematurely clipped at the edges.

  2. Initialize a new gamera camera

    master

    Create a camera instance using gamera.new. You must provide four numbers defining the world boundaries: left, top, width, and height.

    Note: The left and top parameters can be negative to allow the camera to view areas outside of a 0,0 origin.

    local cam = gamera.new(0,0,2000,2000)
  3. Move, zoom, and rotate the camera

    master

    Use these methods to manipulate the camera's view:

    • cam:setPosition(x, y): Moves the camera to look at the specified coordinates. Gamera automatically clamps the position to ensure the view stays within the world boundaries.
    • cam:setScale(scale): Sets the zoom level. A scale of 1.0 is default. Increasing the value zooms in; decreasing it zooms out. Gamera prevents zooming out far enough to see world edges.
    • cam:setAngle(angle): Sets the rotation angle in radians. Note that setAngle may also adjust scale and position to prevent seeing world borders.
    cam:setPosition(100, 200)
    cam:setScale(2.0)
    cam:setAngle(math.pi / 4)
  4. Transform coordinates between World and Screen space

    master

    Gamera provides methods to convert coordinates between the game world and the screen window:

    • cam:toWorld(x, y): Converts screen coordinates (e.g., mouse position) into world coordinates. This accounts for window, scale, rotation, and translation.
    • cam:toScreen(x, y): Converts world coordinates into screen coordinates. Useful for UI elements like minimap icons.
    -- Example: Convert mouse position to world position
    local mouseX, mouseY = love.mouse.getPosition()
    local worldX, worldY = cam:toWorld(mouseX, mouseY)
  5. Query camera state and visibility

    master

    Use these methods to retrieve the current state of the camera:

    • cam:getWorld(): Returns the l,t,w,h of the world.
    • cam:getWindow(): Returns the l,t,w,h of the screen window.
    • cam:getVisible(): Returns the l,t,w,h of the currently visible area in the world (matches the parameters in the cam:draw callback).
    • cam:getVisibleCorners(): Returns the corners of the rotated rectangle representing the exact visible region as x1,y1,x2,y2,x3,y3,x4,y4.
    • cam:getPosition(): Returns the current coordinates the camera is looking at (clamped to world boundaries).
    • cam:getScale(): Returns the current scaleX and scaleY.
    • cam:getAngle(): Returns the current rotation angle in radians.
  6. Configure world and window boundaries

    master

    You can modify the camera's boundaries after initialization using the following methods:

    • cam:setWorld(left, top, width, height): Updates the boundaries of the game world.
    • cam:setWindow(left, top, width, height): Restricts the portion of the screen used to display graphics (by default, the whole screen is used).
    cam:setWorld(0,0,2000,2000)
    cam:setWindow(0,0,800,600)
  7. Draw objects using the camera

    master

    To draw objects that are affected by the camera's transformations (scale, rotation, translation, and clipping), pass a callback function to cam:draw.

    The callback function receives four optional parameters: l, t, w, h, representing the axis-aligned area currently visible in the world. You can use these parameters to optimize rendering by skipping objects outside this area.

    local function drawCameraStuff(l,t,w,h)
      -- draw stuff that will be affected by the camera
      drawBackground(l,t,w,h)
      drawTiles(l,t,w,h)
      drawEntities(l,t,w,h)
    end
    
    -- In your update/draw loop:
    cam:draw(drawCameraStuff)