SMWcamera.lua
An API for implementing camera functionality resembling that of Super Mario World. Download the latest version (v1.3.2) here.
Features include:
- Leeway of free movement when changing direction - allows fine-tuning of player position
- Platform-snapping camera
- U/D/L/R camera panning
- Autoscrolling
- Camera locking (keeps camera within a player-defined "room")
Installation & Use
Place the SMWcamera.lua file in either your level's custom graphics folder for use in a level, along with a lunadll.lua file, or in the same directory as your .wld file along with a lunaworld.lua file for use throughout an entire episode. To use, insert at the top of your Lua file:
local SMWcam = API.load("SMWcamera");
Note: if you do not plan on using the autoscrolling or camera lock functionalities, it is not necessary to store the variable.
API.load("SMWcamera");
Passive Functionality
Camera Motion
When changing direction, the player is permitted a leeway before the camera refocuses on them; the leeway provided has a default width of 133.3 pixels (1/6 of the camera width).
Whilst on the ground, the API features a platform-snapping camera that will focus on the last platform the player was touching. Camera focus will also be triggered when standing or bouncing on NPCs and spikes (as Link/Sheath).
When climbing/swimming/flying/falling, etc. the camera will freely track the player until they are grounded.
UDLR Panning
After the up/down key is held for several seconds, the camera will pan in the corresponding direction, allowing you to check for hazards above or below outside of the camera's range.
By holding the Tanooki button and double-tapping the left or right arrow keys, the camera will pan horizontally. This is analogous to the function of the L and R buttons in SMW.
Autoscrolling
The following external functions are used to initiate and stop an autoscrolling camera. During autoscroll, the player is confined to the camera's boundaries, and will die if they dip lower than three blocks below the screen.
| BeginAutoScroll(scrollspeedX, scrollspeedY) | scrollspeedX | scrollspeedY |
|---|---|---|
| Initiates an autoscroll. | number
Horizontal scroll speed |
number
Vertical scroll speed |
| StopAutoScroll() | ||
|
Halts the currently running autoscroll. |
If the player warps offscreen during an autoscroll, and the autoscroll is not halted when they exit, the camera will extrapolate using the specified speeds to be as close as possible to the player's position. If the player is still offscreen, the camera will instead be centered on them.
Example
local SMWCam = API.load("SMWcamera")
local t = 0 -- Frame timer
function onTickEnd()
-- Pans the camera to the right, wobbles the camera up and down (like on an airship)
SMWCam.BeginAutoScroll(2, math.cos(t*math.pi/180))
-- Increment frame timer
t = t + 1
end
Camera Locking
The following external functions can be used to confine and release the camera.
| lock {} | |
|---|---|
|
Lock the camera within a defined boundary. |
namedargs |
| unlock() | |
|
Resets camera boundaries to the section and frees the camera. |
n/a |
The lock method takes named arguments, detailed below.
| Argument | Description | Type | Default |
|---|---|---|---|
| x | X-coordinate to lock camera, i.e. the leftmost boundary | number | Current camera x-coordinate |
| y | Y-coordinate to lock camera, i.e. the topmost boundary | number | Current camera y-coordinate |
| width | Width of the player-defined "room" to confine the camera to. | number | Default camera width = 800px |
| height | Height of the player-defined "room" to confine the camera to. | number | Default camera height = 600px |
| locktype | Defines how the camera should pan into position.
|
number | LOCKTYPE_INSTANT |
| speed | Speed at which the camera will pan into position.
If locktype is not LOCKTYPE_CONSTANT, this is unused. |
number | 10 |
| lerpfactor | Multiplier used to linearly interpolate into position.
If locktype is not LOCKTYPE_SMOOTH, this is unused. |
number | 0.15 |
| pause | Defines if physics are halted when the camera is panning. | boolean | false |
NOTE: An error will be thrown if the specified "room" extends past the section boundaries.
Example
SMWCam = API.load("SMWcamera")
function onTickEnd()
-- Create a Megaman-style room transition
left = Section.get(player.section + 1).boundary.left
mod = (player.x - left) % 800
SMWCam.lock {x = player.x - mod, locktype = LOCKTYPE_CONSTANT, speed = 8, pause = true}
end
IMPORTANT: It is recommended that functions related to camera locking and autoscrolling be placed in the onTickEnd() event, particularly if the player is expected to warp in or out of a locked boundary. This is due to the hierarchy of when the logic for SMBX is computed. The effect of not doing so is, at the very least, a single frame discrepancy where the camera will snap to the wrong position. If you're creative you can break everything (please don't).
Other Documentation
Below is the documentation for miscellaneous functions.
| activate() | Return Value |
|---|---|
|
Activates SMW camera logic. Logic is active by default. |
n/a |
| deactivate() | |
|
Deactivates SMW camera logic. |
n/a |
| isActive() | |
|
Checks if SMW camera logic is activated. |
boolean |
| isLocked() | |
|
Checks if the camera is locked within a player-defined boundary. |
boolean |
| isAutoScrolling() | |
|
Checks if the camera is currently autoscrolling. |
boolean |