1use macroquad::prelude::*;
2
3fn short_angle_dist(a0: f32, a1: f32) -> f32 {
4 let max = 360.0;
5 let da = (a1 - a0) % max;
6 2.0 * da % max - da
7}
8
9fn angle_lerp(a0: f32, a1: f32, t: f32) -> f32 {
10 a0 + short_angle_dist(a0, a1) * t
11}
12
13fn draw_cross(x: f32, y: f32, color: Color) {
14 let size = 0.1;
15 let thickness = 0.005;
16 draw_line(x - size, y, x + size, y, thickness, color);
17 draw_line(x, y - size, x, y + size, thickness, color);
18}
19
20#[macroquad::main("Camera")]
21async fn main() {
22 let mut target = (0., 0.);
23 let mut zoom = 1.0;
24 let mut rotation = 0.0;
25 let mut smooth_rotation: f32 = 0.0;
26 let mut offset = (0., 0.);
27
28 loop {
29 if is_key_down(KeyCode::W) {
30 target.1 -= 0.1;
31 }
32 if is_key_down(KeyCode::S) {
33 target.1 += 0.1;
34 }
35 if is_key_down(KeyCode::A) {
36 target.0 += 0.1;
37 }
38 if is_key_down(KeyCode::D) {
39 target.0 -= 0.1;
40 }
41 if is_key_down(KeyCode::Left) {
42 offset.0 -= 0.1;
43 }
44 if is_key_down(KeyCode::Right) {
45 offset.0 += 0.1;
46 }
47 if is_key_down(KeyCode::Up) {
48 offset.1 += 0.1;
49 }
50 if is_key_down(KeyCode::Down) {
51 offset.1 -= 0.1;
52 }
53 #[cfg(not(target_arch = "wasm32"))]
54 if is_key_down(KeyCode::Q) | is_key_down(KeyCode::Escape) {
55 break;
56 }
57
58 match mouse_wheel() {
59 (_x, y) if y != 0.0 => {
60 #[cfg(target_arch = "wasm32")]
62 let y = if y < 0.0 {
63 -1.0
64 } else if y > 0.0 {
65 1.0
66 } else {
67 0.0
68 };
69 if is_key_down(KeyCode::LeftControl) {
70 zoom *= 1.1f32.powf(y);
71 } else {
72 rotation += 10.0 * y;
73 rotation = match rotation {
74 angle if angle >= 360.0 => angle - 360.0,
75 angle if angle < 0.0 => angle + 360.0,
76 angle => angle,
77 }
78 }
79 }
80 _ => (),
81 }
82
83 smooth_rotation = angle_lerp(smooth_rotation, rotation, 0.1);
84
85 clear_background(LIGHTGRAY);
86
87 set_camera(&Camera2D {
88 target: vec2(target.0, target.1),
89 ..Default::default()
90 });
91 draw_cross(0., 0., RED);
92
93 set_camera(&Camera2D {
94 target: vec2(target.0, target.1),
95 rotation: smooth_rotation,
96 ..Default::default()
97 });
98 draw_cross(0., 0., GREEN);
99
100 set_camera(&Camera2D {
101 target: vec2(target.0, target.1),
102 rotation: smooth_rotation,
103 zoom: vec2(zoom, zoom * screen_width() / screen_height()),
104 ..Default::default()
105 });
106 draw_cross(0., 0., BLUE);
107
108 set_camera(&Camera2D {
109 target: vec2(target.0, target.1),
110 rotation: smooth_rotation,
111 zoom: vec2(zoom, zoom * screen_width() / screen_height()),
112 offset: vec2(offset.0, offset.1),
113 ..Default::default()
114 });
115
116 draw_line(-0.4, 0.4, -0.8, 0.9, 0.05, BLUE);
118 draw_rectangle(-0.3, 0.3, 0.2, 0.2, GREEN);
119 draw_circle(0., 0., 0.1, YELLOW);
120
121 set_default_camera();
123 draw_text(
124 format!("target (WASD keys) = ({:+.2}, {:+.2})", target.0, target.1).as_str(),
125 10.0,
126 10.0,
127 15.0,
128 BLACK,
129 );
130 draw_text(
131 format!("rotation (mouse wheel) = {rotation} degrees").as_str(),
132 10.0,
133 25.0,
134 15.0,
135 BLACK,
136 );
137 draw_text(
138 format!("zoom (ctrl + mouse wheel) = {zoom:.2}").as_str(),
139 10.0,
140 40.0,
141 15.0,
142 BLACK,
143 );
144 draw_text(
145 format!("offset (arrow keys) = ({:+.2}, {:+.2})", offset.0, offset.1).as_str(),
146 10.0,
147 55.0,
148 15.0,
149 BLACK,
150 );
151 draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
152
153 next_frame().await
154 }
155}