Skip to content

rgrams/lovercam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 

Repository files navigation

Lovercam

A camera library for Löve. Pretty complete, but not thoroughly battle-tested.

Feature List

  • Window resize handling - with four scale modes:
    • Expand View
    • Fixed Area
    • Fixed Width
    • Fixed Height
  • Initial View Area
  • Fixed Aspect Ratio (black bars)
    • Customizable black bar alignment
  • Switch Between Multiple Cameras
  • Zoom
  • Shake
    • Regular
    • With Rotation
    • Perlin
    • Linear or Quadratic Falloff
  • Recoil
  • Smoothed Following
  • Weighted Multi-Following
  • Follow Deadzones
  • Screen-to-World transform
  • World-to-Screen transform
  • Camera Bounds

To Do (maybe):

  • Split-Screen / Custom Scissor Support - draw from multiple cameras
    • Locked integer pixel ratios (may have border on all sides)
  • Zoom to Point
  • Multi-Follow Zoom (?)

Basic Usage

Make a new camera object. Use M.apply_transform() and M.reset_transform() to push and pop the current camera's view transform from Löve's rendering transform stack. Call M.window_resized() in love.resize() so your cameras zoom correctly when the window changes. Make sure to call M.update() in love.update() (or update cameras one-by-one if you want) if you are doing any shake, recoil, or following. Set a camera's pos (x and y) to move it around, and call functions on it to make it do other stuff.

Constructor

M.new([x], [y], [angle], [zoom_or_area], [scale_mode], [fixed_aspect_ratio], [inactive])

Creates a new camera object. If not inactive, the current camera (at M.cur_cam) will be set to this one.

PARAMETERS

  • x, y number - optional - Initial x and y position of the camera. Defaults to 0, 0.
  • angle number - optional - Initial rotation of the camera. Defaults to 0.
  • zoom_or_area number | table | vector2 - optional - Either the initial zoom or the initial view area of the camera. Pass in a number, and it will be used as a zoom value. Pass in a table or vector type (anything with x, y, w, h, or [1], [2] fields), and it will be used as a view area width and height, and the camera's zoom will be calculated based on this. The actual area rendered may not match this exactly, it depends on your window proportion and any fixed aspect ratio you have set. The necessary adjustments will be made based on the camera's scale mode. ("expand view" cameras will still zoom, based on a "fixed area" calculation). Defaults to 1.
  • scale_mode string - optional - The camera's scale mode, which determines how it handles window resizing. Must be one of the following: (Defaults to "fixed area")
    • "expand view" - How Löve works normally---zoom doesn't change---if the window is made larger a larger area is rendered, and vice versa.
    • "fixed area" - Lovercam's default (because it's the best). The camera zooms in or out to show the same area of game world, regardless of window size and proportion.
    • "fixed width" - The camera zooms to show the same horizontal amount of world. The top and bottom will be cropped or expanded depending on the window proportion.
    • "fixed height" - The camera zooms to show the same vertical amount of space. The sides will be cropped or expanded depending on the window proportion.
  • fixed_aspect_ratio number optional - The aspect ratio that the viewport will be fixed to (if specified). If you pass in a value here, the camera will crop the area that it draws to as necessary maintain this aspect ratio. It will either crop the top and bottom, or left and right, depending on the aspect ratio and your window proportion. The cropping is applied and removed along with the camera's transform (with apply_transform and reset_transform). Defaults to nil (no aspect ratio enforced).
  • inactive bool optional - If the camera should be inactive when initialized. This just means the camera won't be set as the active camera. Defaults to false (i.e. active).

RETURNS

  • t table - The camera object table.

Update Functions

M.window_resized(w, h)

Updates all cameras for the new window size. This may alter the zoom of your cameras, depending on their scale mode. ("expand view" mode cameras keep the same zoom.)

PARAMETERS

  • w number - The new width of the window.
  • h number - The new height of the window.

M.update(dt)

Runs the update functions of all cameras. This will step forward all time-related features: following, shake, & recoil, and enforce camera bounds. For finer control you can use M.update_current() to only update the currently active camera, or directly call the update function of any camera you have a reference to (i.e. my_camera:update(dt)).

PARAMETERS

  • dt number - Delta time for this frame

