/Brady

A camera library with parallax scrolling and aspect ratios for LÖVE.

Primary LanguageLua

Brady

Brady is a camera library for LOVE that features parallax scrolling and aspect ratios.

Minimal Example

Below is a minimal example of using the module. In the repository, you will find a more advanced example/demo here

local Camera = require 'Camera'

function love.load()
	-- Create a camera with a 'width' of 400 x 300 on screen at ( 32, 32 ).
	-- Because the camera has the flags 'resizable' and 'maintainAspectRatio', the default scaling will take over
	-- So everything drawn will be scaled up to maximize space within the window, with a 32 pixel buffer from each edge.
	cam = Camera( 400, 300, { x = 32, y = 32, resizable = true, maintainAspectRatio = true } )
end

function love.update( dt )
	cam:update() -- Needed to appropriately resize the camera
end

function love.draw()
	cam:push()
		-- By default, translation is half camera width, half camera height
		-- So this draws a rectangle at the center of the screen.
		love.graphics.rectangle( 'fill', -32, -32, 64, 64 )
	cam:pop()
end

Demo

Within the repo is a demo to show off some of the capabilities. To run, follow the instructions found here. In the demo, the left box shows a close-up view, the right box shows an overview. Use the mouse to create squares using either box. With the mousewheel you can zoom in and out and you can move around using the wasd keys and rotate with q and e. To reset the view, press o (for origin). To clear the squares, press c, and to reset everything, press r.

Gotchas

  • Every camera has a layer called 'main' automatically created. This layer has the same scale as the camera and is used simply to distinguish the layers.
  • Layers can have an attribute known as the "relativeScale". This value is used to control how fast the layer moves, relative to its scale. For instance, if the layer has a scale of 2 and a relativeScale of .5, it will move at the same speed as the main layer, but will appear twice as large. See cam:addLayer for more.
  • cam.scale is a number, not a function. Use cam:scaleBy instead.

Functions

Camera.newCamera

Creates a new camera object.

Synopsis: cam = Camera.newCamera( w, h, flags ) or cam = Camera( w, h, flags )

  • cam: Table. A new camera object.

  • w, h: Numbers. The width/height of the camera. If the flags resizable and maintainAspectRatio are set, these are used to determine the scaling needed. Otherwise, it sets the camera to this size.

  • flags: Table. These allow you to set some of the options of the camera without using getter/setter methods. Possible flags are:

    • x, y: Numbers (Default to 0, 0). The position of the camera on the screen.
    • translationX, translationY: Numbers (Defaults to 0, 0). The translation of the camera.
    • offsetX, offsetY: Numbers (Default to w / 2, h / 2). The amount to offset the camera.
    • scale: Number (Defaults to 1). The scale of the camera.
    • rotation: Number (Defaults to 0). The rotation of the camera.
    • resizable: Boolean (Defaults to false). true if the camera can be resized, false if it cannot.
    • maintainAspectRatio: Boolean (Defaults to false). true if the initial aspect ratio should be maintained, false if it shouldn't.
    • center: Boolean (Defaults to false). true if offsets should be centered on a screen, false if it shouldn't.
    • mode: String (Defaults to 'transform'). The StackType to use for pushing and poping the camera.
    • update: Function. The function called every frame used to control scaling and size. By default, if the camera is resizable, the resizing function is called, passing itself and the results of cam:getContainerDimensions.
    • resizingFunction: Function. Only called if the resizable flag is true. Used to set the width and height of the camera, as well as any other changes due to resizing. By default, the function changes the aspectRatioScale, offsetX and offsetY, w, and h of the camera and takes the parameters self, containerW, and containerH.
    • getContainerDimensions: Function. By default, it returns the width and height of the screen.

cam:push

Prepare the draw area. Pseudonym for layer:push.

Synopsis: cam:push( layer )

  • layer: nil, String, or table (Defaults to 'main', a layer that is automatically created). The name of the layer (as specified in cam:addLayer) or the layer, as returned by cam:addLayer.

cam:pop

Used to stop the camera scaling, etc. Pseudonym for layer:pop.

Synopsis: cam:pop( layer )

  • layer: nil, String, or table. See cam:push for a detailed description of the layer. By default, this is just the same as calling love.graphics.pop, so specifying the layer isn't required unless you want to for stylistic reasons.

cam:getWorldCoordinates

Returns the position within the "world," i.e. what the camera is seeing. Translates mouse coordinates to in-game coordinates.

