{"id":15103981,"url":"https://github.com/a327ex/stalker-x","last_synced_at":"2025-09-27T02:32:13.607Z","repository":{"id":89618889,"uuid":"111043584","full_name":"a327ex/STALKER-X","owner":"a327ex","description":"Camera module for LÖVE","archived":true,"fork":false,"pushed_at":"2019-09-01T15:39:26.000Z","size":25,"stargazers_count":276,"open_issues_count":4,"forks_count":22,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-01-17T14:35:39.405Z","etag":null,"topics":["camera","game-development","love2d","lua"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a327ex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-17T01:43:54.000Z","updated_at":"2025-01-09T02:35:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"2b83ead1-27a8-4ecc-9936-571ab70b6a59","html_url":"https://github.com/a327ex/STALKER-X","commit_stats":{"total_commits":14,"total_committers":4,"mean_commits":3.5,"dds":0.2142857142857143,"last_synced_commit":"f996317d82a955d80bd1e4472cb564c23ccbc1ee"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/a327ex/STALKER-X","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2FSTALKER-X","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2FSTALKER-X/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2FSTALKER-X/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2FSTALKER-X/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a327ex","download_url":"https://codeload.github.com/a327ex/STALKER-X/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a327ex%2FSTALKER-X/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277171586,"owners_count":25773246,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-27T02:00:08.978Z","response_time":73,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["camera","game-development","love2d","lua"],"created_at":"2024-09-25T20:00:19.255Z","updated_at":"2025-09-27T02:32:13.380Z","avatar_url":"https://github.com/a327ex.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"**STALKER-X** is a camera module for LÖVE. It provides basic functionalities that a camera should have and is inspired by \n[hump.camera](http://hump.readthedocs.io/en/latest/camera.html) and [FlxCamera](http://haxeflixel.com/demos/FlxCamera/). The goal\nis to provide enough functions that building something like [in this video](https://www.youtube.com/watch?v=aAKwZt3aXQM)\nbecomes as easy as possible.\n\n# Contents\n\n* [Quick Start](#quick-start)\n   * [Creating a camera object](#creating-a-camera-object)\n   * [Following a target](#following-a-target)\n   * [Follow lerp and lead](#follow-lerp-and-lead)\n   * [Deadzones](#deadzones)\n      * [LOCKON](#lockon)\n      * [PLATFORMER](#platformer)\n      * [TOPDOWN](#topdown)\n      * [TOPDOWN_TIGHT](#topdown_tight)\n      * [SCREEN_BY_SCREEN](#screen_by_screen)\n      * [NO_DEADZONE](#no_deadzone)\n      * [Custom Deadzones](#custom-deadzones)\n   * [Shake](#shake)\n   * [Flash](#flash)\n   * [Fade](#fade)\n* [Tips](#tips)\n   * [Pixel Camera](#pixel-camera)\n   * [Fixed Timestep](#fixed-timestep)\n* [Documentation](#documentation)\n   * [Camera](#camerax-y-w-h-scale-rotation)\n   * [update](#updatedt)\n   * [draw](#draw)\n   * [attach](#attach)\n   * [detach](#detach)\n   * [x, y](#x-y)\n   * [scale](#scale)\n   * [rotation](#rotation)\n   * [toWorldCoords](#toworldcoordsx-y)\n   * [toCameraCoords](#tocameracoordsx-y)\n   * [getMousePosition](#getmouseposition)\n   * [shake](#shakeintensity-duration-frequency-axes)\n   * [flash](#flashduration-color)\n   * [fade](#fadeduration-color)\n   * [follow](#followx-y)\n   * [setFollowStyle](#setfollowstylefollow_style)\n   * [setDeadzone](#setdeadzonex-y-w-h)\n   * [draw_deadzone](#draw_deadzone)\n   * [setFollowLerp](#setfollowlerpx-y)\n   * [setFollowLead](#setfollowleadx-y)\n   * [setBounds](#setboundsx-y-w-h)\n\n\u003cbr\u003e\n\n# Quick Start\n\nPlace the `Camera.lua` file inside your project and require it:\n\n```lua\nCamera = require 'Camera'\n```\n\n\u003cbr\u003e\n\n## Creating a camera object\n\n```lua\nfunction love.load()\n    camera = Camera()\nend\n\nfunction love.update(dt)\n    camera:update(dt)\nend\n\nfunction love.draw()\n    camera:attach()\n    -- Draw your game here\n    camera:detach()\n    camera:draw() -- Call this here if you're using camera:fade, camera:flash or debug drawing the deadzone\nend\n```\n\nYou can create multiple camera objects if needed, even though most of the time you can get away with just a single global one.\n\n\u003cbr\u003e\n\n## Following a target\n\nThe main feature of this library is the ability to follow a target. We can do that in a basic way like this:\n\n```lua\nfunction love.update(dt)\n    camera:update(dt)\n    camera:follow(player.x, player.y)\nend\n```\n\nAnd that would look like this:\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/CmGYXxW.gif\"/\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Follow lerp and lead\n\nWe can change how sticky or how ahead of the target the camera is by changing its lerp and lead variables. \nLerp is value that goes from 0 to 1. Closer to 0 means less sticky following, while closer to 1 means stickier following:\n\n```lua\nfunction love.load()\n    camera = Camera()\n    camera:setFollowLerp(0.2)\nend\n```\n\nAnd that would look like this:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/qtdTzU6.gif\"/\u003e\n\u003c/p\u003e\n\nLead is a value that goes from 0 to infinity. Closer to 0 means no look-ahead, while higher values will move the camera\nin the direction of the target's movement more. In practice good lead values will range from 2 to 10.\n\n```lua\nfunction love.load()\n    camera = Camera()\n    camera:setFollowLerp(0.2)\n    camera:setFollowLead(10)\nend\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/ZcOZ6n6.gif\"/\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Deadzones\n\nDifferent deadzones define different areas in which the camera will or will not follow the target. \nThis can be useful to create all sorts of different behaviors like the some of the ones outlined in \n[this article](https://www.gamasutra.com/blogs/ItayKeren/20150511/243083/Scroll_Back_The_Theory_and_Practice_of_Cameras_in_SideScrollers.php). All the examples below use a lerp\nvalue of 0.2 and a lead value of 0.\n\n### LOCKON\n\n```lua\nfunction love.load()\n    camera = Camera()\n    camera:setFollowStyle('LOCKON')\nend\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/9NCOySe.gif\"/\u003e\n\u003c/p\u003e\n\n### PLATFORMER\n\n```lua\nfunction love.load()\n    camera = Camera()\n    camera:setFollowStyle('PLATFORMER')\nend\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/eNny8VU.gif\"/\u003e\n\u003c/p\u003e\n\n### TOPDOWN\n\n```lua\nfunction love.load()\n    camera = Camera()\n    camera:setFollowStyle('TOPDOWN')\nend\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/eA57zFd.gif\"/\u003e\n\u003c/p\u003e\n\n### TOPDOWN_TIGHT\n\n```lua\nfunction love.load()\n    camera = Camera()\n    camera:setFollowStyle('TOPDOWN_TIGHT')\nend\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/FqiTqOM.gif\"/\u003e\n\u003c/p\u003e\n\n### SCREEN_BY_SCREEN\n\nIn this one the camera will move whenever the target reaches the edges of the screen in a screen by screen basis.\nBecause of this we need to define the width and height of our screen, which can be seen below as the 3rd and 4rd arguments\nto the `Camera` call. In most cases where the external screen size matches the internal screen size this will be done\nautomatically, but in some cases you might need to define it yourself. \n\nFor instance, if you're doing a pixel art game which has an internal resolution of `360x270`, in which you draw the entire\ngame to a canvas and then draw the canvas scaled by a factor in the end to fit the final screen size, you'd want the camera's\ninternal width/height to be the base `360x270`, and not the final `1440x1080` in case of 4x scale factor.\n\n```lua\nfunction love.load()\n    camera = Camera(200, 150, 400, 300)\n    camera:setFollowStyle('SCREEN_BY_SCREEN')\nend\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/SN1S0Jo.gif\"/\u003e\n\u003c/p\u003e\n\n### NO_DEADZONE\n\nWithout a deadzone the target will just be followed directly and without lerping or leading being applied.\nIf the lerp value is 1 and the lead value is 0 (the default values for both of those) then the camera will act\njust like in the `NO_DEADZONE` mode, even though the default mode is `LOCKON`.\n\n```lua\nfunction love.load()\n    camera = Camera()\n    camera:setFollowStyle('NO_DEADZONE')\nend\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/TBQE88l.gif\"/\u003e\n\u003c/p\u003e\n\n### Custom Deadzones\n\nCustom deadzones can be set with the `:setDeadzone(x, y, w, h)` call. Deadzones are set in camera coordinates, \nwith the top-left being `0, 0` and the bottom-right being `camera.w, camera.h`. So the following call:\n\n```lua\nfunction love.load()\n    local w, h = 400, 300\n    camera = Camera(w/2, h/2, w, h)\n    camera:setDeadzone(40, h/2 - 40, w - 80, 80)\nend\n```\n\nWill result in this:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/rDpdvRI.gif\"/\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Shake\n\n```lua\nfunction love.keypressed(key)\n    if key == 's' then\n        camera:shake(8, 1, 60)\n    end\nend\n```\n\nIn this example the camera will shake with intensity 8 and for the duration of 1 second with a frequency of 60Hz.\nThe camera implementation is based on [this tutorial](https://jonny.morrill.me/en/blog/gamedev-how-to-implement-a-camera-shake-effect/)\nwhich provides a nice additional `frequency` parameter. Higher frequency means jerkier motion, and lower frequency means\nsmoother motion.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/0GaczA3.gif\"/\u003e\n\u003c/p\u003e\n\nNote that if you have a target locked and you have `NO_DEADZONE` or a lerp of 1 set, then a screen shake won't happen\nsince the camera will be locked tightly to the target.\n\n\u003cbr\u003e\n\n## Flash\n\nThis is a good effect for when the player gets hit, lightning strikes, or similar events.\n\n```lua\nfunction love.draw()\n    camera:attach()\n    -- ...\n    camera:detach()\n    camera:draw() -- Must call this to use camera:flash!\nend\n\nfunction love.keypressed(key)\n    if key == 'f' then\n        camera:flash(0.05, {0, 0, 0, 1})\n    end\nend\n```\n\nThe example above will fill the screen with the black color for 0.05 seconds, which looks like this:\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/UkhiyzE.gif\"/\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## Fade\n\nThis is a good effect for transitions between levels.\n\n```lua\nfunction love.draw()\n    camera:attach()\n    -- ...\n    camera:detach()\n    camera:draw() -- Must call this to use camera:fade!\nend\n\nfunction love.keypressed(key)\n    if key == 'f' then\n        camera:fade(1, {0, 0, 0, 1})\n    end\n    \n    if key == 'g' then\n        camera:fade(1, {0, 0, 0, 0})\n    end\nend\n```\n\nIn the example above, when `f` is pressed the screen will be gradually filled over 1 second with the black color \nand then it will remain covered. If `g` is pressed after that then the screen will gradually go back to normal over 1 second.\nThe default color that covers the screen initially is `{0, 0, 0, 0}`. \n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/o3r2noG.gif\"/\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n# Tips\n\n## Pixel Camera\n\nAll the gifs above were created with what I call a pixel art setup. In that everything is drawn to a canvas at a base resolution\nand then that canvas is scaled to the final screen using the `nearest` filter mode. This is how a chunky pixel look can be achieved and it's generally how pixel art is scaled in games. The advantages of this method is that you only have to care\nabout a single resolution and then everything else takes care of itself. The way this setup looks like in LÖVE code could go\nsomething like this:\n\n```lua\nfunction love.load()\n    love.graphics.setDefaultFilter('nearest', 'nearest') -- scale everything with nearest neighbor\n    canvas = love.graphics.newCanvas(400, 300)\nend\n\nfunction love.draw()\n    love.graphics.setCanvas(canvas)\n    love.graphics.clear()\n    -- draw the game here\n    love.graphics.setCanvas()\n    \n    -- Draw the 400x300 canvas scaled by 2 to a 800x600 screen\n    love.graphics.setColor(1, 1, 1, 1)\n    love.graphics.setBlendMode('alpha', 'premultiplied')\n    love.graphics.draw(canvas, 0, 0, 0, 2, 2)\n    love.graphics.setBlendMode('alpha')\nend\n```\n\nAll the gifs above followed this code. It's a base resolution of `400x300` being drawn at a scale of 2 to a `800x600` screen.\n\nNow, this relates to the camera in that to make the camera work with this setup we need to tell it what's the base resolution\nwe're using. In this case it's `400x300` and so we can create the camera object specifying these values:\n\n```lua\nfunction love.load()\n    camera = Camera(200, 150, 400, 300)\n    ...\nend\n```\n\nThe third and fourth arguments of the `Camera` call are for the internal width and height of the camera, and in this case\nthey should match the base resolution. If those arguments are omitted then it will default to whatever value is returned\nby the `love.graphics.getWidth` and `love.graphics.getHeight` calls. In a pixel setup like this omitting those values is \nproblematic because then the camera would assume an internal resolution of `800x600` which would make everything not work properly.\n\n\u003cbr\u003e\n\n## Fixed Timestep\n\nIf you're using a variable timestep you might notice a jerky motion when the camera tries to follow a target tightly.\nThis can be fixed by decreasing the lerp value, or more cleanly by using a fixed timestep setup. The code below is based\non the \"Free the Physics\" section of [this article](https://gafferongames.com/post/fix_your_timestep/).\n\n```lua\n-- LÖVE 0.10.2 fixed timestep loop, Lua version\nfunction love.run()\n    if love.math then love.math.setRandomSeed(os.time()) end\n    if love.load then love.load(arg) end\n    if love.timer then love.timer.step() end\n\n    local dt = 0\n    local fixed_dt = 1/60\n    local accumulator = 0\n\n    while true do\n        if love.event then\n            love.event.pump()\n            for name, a, b, c, d, e, f in love.event.poll() do\n                if name == 'quit' then\n                    if not love.quit or not love.quit() then\n                        return a\n                    end\n                end\n                love.handlers[name](a, b, c, d, e, f)\n            end\n        end\n\n        if love.timer then\n            love.timer.step()\n            dt = love.timer.getDelta()\n        end\n\n        accumulator = accumulator + dt\n        while accumulator \u003e= fixed_dt do\n            if love.update then love.update(fixed_dt) end\n            accumulator = accumulator - fixed_dt\n        end\n\n        if love.graphics and love.graphics.isActive() then\n            love.graphics.clear(love.graphics.getBackgroundColor())\n            love.graphics.origin()\n            if love.draw then love.draw() end\n            love.graphics.present()\n        end\n\n        if love.timer then love.timer.sleep(0.0001) end\n    end\nend\n```\n\n```moonscript\n-- LÖVE 0.10.2 fixed timestep loop, MoonScript version\nlove.run = () -\u003e\n  if love.math then love.math.setRandomSeed(os.time())\n  if love.load then love.load(arg)\n  if love.timer then love.timer.step()\n\n  dt = 0\n  fixed_dt = 1/60\n  accumulator = 0\n\n  while true\n    if love.event\n      love.event.pump()\n      for name, a, b, c, d, e, f in love.event.poll() do\n        if name == \"quit\"\n          if not love.quit or not love.quit()\n            return a\n        love.handlers[name](a, b, c, d, e, f)\n\n    if love.timer\n      love.timer.step()\n      dt = love.timer.getDelta()\n\n    accumulator += dt\n    while accumulator \u003e= fixed_dt do\n      if love.update then love.update(fixed_dt)\n      accumulator -= fixed_dt\n\n    if love.graphics and love.graphics.isActive()\n      love.graphics.clear(love.graphics.getBackgroundColor())\n      love.graphics.origin()\n      if love.draw then love.draw()\n      love.graphics.present()\n\n    if love.timer then love.timer.sleep(0.0001)\n```\n\n\u003cbr\u003e\n\n# DOCUMENTATION\n\n#### `Camera(x, y, w, h, scale, rotation)`\n\nCreates a new Camera.\n\n```lua\ncamera = Camera()\n```\n\nArguments:\n\n* `x=w/2` `(number)` - The camera's x position. Defaults to `w/2`\n* `y=h/2` `(number)` - The camera's y position. Defaults to `h/2`\n* `w=love.graphics.getWidth()` `(number)` - The camera's width. Defaults to `love.graphics.getWidth()`\n* `h=love.graphics.getHeight()` `(number)` - The camera's height. Defaults to `love.graphics.getHeight()`\n* `scale=1` `(number)` - The camera's scale. Defaults to `1`\n* `rotation=0` `(number)` - The camera's rotation. Defaults to `0`\n\nReturns:\n\n* `Camera` `(table)` - the Camera object\n\n---\n\n#### `:update(dt)`\n\nUpdates the camera.\n\n```lua\ncamera:update(dt)\n```\n\nArguments:\n\n* `dt` `(number)` - The time step delta\n\n---\n\n#### `:draw()`\n\nDraws the camera, drawing the deadzone if `draw_deadzone` is `true` and also drawing the `flash` and `fade` effects.\n\n```lua\ncamera:draw()\n```\n\n---\n\n#### `:attach()`\n\nAttaches the camera, making all following draw operations be affected by the camera's translation, scale and rotation transformations.\n\n```lua\ncamera:attach()\n-- draw the game here\ncamera:detach()\n```\n\n---\n\n#### `:detach()`\n\nDetaches the camera, returning the transformation stack back to normal.\n\n```lua\ncamera:attach()\n-- draw the game here\ncamera:detach()\n```\n\n---\n\n#### `.x, .y`\n\nThe camera's position. This is the center of the camera and not its top-left position. This can be changed directly although\nif you're using the `follow` function then changing this directly might result in bugs.\n\n```lua\ncamera.x, camera.y = 0, 0\n```\n\n---\n\n#### `.scale`\n\nThe camera's scale/zoom. \n\n```lua\ncamera.scale = 2\n```\n\n---\n\n#### `.rotation`\n\nThe camera's rotation.\n\n```lua\ncamera.rotation = math.pi/8\n```\n\n---\n\n#### `:toWorldCoords(x, y)`\n\nThe same as [hump.camera:worldCoords](http://hump.readthedocs.io/en/latest/camera.html#camera:worldCoords). This takes in \na position in camera coordinates and translates it to world coordinates. An example of this is taking the position of the\nmouse and seeing where it is in the world.\n\n```lua\nmx, my = camera:toWorldCoords(love.mouse.getPosition())\n```\n\nArguments:\n\n* `x` `(number)` - The x position in camera coordinates\n* `y` `(number)` - The y position in camera coordinates\n\nReturns:\n\n* `x` `(number)` - The x position in world coordinates\n* `y` `(number)` - The y position in world coordinates\n\n---\n\n#### `:toCameraCoords(x, y)`\n\nThe same as [hump.camera:cameraCoords](http://hump.readthedocs.io/en/latest/camera.html#camera:cameraCoords). This takes in \na position in world coordinates and translates it to camera coordinates. An example of this is taking the position of the\nplayer and \n\n```lua\nplayer_x, player_y = camera:toCameraCoords(player.x, player.y)\nlove.graphics.line(player_x, player_y, love.mouse.getPosition())\n```\n\nArguments:\n\n* `x` `(number)` - The x position in world coordinates\n* `y` `(number)` - The y position in world coordinates\n\nReturns:\n\n* `x` `(number)` - The x position in camera coordinates\n* `y` `(number)` - The y position in camera coordinates\n\n---\n\n#### `:getMousePosition()`\n\nGets the position of the mouse in world coordinates. This position can also be accessed directly through `.mx, .my`.\n\n```lua\nmx, my = camera:getMousePosition()\nmx, my = camera.mx, camera.my\n```\n\nReturns:\n\n* `x` `(number)` - The x position of the mouse in world coordinates\n* `y` `(number)` - The y position of the mouse in world coordinates\n\n---\n\n#### `:shake(intensity, duration, frequency, axes)`\n\nShakes the screen with intensity for a certain duration.\n\n```lua\ncamera:shake(8, 1, 60, 'X')\n```\n\nArguments:\n\n* `intensity` `(number)` - The intensity of the shake in pixels. This will be decreased along the duration of the shake.\n* `duration=1` `(number)` - The duration of the shake in seconds. Defaults to `1`\n* `frequency=60` `(number)` - The frequency of the shake. Higher = jerkier, lower = smoother. Defaults to `60`\n* `axes='XY'` `(string)` - The axes of the shake. Can be `'X'` for horizontal, `'Y'` for vertical or `'XY'` for both. Defaults to `'XY'`\n\n---\n\n#### `:flash(duration, color)`\n\nFills the screen up with a color for a certain duration.\n\n```lua\ncamera:flash(0.05, {0, 0, 0, 1})\n```\n\nArguments:\n\n* `duration` `(number)` - The duration of the flash in seconds\n* `color={0, 0, 0, 1}` `(table[number])` - The color of the flash. Defaults to `{0, 0, 0, 1}`\n\n---\n\n#### `:fade(duration, color, action)`\n\nSlowly fills up the screen with a color along the duration.\n\n```lua\ncamera:fade(1, {0, 0, 0, 1}, function() print(1) end)\n```\n\nArguments: \n\n* `duration` `(number)` - The duration of the fade in seconds\n* `color` `(table[number])` - The target color of the fade\n* `action` `function` - An optional action that is run when the fade ends\n\n---\n\n#### `:follow(x, y)`\n\nFollow the target according to the follow style and lerp, lead values.\n\n```lua\ncamera:follow(player.x, player.y)\n```\n\nArguments:\n\n* `x` `(number)` - The x position of the target in world coordinates\n* `y` `(number)` - The y position of the target in world coordinates\n\n---\n\n#### `:setFollowStyle(follow_style)`\n\nSets the follow style to be used by `camera:follow`. Possible values are `'LOCKON'`, `'PLATFORMER'`, `'TOPDOWN'`, `'TOPDOWN_TIGHT'`, `'SCREEN_BY_SCREEN'` and `'NO_DEADZONE'`. This can also be changed directly through `.follow_style`.\n\n```lua\ncamera:setFollowStyle('LOCKON')\ncamera.follow_style = 'LOCKON'\n```\n\nArguments:\n\n* `follow_style` `(string)` - The follow style to be used\n\n---\n\n#### `:setDeadzone(x, y, w, h)`\n\nSets the deadzone directly. The follow style must be set to `nil` for this to work.\n\n```lua\ncamera:setDeadzone(0, 0, w, h)\n```\n\nArguments:\n\n* `x` `(number)` - The top-left x position of the deadzone in camera coordinates\n* `y` `(number)` - The top-left y position of the deadzone in camera coordinates\n* `w` `(number)` - The width of the deadzone\n* `h` `(number)` - The height of the deadzone\n\n---\n\n#### `.draw_deadzone`\n\nDraws the deadzone if set to true. `camera:draw()` must be called outside the `camera:attach/detach` block for it to work.\n\n```lua\ncamera.draw_deadzone = true\n```\n\n---\n\n#### `:setFollowLerp(x, y)`\n\nSets the lerp value. This can be accessed directly through `.follow_lerp_x` and `.follow_lerp_y`.\n\n```lua\ncamera:setFollowLerp(0.2)\ncamera.follow_lerp_x = 0.2\ncamera.follow_lerp_y = 0.2\n```\n\nArguments:\n\n* `x` `(number)` - The x lerp value\n* `y=x` `(number)` - The y lerp value. Defaults to the `x` value\n\n---\n\n#### `:setFollowLead(x, y)`\n\nSets the lead value. This can be accessed directly through `.follow_lead_x` and `.follow_lead_y`.\n\n```lua\ncamera:setFollowLead(10)\ncamera.follow_lead_x = 10\ncamera.follow_lead_y = 10\n```\n\nArguments:\n\n* `x` `(number)` - The x lead value\n* `y=x` `(number)` The y lead value. Defaults to the `x` value\n\n---\n\n#### `:setBounds(x, y, w, h)`\n\nSets the boundaries of the camera in world coordinates. The camera won't be able to move past those points.\n\n```lua\ncamera:setBounds(0, 0, 800, 600)\n```\n\nArguments:\n\n* `x` `(number)` - The top-left x position of the boundary\n* `y` `(number)` - The top-left y position of the boundary\n* `w` `(number)` - The width of the rectangle that defines the boundary\n* `h` `(number)` - The height of the rectangle that defines the boundary\n\n---\n\n\u003cbr\u003e\n\n# LICENSE\n\nYou can do whatever you want with this. See the license at the top of the main file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa327ex%2Fstalker-x","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa327ex%2Fstalker-x","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa327ex%2Fstalker-x/lists"}