M.update_current(dt)

Runs the update function of the currently active camera only.

PARAMETERS

  • dt number - Delta time for this frame

Shortcut to Current Camera

All of the following camera functions, except update(see above) and activate, can be used as module functions, which will call them on the current active camera. This way, you generally don't need to keep track of camera object references and which one is active, except when you want to switch between multiple cameras. For example:

local Camera = require "lib.lovercam"

function love.draw()
	Camera.apply_transform() -- apply the transform of the current camera
	-- set an object's world position based on a stored mouse screen pos
	my_obj.pos.x, my_obj.pos.y = Camera.screen_to_world(mouse_sx, mouse_sy)
	my_obj:draw()
	Camera.reset_transform() -- reset the transform of the current camera
	-- draw GUI stuff
end

Of course, if you want more control, you are free to call functions on specific camera objects that you choose.

Camera Functions

cam:update(dt)

Updates the camera follow, shake, recoil, and bounds.

PARAMETERS

  • dt number - Delta time for this frame

cam:apply_transform()

Adds this camera's view transform (position, rotation, and zoom) to Löve's render transform stack.

cam:reset_transform()

Resets to the last render transform (love.graphics.pop())

cam:activate()

Activates/switches to this camera.

cam:screen_to_world(x, y, [delta])

Transforms x and y from screen coordinates to world coordinates based on this camera's position, rotation, and zoom.

PARAMETERS

  • x number - The screen x coordinate to transform.
  • y number - The screen y coordinate to transform.
  • delta bool - optional If the coordinates are for a change in position (or size), rather than an absolute position. Defaults to false.

RETURNS

  • x number - The corresponding world x coordinate.
  • y number - The corresponding world y coordinate.

cam:world_to_screen(x, y, [delta])

Transform x and x from world coordinates to screen coordinates based on this camera's position, rotation, and zoom.

PARAMETERS

  • x number - The world x coordinate to transform.
  • y number - The world y coordinate to transform.
  • delta bool - optional If the coordinates are for a change in position (or size), rather than an absolute position. Defaults to false.

RETURNS

  • x number - The corresponding screen x coordinate.
  • y number - The corresponding screen y coordinate.

cam:pan(dx, dy)

Moves this camera's position by (dx, dy). This is just for convenience, you can also move the camera around by setting its pos property (pos.x and pos.y).

PARAMETERS

  • x number - The change in x to apply to the camera's position.
  • y number - The change in y to apply to the camera's position.

cam:zoom(z)

A convenience function to zoom the camera in or out by a percentage. Just sets the camera's zoom property to zoom * (1 + z).

PARAMETERS

  • z number - The percent of the current zoom value to add or subtract.

cam:shake(dist, duration, [falloff])

Adds a shake to the camera. The shake will last for duration seconds, randomly offsetting the camera's position every frame by a maximum distance of +/-dist, and optionally rotating it as well. The shake effect will falloff to zero over its duration. By default it uses linear falloff. For each shake you can optionally specify the fallof function, as "linear" or "quadratic", or you can change the default by setting M.default_shake_falloff.

Use M.shake_rot_mult to globally control how strong the rotational shake effect is (in +/= radians / dist). It defaults to 0.001. Set it to zero to disable rotational shake.

PARAMETERS

  • dist number - The "intensity" of the shake. The length of the maximum offset it may apply.
  • duration number - How long the shake will last, in seconds.
  • falloff string - optional - The falloff type for the shake to use. Can be either "linear" or "quadratic". Defaults to "linear" (or M.default_shake_falloff).

cam:perlin_shake(dist, duration, [freq], [falloff])

Adds a shake to the camera that will use Perlin noise rather than normal randomness to generate the shake position (and rotation). This gives two benefits: 1) the shake will look correct if the game is run in slow-motion, and 2) you can get a slightly wider variety of effects by varying the frequency parameter. Set M.default_shake_freq to change the default frequency, or specify a custom value for each shake.

PARAMETERS

  • dist number - The "intensity" of the shake. The length of the maximum offset it may apply.
  • duration number - How long the shake will last, in seconds.
  • freq number - optional - The frequency of the shake. This defaults to 8, which will look pretty similar to a regular shake. You can set it lower to get a slower, gentler shake, like a handheld camera effect.
  • falloff string - optional - The falloff type for the shake to use. Can be either "linear" or "quadratic". Defaults to "linear" (or M.default_shake_falloff).

