-
Notifications
You must be signed in to change notification settings - Fork 5
STANNcam Instance
This creates a new stanncam
camera instance, you can use to follow a player object or other and then display it's contents to the screen.
Returns: Struct.stanncam
Argument | Type | Description |
---|---|---|
[x] | Float |
Camera's starting x positionDefault: 0 |
[y] | Float |
Camera's starting y positionDefault: 0 |
[width] | Integer |
Camera's width Default: global.game_w
|
[height] | Integer |
Camera's height Default: global.game_h
|
[surface_extra_on] | Boolean |
This will enable the camera to draw to an extra surface, allowing it to render itself recursively Default: false
|
[smooth_draw] | Boolean |
Whether the camera should move smoothly, or snap to nearest integer. If you want your display to be pixel perfect, set this to false . However, it will be a bit stuttery if the camera moves slowly due to the nature of upscaling pixels.Default: true
|
Example:
stanncam_init(320, 240, 1920, 1080);
cam1 = new stanncam(obj_player.x, obj_player.y, global.game_w, global.game_h);
cam1.follow = obj_player;
This makes a new stanncam
instance, and sets it to follow the player object.
These are all variables that you can get or set.
Variable | Type | Getter or Setter | Description |
---|---|---|---|
x | Float |
Get | Camera's x positionDefault 0 |
y | Float |
Get | Camera's y positionDefault 0 |
width | Integer |
Get | Camera's width Default global.game_w
|
height | Integer |
Get | Camera's height Default global.game_h
|
offset_x | Integer |
Get | Camera's horizontal offset Default 0 |
offset_y | Integer |
Get | Camera's vertical offset Default 0 |
follow |
Id.Instance , Asset.GMObject , noone
|
Get & Set | Instance for the camera to follow. Set to noone to stop following.Default: noone
|
spd | Float |
Get & Set | How fast the camera moves towards the follow instanceDefault: 10 |
spd_threshold | Float |
Get & Set | The minimum distance the follow target is away for the speed to be in full effectDefault: 50 |
room_constrain | Boolean |
Get & Set | Whether the camera should be constrained to the room dimensions Default: false
|
bounds_w, bounds_h |
Float |
Get & Set | Bounding box the followed object has to to leave in order for the camera to start moving Default: 20 |
bounds_dist_w, bounds_dist_h |
Float |
Get | Distance the followed object is from the bounding box edges. This is useful, for example, if you want to make the camera offset to look ahead of the player when moving horizontally |
smooth_draw | Boolean |
Get & Set | If camera movement should be smooth |
zoom_amount | Float |
Get | Current zoom amount set by .zoom(zoom_amount, duration) if duration is more than 0 you can see the value gradually increase.If .smooth_draw is turned off, you should be using .get_zoom_x and .get_zoom_y instead. To maintain pixel-perfection if you use this value to match anything |
x_frac, y_frac |
Float |
Get | When smooth_draw is on, the fractional part of the camera's x and y positions are separated. So when the camera's surface is drawn, it can be used to make stuff appear to move smoothly. If you want to draw sprites that move with the camera, and they appear stuttery, adding these values might help |
anim_curve | Asset.GMAnimCurve |
Get & Set | The animation curve used when the camera moves |
anim_curve_zoom | Asset.GMAnimCurve |
Get & Set | The animation curve used when the camera zooms in/out |
anim_curve_size | Asset.GMAnimCurve |
Get & Set | The animation curve used when the camera is resized |
anim_curve_offset | Asset.GMAnimCurve |
Get & Set | The animation curve used when the camera gets offset |
debug_draw | Boolean |
Get & Set | Draws a visual indication of the bounding box when enabled |
surface | Id.Surface |
Get | The surface the camera draws to, if you need to do something fancy you can draw it manually |
surface_extra_on | Boolean |
Get & Set | Whether the camera should draw to an extra surface, allowing it to draw itself recursively |
surface_extra | Id.Surface |
Get | If surface_extra_on is true , this surface will copy the contents from surface at the end of every frame onto itself |
paused | Boolean |
Get & Set | Whether the camera should update |
Creates an exact clone of the current stanncam
camera and returns it.
Returns: stanncam
Example:
// Creates a new camera and sets it to follow player #2
cam2 = cam1.clone();
cam2.follow = obj_player2;
This will make a clone of the first camera, and set it to follow the second player.
Moves the camera to a specific location in the room. Doesn't work if it's currently following an instance.
This uses anim_curve
for the movement, you can set this to your own animation curve.
Argument | Type | Description |
---|---|---|
x | Float |
X coordinate to move the camera to |
y | Float |
Y coordinate to move the camera to |
[duration] | Float |
Duration (in frames) it takes for the camera to move to its new position Default: 0 |
Example:
// Moves the camera to where the player clicks on screen
var _new_x = cam1.get_mouse_x();
var _new_y = cam1.get_mouse_y();
cam1.move(_new_x, _new_y, game_get_speed(gamespeed_fps) * 0.5);
Sets camera size.
Argument | Type | Description |
---|---|---|
width | Integer |
Camera width |
height | Integer |
Camera height |
[duration] | Float |
The duration (in frames) it takes for the size change to be complete Default: 0 |
This uses anim_curve_size
for the animation, you can set this to your own animation curve
Example:
// Sets both cameras to be half the games width
cam1.set_size(global.game_w * 0.5, global.game_h);
cam2.set_size(global.game_w * 0.5, global.game_h);
Displaces the camera's position with an offset amount.
Argument | Type | Description |
---|---|---|
x | Float |
Horizontal camera offset |
y | Float |
Vertical camera offset |
[duration] | Float |
The duration it takes for the camera to move to its new position (in frames) Default: 0 |
This uses anim_curve_offset
for the offsetting, you can set this with your own animation curve.
Example:
In the Step Event:
// Makes the camera look ahead in the direction the player is going
if(cam1.bounds_dist_w != 0){
if(!lookahead){
cam1.offset(60 * sign(cam1.bounds_dist_w), 0, game_get_speed(gamespeed_fps) * 0.5);
lookahead = true;
}
} else {
lookahead = false;
}
Zooms the camera in or out.
zoom 1
is default.
zoom 0.5
is zoomed in.
zoom 2
is zoomed out.
Argument | Type | Description |
---|---|---|
zoom | Float |
The new zoom level |
[duration] | Float |
The duration it takes for the zoom_amount to be changed (in frames) Default: 0 |
Example 1:
// When holding down the "O" key, the camera zooms out to reveal more of the level
if(keyboard_check_pressed(ord("O"))){
cam1.zoom(2, game_get_speed(gamespeed_fps) * 0.5);
}
if(keyboard_check_released(ord("O"))){
cam1.zoom(1, game_get_speed(gamespeed_fps) * 0.5);
}
Example 2:
// Zoom in and out using the mouse scroll wheel
var _dir = mouse_wheel_down() - mouse_wheel_up();
if(_dir != 0){
var _zoom_amount = cam1.zoom_amount;
_zoom_amount = clamp(_zoom_amount + _dir * 0.05, 0.1, 2);
cam1.zoom(_zoom_amount, 0);
}
Gets the camera's current .zoom_amount
.
The reason it is split in two separate functions is in case you have smooth_draw
turned off, then the zoom amount needs to be split in 2 axis to maintain pixel-perfection. If you exclusively have smooth_draw
turned on (which it is by default), you can easily grab the .zoom_amount
value directly.
Shakes the camera.
Argument | Type | Description |
---|---|---|
magnitude | Float |
How far (in pixels) the camera will move when shaking at max duration |
duration | Integer |
For how long (in frames) the camera will shake before standing still again |
Example:
// When the player gets hurt the camera shakes for 2 seconds
function hurt_player(damage){
obj_player.health -= damage;
cam1.shake_screen(10, game_get_speed(gamespeed_fps) * 2);
}
Sets the speed and threshold variables. You can also set either of the variables manually with no issues.
Argument | Type | Description |
---|---|---|
spd | Float |
How fast the camera can move when following an instance |
threshold | Float |
The minimum distance the follow target is away for the speed to be in full effect |
Example:
// When holding the running button the camera also goes faster
if(keyboard_check_pressed(vk_shift)){
cam1.set_speed(10, 50);
}
if(keyboard_check_released(vk_shift)){
cam1.set_speed(1, 10);
}
Get the camera's top left corner position.
If you need the middle of the camera use .x
or .y
.
Returns: Float
mouse_x
and mouse_y
do not work using STANNcam so you must use these methods instead to get the mouse position.
Gets the mouse position within the room relative to the camera.
This assumes that the camera view is drawn at the (0, 0) position with no scaling.
So if you've drawn the camera at another position you need to offset this value to match.
Returns: Float
Example:
// Moves the camera to where the player clicks on screen
var _new_x = cam1.get_mouse_x();
var _new_y = cam1.get_mouse_y();
cam1.move(_new_x, _new_y, game_get_speed(gamespeed_fps) * 0.5);
Returns where the specified position in the room would be on the GUI relative to the camera.
This assumes that the camera view is drawn at the 0, 0 position with no scaling.
So if you've drawn the camera at another position you need to offset this value to match.
Returns: Float
Example:
// Draws pointer over players head on the GUI
var _arrow_x = cam1.room_to_gui_x(obj_player.x);
var _arrow_y = cam1.room_to_gui_y(obj_player.y);
draw_sprite(spr_arrow, 0, _arrow_x, _arrow_y);
Returns where the specified position in the room would be on the game window relative to the camera.
This assumes that the camera view is drawn at the 0, 0 position with no scaling.
So if you've drawn the camera at another position you need to offset this value to match.
Returns: Float
Returns whether or not the position is outside the stanncam
camera's view.
Argument | Type | Description |
---|---|---|
x | Float |
x value within room position |
y | Float |
y value within room position |
[margin] | Float |
The margin of the bounds to check Default: 0
|
Returns: Boolean
Example:
// When the player is outside the camera view,
// draw an arrow at the edges of the GUI surface pointing towards the player
if(cam1.out_of_bounds(obj_player.x, obj_player.y, 8)){
var _x = cam1.room_to_gui_x(obj_player.x);
var _y = cam1.room_to_gui_y(obj_player.y);
var _gui_scale_x = stanncam_get_gui_scale_x();
var _gui_scale_y = stanncam_get_gui_scale_y();
_x = clamp(_x, 0, cam1.width * _gui_scale_x);
_y = clamp(_y, 0, cam1.height * _gui_scale_y);
var _dir = point_direction(_x, _y, cam1.room_to_gui_x(obj_player.x), cam1.room_to_gui_y(obj_player.y));
draw_sprite_ext(spr_arrow, 0, _x, _y, 1, 1, _dir, -1, 1);
}
This function destroys the associated GameMaker camera, removes it from the manager's cameras, and frees any surfaces for that camera. The STANNcam is marked as "destroyed", but it still exists until it gets cleaned up by Garbage Collection.
Returns: Undefined
Returns whether or not the camera is marked as destroyed.
Returns: Boolean
Sets the camera paused state.
Argument | Type | Description |
---|---|---|
paused | Boolean |
Whether or not to pause the camera |
Returns: Undefined
Example:
// Toggles the game paused state and sets the stanncam camera as the same state
if(keyboard_check_pressed(vk_escape)){
global.game_paused = !global.game_paused;
cam1.set_paused(global.game_paused);
}
Gets the camera paused state.
Returns: Boolean
Example:
// Draw GUI Event
// Draw text on the screen while the stanncam camera is paused
if(cam1.get_paused()){
draw_text(global.game_w * 0.5, global.game_h * 0.5, $"Camera {cam1.cam_id} Paused");
}
Toggles the camera paused state to the opposite value.
Returns: Undefined
Example:
// Toggles both the game pause state and stanncam camera pause state
if(keyboard_check_pressed(vk_escape)){
global.game_paused = !global.game_paused;
cam1.toggle_paused();
}
Draws the camera contents to the screen, the size will match the camera's width and height.
Argument | Type | Description |
---|---|---|
x | Float |
The x position on the game's display to draw the camera's view |
y | Float |
The y position on the game's display to draw the camera's view |
[scale_x] | Float |
The horizontal scale at which the camera's view will be drawn Default: 1 |
[scale_y] | Float |
The vertical scale at which the camera's view will be drawn Default: 1 |
Example:
In the your camera object's Post-Draw Event:
cam1.draw(0, 0);
Or
cam1.draw(0, 0);
cam2.draw(global.width * 0.5, 0);
This draws 2 cameras next to each other as a vertical split-screen.
Works exactly the same as .draw
but doesn't compensate for when the window doesn't match the aspect ratio.
Image example:
Example: In the your camera object's Post-Draw Event:
//draws the camera in the top left corner of the window
//regardless of how the window is stretched
cam1.draw_no_compensate(0, 0);
This will draw a cropped version of the camera's view to the display. It works similar to GameMaker's native draw_sprite_part() function.
Argument | Type | Description |
---|---|---|
x | Integer |
x position where to draw part of the camera's view on the display |
y | Integer |
y position where to draw part of the camera's view on the display |
left | Integer |
Left position of the camera view to crop from |
top | Integer |
Top position of the camera view to crop from |
width | Integer |
Width of the camera view to draw from the left part |
height | Integer |
Height of the camera view to draw from the top part |
[scale_x] | Float |
Horizontal scale at which to draw the part of the camera's view Default: 1 |
[scale_y] | Float |
Vertical scale at which to draw the part of the camera's view Default: 1 |
Example:
In the your camera object's Post-Draw Event:
// Draw the camera contents cropped
cam1.draw(0, 0, 1, 1, 10, 10, 200, 200);
With this you can include a callback and draw anything, and still have it scaled and conform to the camera system. This could be useful if you want to draw a fancy background or foreground that conforms to the game.
Argument | Type | Description |
---|---|---|
draw_func | Function |
Function that gets called to draw to the surface |
x | Integer |
x position on the display to draw the camera's view |
y | Integer |
y position on the display to draw the camera's view |
[surf_width] | Integer |
Width of the surface Default: width , width of the camera |
[surf_height] | Integer |
Height of the surface Default: height , height of the camera |
[scale_x] | Float |
Horizontal scale to draw the camera's view Default: 1 |
[scale_y] | Float |
Vertical scale to draw the camera's view Default: 1 |
Example:
In the your camera object's Post-Draw Event:
// Background is scaled up so it appears smooth when being parallaxed
parallax_background = function(){
var _scale_x = stanncam_get_res_scale_x();
var _scale_y = stanncam_get_res_scale_y();
// Offset the camera from the middle of the room
var _offset_x = (-cam_.get_x() - cam_.__x_frac) * _scale_x;
var _pos_x = cam_.__x_frac - 200;
var _pos_y = cam_.__y_frac;
draw_sprite_ext_tiled(spr_bg_layer00, 0, _pos_x + (_offset_x * 0.0), _pos_y, 2, 1, _scale_x, _scale_y);
draw_sprite_ext_tiled(spr_bg_layer01, 0, _pos_x + (_offset_x * 0.5), _pos_y, 2, 1, _scale_x, _scale_y);
draw_sprite_ext_tiled(spr_bg_layer02, 0, _pos_x + (_offset_x * 1.0), _pos_y, 2, 1, _scale_x, _scale_y);
}
// The parallax drawing is scaled down again
var _scale_x = 1 / stanncam_get_res_scale_x();
var _scale_y = 1 / stanncam_get_res_scale_y();
// Draw a fancy parallax background before the main camera gets drawn
cam1.draw_special(parallax_background, 0, 0, global.res_w, global.res_h, _scale_x, _scale_y);
cam1.draw(0, 0);
.draw_surf(surface, x, y, [scale_x], [scale_y], [left], [top], [width], [height], [ratio_compensate])
Draws the supplied surface with the proper size and scaling.
Argument | Type | Description |
---|---|---|
surface | Id.Surface |
Surface to draw |
x | Integer |
x position on the display to draw the camera's view |
y | Integer |
y position on the display to draw the camera's view |
[scale_x] | Float |
Horizontal scale the camera's view should be drawn at Default: 1 |
[scale_y] | Float |
Vertical scale the camera's view should be drawn at Default: 1 |
[left] | Integer |
Left position of the camera view to crop from |
[top] | Integer |
Top position of the camera view to crop from |
[width] | Integer |
Width of the camera view to draw from the left part |
[height] | Integer |
Height of the camera view to draw from the top part |
[ratio_compensate] | Boolean |
Whether or not to add an offset amount to the draw position to compensate for different aspect ratios Default: true
|
Example:
In the your camera object's Post-Draw Event:
// Draw the camera, and then draw a smiley on top of it in the middle of the game window
var _bg_surf = surface_create(global.game_w, global.game_h);
surface_set_target();
draw_sprite(spr_smiley, 0, global.game_w * 0.5, global.game_h * 0.5);
surface_reset_target();
cam1.draw(0, 0);
cam1.draw_surf(_bg_surf, 0, 0);