Synopsis: worldX, worldY = cam:getWorldCoordinates( screenX, screenY )

  • worldX, worldY: Numbers. The word-coordinates of the mouse.
  • screenX, screenY: Numbers. The coordinates on-screen, i.e. the mouse usually.

cam:getScreenCoordinates

Translates in-game coordinates to the screen. The opposite of cam:getWorldCoordinates.

Synopsis: screenX, screenY = cam:getWorldCoordinates( worldX, worldY )

  • screenX, screenY: Numbers. The coordinates on-screen, i.e. the mouse usually.
  • worldX, worldY: Numbers. The word-coordinates of the mouse.

cam:getMouseWorldCoordinates

Short for cam:getScreenCoordinates( love.mouse.getPosition() ). See cam:getScreenCoordinates for more.

Synopsis: screenX, screenY = cam:getMouseWorldCoordinates( layer )

  • screenX, screenY: Numbers. The coordinates on-screen, i.e. the mouse usually.
  • layer: nil, String, or table. See cam:push for a detailed description of the layer. If nil, the main layer is used.

cam:setViewportPosition

Set the x and y position of the camera's upper-left corner on-screen. Wrapper function for cam.x, cam.y = -- etc.

Synopsis: cam:setViewportPosition( x, y )

  • x, y: Numbers. The upper-left corner of the camera.

cam:getViewportPosition

Returns the upper-left x and y position of the camera.

Synopsis: x, y = cam:getViewportPosition()

  • x, y: Numbers. The upper-left corner of the camera.

cam:setOffset

Sets the camera's offset, which, by default, is w / 2 and h / 2.

Synopsis: cam:setOffset( x, y )

  • x, y: Numbers. The x and y offset for the camera.

cam:setTranslation

Gets the camera's offset.

Synopsis: x, y = cam:getOffset()

  • x, y: Numbers. The x and y offset of the camera.

cam:getTranslation

cam:increaseTranslation

Get/set/increase the translation.

cam:translate

Synonymous with cam:increaseTranslation

cam:setRotation

cam:getRotation

cam:increaseRotation

Get/set/increase the rotation.

cam:rotate

Synonymous with cam:increaseRotation

cam:setScale

cam:getScale

cam:increaseScale

Get/set/increase the scale.

cam:scaleBy

Increase the scale by a factor.

Synopsis: cam:scaleBy( factor )

  • factor: Number. Multiply the scale by this amount. e.g. if the scale is .5 and you scaleBy 2, the scale is now 1.

cam:increaseScaleToPoint

Increment the scale, while zooming in to a point

Synopsis: cam:increaseScaleToPoint( ds, wx, wy )

  • ds: Number. The amount by which to increment the scale. I.e. if scale is 1 and ds is .1, then new scale is 1.1.
  • wx, wy: nil or Numbers. The world coordinates to zoom into. If left nil, defaults to cam:getMouseWorldCoordinates().

cam:scaleToPoint

Increase the scale by a factor, while zooming to a point

Synopsis: cam:scaleToPoint( s, wx, wy )

  • s: Number. The factor by which to increase the scale. I.e. if scale is 1 and s is 2, the new scale is 2.
  • wx, wy: nil or Numbers. The world coordinates to zoom into. If left nil, defaults to cam:getMouseWorldCoordinates().

cam:getLayer

Get the specified layer.

Synopsis: layer = cam:getLayer( target )

  • target: Table or String. Get the specified layer. If a table is passed, the table is returned. If a string is passed, the layer of the specified name is returned.
  • layer: Table or nil. The specified layer, or nil if the specified layer does not exist.

cam:addLayer

Create a new layer for the camera.

Synopsis: layer = cam:addLayer( name, scale, flags )

  • name: String. The name used to identify the layer.

  • scale: Number. The scale of the layer.

  • flags: Table. These allow you to specify values for the layer. Possible flags are:

    • relativeScale: Number (Defaults to 1). The relative scale of the layer. This does not affect the scale in any way; this controls how much the layer is translated. For instance, a layer with a scale of 2 and a relative scale of .5 moves at the same speed as the main layer, it is just twice the size.
    • mode: String (Defaults to cam.mode). The StackType of the layer.

layer:push

Prepare for the layer's translations.

Synopsis: layer:push()

layer:pop

Ends the layer's translations. By default, it's only [love.graphics.pop].

Synopsis: layer:pop()

License

This is under the MIT license, which can be found at the top of camera.lua