cam:recoil(vec, duration, [falloff])

Adds a recoil to the camera. This is sort of like a shake, only it just offsets the camera by the vector you specify--smoothly falling off to (0, 0) over duration. The falloff function for each recoil can optionally be set to "linear" or "quadratic" (defaults to "quadratic"), or you can change the default by setting M.default_recoil_falloff.

PARAMETERS

  • vec table | vector - The vector of the recoil. The initial offset it applies to the camera. Must have x and y fields.
  • duration number - How long the recoil will last, in seconds.
  • falloff string - optional - The falloff type for the shake to use. Can be either "linear" or "quadratic". Defaults to "quadratic" (or M.default_recoil_falloff).

cam:stop_shaking()

Cancels all shakes and recoils on this camera.

cam:follow(obj, [allowMultiFollow], [weight], [deadzone])

Tells this camera to smoothly follow obj. This requires that obj has a property pos with x and y elements. Set the camera's follow_lerp_speed property to adjust the smoothing speed. If allowMultiFollow is true then obj will be added to a list of objects that the camera is following---the camera's lerp target will be the average position of all objects on the list. The optional weight parameter allows you to control how much each followed object influences the camera position. You might set it to, say, 1 for your character, and 0.5 for the mouse cursor for a top-down shooter. This only has an effect if the camera is following multiple objects. Call cam:follow() again with the same object to update the weight.

To set a deadzone on the camera follow (the camera won't move unless the object moves out of the deadzone), supply a table with x, y, w, and h fields. These fields should contain 0-to-1 screen percentage values that describe the deadzone rectangle. If you are using a fixed aspect ratio camera, the deadzone will be based on the viewport area, not the full window. Deadzones work per-object. If your camera is following a single object and you want to change which object that is without changing the deadzone, you can just put true for the deadzone, and the deadzone settings for the previous object will be copied and used for the new object. For this to work, allowMultiFollow must be false and the camera can't be following multiple objects.

PARAMETERS

  • obj table - The object to follow. This must be a table with a property pos that has x and y elements.
  • allowMultiFollow bool - optional - Whether to add obj to the list of objects to follow, or to replace the list with only obj. Defaults to false.
  • weight number - optional - The averaging weight for this object. This only matters if the camera is following multiple objects. Higher numbers will make the camera follow this object more closely than the other objects, and vice versa. The actual number doesn't matter, only its value relative to the weights of the other objects this camera is following. Defaults to 1.
  • deadzone table | bool - optional - The deadzone rectangle, a table with x, y, w, and h fields. (x and y of the top left corner, and width and height.) These should be 0-to-1 screen percentages. If the window changes, the deadzone rectangle will adapt to the new window/viewport size according to these percentages. You can also put true for the deadzone to copy an existing deadzone to a new object (see the description above).

cam:unfollow([obj])

Removes obj from the camera's list of followed objects. If no object is given, the camera will unfollow anything and everything it is currently following.

PARAMETERS

  • obj table - optional - The object to stop following. Leave out this argument to unfollow everything.

cam:set_bounds([lt, rt, top, bot])

Sets limits on how far the edge of the camera view can travel, in world coordinates. Call this with no arguments to remove the bounds. If the bounds are smaller than the camera view in either direction then the camera's position will be locked to the center of the bounds area in that axis.

PARAMETERS

  • lt number - The x position of the left edge of the bounds.
  • rt number - The x position of the right edge of the bounds.
  • top number - The y position of the top edge of the bounds.
  • bot number - The y position of the bottom edge of the bounds.

Camera Properties

Properties of the camera object that you may want to get or set.

pos vector2

The camera's position. Set pos.x and pos.y to move the camera around.

angle number

The camera's rotation, in radians.

zoom number

The camera's zoom. Set it higher to zoom in, or lower to zoom out.

scale_mode string

How the camera adapts when the window size is changed. See the documentation for the constructor function (near the top of the page) for a list of available options.

follow_lerp_speed number

The camera's interpolation speed, used when following objects.

About

A camera library for Löve

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages