ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
camera.cpp
Go to the documentation of this file.
1
8
10
11#include <algorithm>
12#include <cmath>
13
14#include "asw/modules/random.h"
15
16namespace asw {
17
18Camera::Camera(const Vec2<float>& view_size)
19 : view_size(view_size)
20{
21}
22
23void Camera::set_view_size(const Vec2<float>& view_size)
24{
25 this->view_size = view_size;
27}
28
30{
31 this->bounds = bounds;
32 has_bounds = true;
34}
35
37{
38 has_bounds = false;
39}
40
42{
43 this->anchor = anchor;
44 has_anchor = true;
45}
46
48{
49 has_anchor = false;
50}
51
52void Camera::set_follow_speed(float speed)
53{
54 follow_speed = std::max(0.0F, speed);
55}
56
57void Camera::set_shake_decay(float decay)
58{
59 shake_decay = std::max(0.0F, decay);
60}
61
62void Camera::snap_to(const Vec2<float>& target)
63{
64 const auto point = has_anchor ? anchor : view_size / 2.0F;
65 position = target - point;
66 shake_strength = 0.0F;
67 shake_offset = Vec2<float>(0.0F, 0.0F);
69}
70
71void Camera::follow(const Vec2<float>& target, float dt)
72{
73 if (follow_speed <= 0.0F) {
74 const float strength = shake_strength;
75 snap_to(target);
76 shake_strength = strength;
77 return;
78 }
79
80 // Frame rate independent ease
81 const auto point = has_anchor ? anchor : view_size / 2.0F;
82 const float t = 1.0F - std::exp(-follow_speed * dt);
83 position += ((target - point) - position) * t;
85}
86
87void Camera::update(float dt)
88{
89 shake_strength = std::max(0.0F, shake_strength - (shake_decay * dt));
90
91 if (shake_strength > 0.0F) {
92 shake_offset = Vec2<float>(random::between(-1.0F, 1.0F), random::between(-1.0F, 1.0F))
94 } else {
95 shake_offset = Vec2<float>(0.0F, 0.0F);
96 }
97}
98
99void Camera::shake(float strength)
100{
101 shake_strength = std::max(shake_strength, strength);
102}
103
105{
106 this->position = position;
108}
109
111{
112 return position;
113}
114
116{
117 return { position + shake_offset, view_size };
118}
119
121{
122 return world - (position + shake_offset);
123}
124
126{
127 return { world_to_screen(world.position), world.size };
128}
129
131{
132 return screen + (position + shake_offset);
133}
134
136{
137 if (!has_bounds) {
138 return;
139 }
140
141 // Centre on bounds smaller than the view
142 if (bounds.size.x <= view_size.x) {
143 position.x = bounds.position.x - ((view_size.x - bounds.size.x) / 2.0F);
144 } else {
145 position.x = std::clamp(
147 }
148
149 if (bounds.size.y <= view_size.y) {
150 position.y = bounds.position.y - ((view_size.y - bounds.size.y) / 2.0F);
151 } else {
152 position.y = std::clamp(
154 }
155}
156
157} // namespace asw
2D camera for scrolling worlds
void snap_to(const Vec2< float > &target)
Move straight to a target and stop any shake.
Definition camera.cpp:62
void follow(const Vec2< float > &target, float dt)
Ease towards a target. Call once per update.
Definition camera.cpp:71
Vec2< float > shake_offset
Definition camera.h:145
Vec2< float > world_to_screen(const Vec2< float > &world) const
Convert a world position to screen space.
Definition camera.cpp:120
Camera()=default
Create a camera with no view size. Call set_view_size before use.
Quad< float > bounds
Definition camera.h:146
void set_shake_decay(float decay)
Set how quickly screen shake fades.
Definition camera.cpp:57
Vec2< float > get_position() const
Get the top left of the view in world space, without shake.
Definition camera.cpp:110
void shake(float strength)
Start a screen shake. A weaker shake does not cut short a stronger one already running.
Definition camera.cpp:99
Vec2< float > view_size
Definition camera.h:143
float follow_speed
Definition camera.h:149
bool has_bounds
Definition camera.h:147
Vec2< float > position
Definition camera.h:142
bool has_anchor
Definition camera.h:148
void set_position(const Vec2< float > &position)
Set the top left of the view in world space.
Definition camera.cpp:104
Vec2< float > screen_to_world(const Vec2< float > &screen) const
Convert a screen position, such as the mouse, to world space.
Definition camera.cpp:130
void set_follow_speed(float speed)
Set how quickly follow catches up with its target.
Definition camera.cpp:52
float shake_decay
Definition camera.h:151
void update(float dt)
Advance screen shake. Call once per update.
Definition camera.cpp:87
float shake_strength
Definition camera.h:150
void clamp_to_bounds()
Definition camera.cpp:135
void clear_bounds()
Let the view move anywhere.
Definition camera.cpp:36
void set_bounds(const Quad< float > &bounds)
Keep the view inside an area of the world. If the area is smaller than the view, the view is centred ...
Definition camera.cpp:29
Vec2< float > anchor
Definition camera.h:144
Quad< float > get_view() const
Get the visible world area, including shake.
Definition camera.cpp:115
void clear_anchor()
Keep the followed target in the middle of the view again.
Definition camera.cpp:47
void set_anchor(const Vec2< float > &anchor)
Set the point in the view where the followed target is kept. Defaults to the middle of the view.
Definition camera.cpp:41
void set_view_size(const Vec2< float > &view_size)
Set the size of the area the camera shows.
Definition camera.cpp:23
A 2D rectangle in space.
Definition geometry.h:504
Vec2< T > size
The size of the rectangle.
Definition geometry.h:728
Vec2< T > position
The position of the rectangle.
Definition geometry.h:725
A 2D vector in space.
Definition geometry.h:27
T y
The y component of the vector.
Definition geometry.h:280
T x
The x component of the vector.
Definition geometry.h:277
int between(int min, int max)
Generate a random integer between min and max.
Definition random.cpp:19
Definition camera.cpp:16
Random module for the ASW library.