pub fn get_time() -> f64Expand description
Returns elapsed wall-clock time in seconds since start
Note that as real world time progresses during computation, the value returned will change. Therefore if you want your game logic update to happen at the same in-game time for all game objects, you should call this function once save the value and reuse it throughout your code.
Examples found in repository?
examples/tree.rs (line 42)
30async fn main() {
31 let camera = Camera2D {
32 zoom: vec2(1., 1.),
33 target: vec2(0.0, 0.5),
34 ..Default::default()
35 };
36
37 set_camera(&camera);
38 loop {
39 clear_background(LIGHTGRAY);
40
41 draw_circle(0., 0., 0.03, DARKGRAY);
42 tree(unsafe { get_internal_gl().quad_gl }, get_time(), 0, 1., 0.3);
43
44 next_frame().await
45 }
46}More examples
examples/raw_miniquad.rs (line 32)
4async fn main() {
5 let stage = {
6 let InternalGlContext {
7 quad_context: ctx, ..
8 } = unsafe { get_internal_gl() };
9
10 raw_miniquad::Stage::new(ctx)
11 };
12
13 loop {
14 clear_background(LIGHTGRAY);
15
16 // Render some primitives in camera space
17
18 set_camera(&Camera2D {
19 zoom: vec2(1., screen_width() / screen_height()),
20 ..Default::default()
21 });
22 draw_line(-0.4, 0.4, -0.8, 0.9, 0.05, BLUE);
23 draw_rectangle(-0.3, 0.3, 0.2, 0.2, GREEN);
24 draw_circle(0., 0., 0.1, YELLOW);
25
26 {
27 let mut gl = unsafe { get_internal_gl() };
28
29 // Ensure that macroquad's shapes are not going to be lost
30 gl.flush();
31
32 let t = get_time();
33
34 gl.quad_context.apply_pipeline(&stage.pipeline);
35
36 gl.quad_context
37 .begin_default_pass(miniquad::PassAction::Nothing);
38 gl.quad_context.apply_bindings(&stage.bindings);
39
40 for i in 0..10 {
41 let t = t + i as f64 * 0.3;
42
43 gl.quad_context
44 .apply_uniforms(miniquad::UniformsSource::table(
45 &raw_miniquad::shader::Uniforms {
46 offset: (t.sin() as f32 * 0.5, (t * 3.).cos() as f32 * 0.5),
47 },
48 ));
49 gl.quad_context.draw(0, 6, 1);
50 }
51 gl.quad_context.end_render_pass();
52 }
53
54 // Back to screen space, render some text
55
56 set_default_camera();
57 draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
58
59 next_frame().await
60 }
61}examples/text.rs (line 35)
4async fn main() {
5 let font = load_ttf_font("./examples/DancingScriptRegular.ttf")
6 .await
7 .unwrap();
8
9 let mut angle = 0.0;
10
11 loop {
12 clear_background(BLACK);
13
14 draw_text_ex("Custom font size:", 20.0, 20.0, TextParams::default());
15 let mut y = 20.0;
16
17 for font_size in (30..100).step_by(20) {
18 let text = "abcdef";
19 let params = TextParams {
20 font_size,
21 ..Default::default()
22 };
23
24 y += font_size as f32;
25 draw_text_ex(text, 20.0, y, params);
26 }
27
28 draw_text_ex("Dynamic font scale:", 20.0, 400.0, TextParams::default());
29 draw_text_ex(
30 "abcd",
31 20.0,
32 450.0,
33 TextParams {
34 font_size: 50,
35 font_scale: get_time().sin() as f32 / 2.0 + 1.0,
36 ..Default::default()
37 },
38 );
39
40 draw_text_ex("Custom font:", 400.0, 20.0, TextParams::default());
41 draw_text_ex(
42 "abcd",
43 400.0,
44 70.0,
45 TextParams {
46 font_size: 50,
47 font: Some(&font),
48 ..Default::default()
49 },
50 );
51
52 draw_text_ex(
53 "abcd",
54 400.0,
55 160.0,
56 TextParams {
57 font_size: 100,
58 font: Some(&font),
59 ..Default::default()
60 },
61 );
62
63 draw_text_ex(
64 "abcd",
65 screen_width() / 4.0 * 2.0,
66 screen_height() / 3.0 * 2.0,
67 TextParams {
68 font_size: 70,
69 font: Some(&font),
70 rotation: angle,
71 ..Default::default()
72 },
73 );
74
75 let center = get_text_center("abcd", Option::None, 70, 1.0, angle * 2.0);
76 draw_text_ex(
77 "abcd",
78 screen_width() / 4.0 * 3.0 - center.x,
79 screen_height() / 3.0 * 2.0 - center.y,
80 TextParams {
81 font_size: 70,
82 rotation: angle * 2.0,
83 ..Default::default()
84 },
85 );
86
87 angle -= 0.030;
88
89 next_frame().await
90 }
91}examples/snake.rs (line 25)
16async fn main() {
17 let mut snake = Snake {
18 head: (0, 0),
19 dir: (1, 0),
20 body: LinkedList::new(),
21 };
22 let mut fruit: Point = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
23 let mut score = 0;
24 let mut speed = 0.3;
25 let mut last_update = get_time();
26 let mut navigation_lock = false;
27 let mut game_over = false;
28
29 let up = (0, -1);
30 let down = (0, 1);
31 let right = (1, 0);
32 let left = (-1, 0);
33
34 loop {
35 if !game_over {
36 if is_key_down(KeyCode::Right) && snake.dir != left && !navigation_lock {
37 snake.dir = right;
38 navigation_lock = true;
39 } else if is_key_down(KeyCode::Left) && snake.dir != right && !navigation_lock {
40 snake.dir = left;
41 navigation_lock = true;
42 } else if is_key_down(KeyCode::Up) && snake.dir != down && !navigation_lock {
43 snake.dir = up;
44 navigation_lock = true;
45 } else if is_key_down(KeyCode::Down) && snake.dir != up && !navigation_lock {
46 snake.dir = down;
47 navigation_lock = true;
48 }
49
50 if get_time() - last_update > speed {
51 last_update = get_time();
52 snake.body.push_front(snake.head);
53 snake.head = (snake.head.0 + snake.dir.0, snake.head.1 + snake.dir.1);
54 if snake.head == fruit {
55 fruit = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
56 score += 100;
57 speed *= 0.9;
58 } else {
59 snake.body.pop_back();
60 }
61 if snake.head.0 < 0
62 || snake.head.1 < 0
63 || snake.head.0 >= SQUARES
64 || snake.head.1 >= SQUARES
65 {
66 game_over = true;
67 }
68 for (x, y) in &snake.body {
69 if *x == snake.head.0 && *y == snake.head.1 {
70 game_over = true;
71 }
72 }
73 navigation_lock = false;
74 }
75 }
76 if !game_over {
77 clear_background(LIGHTGRAY);
78
79 let game_size = screen_width().min(screen_height());
80 let offset_x = (screen_width() - game_size) / 2. + 10.;
81 let offset_y = (screen_height() - game_size) / 2. + 10.;
82 let sq_size = (screen_height() - offset_y * 2.) / SQUARES as f32;
83
84 draw_rectangle(offset_x, offset_y, game_size - 20., game_size - 20., WHITE);
85
86 for i in 1..SQUARES {
87 draw_line(
88 offset_x,
89 offset_y + sq_size * i as f32,
90 screen_width() - offset_x,
91 offset_y + sq_size * i as f32,
92 2.,
93 LIGHTGRAY,
94 );
95 }
96
97 for i in 1..SQUARES {
98 draw_line(
99 offset_x + sq_size * i as f32,
100 offset_y,
101 offset_x + sq_size * i as f32,
102 screen_height() - offset_y,
103 2.,
104 LIGHTGRAY,
105 );
106 }
107
108 draw_rectangle(
109 offset_x + snake.head.0 as f32 * sq_size,
110 offset_y + snake.head.1 as f32 * sq_size,
111 sq_size,
112 sq_size,
113 DARKGREEN,
114 );
115
116 for (x, y) in &snake.body {
117 draw_rectangle(
118 offset_x + *x as f32 * sq_size,
119 offset_y + *y as f32 * sq_size,
120 sq_size,
121 sq_size,
122 LIME,
123 );
124 }
125
126 draw_rectangle(
127 offset_x + fruit.0 as f32 * sq_size,
128 offset_y + fruit.1 as f32 * sq_size,
129 sq_size,
130 sq_size,
131 GOLD,
132 );
133
134 draw_text(format!("SCORE: {score}").as_str(), 10., 20., 20., DARKGRAY);
135 } else {
136 clear_background(WHITE);
137 let text = "Game Over. Press [enter] to play again.";
138 let font_size = 30.;
139 let text_size = measure_text(text, None, font_size as _, 1.0);
140
141 draw_text(
142 text,
143 screen_width() / 2. - text_size.width / 2.,
144 screen_height() / 2. + text_size.height / 2.,
145 font_size,
146 DARKGRAY,
147 );
148
149 if is_key_down(KeyCode::Enter) {
150 snake = Snake {
151 head: (0, 0),
152 dir: (1, 0),
153 body: LinkedList::new(),
154 };
155 fruit = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
156 score = 0;
157 speed = 0.3;
158 last_update = get_time();
159 game_over = false;
160 }
161 }
162 next_frame().await;
163 }
164}examples/asteroids.rs (line 54)
46async fn main() {
47 let mut ship = Ship {
48 pos: Vec2::new(screen_width() / 2., screen_height() / 2.),
49 rot: 0.,
50 vel: Vec2::new(0., 0.),
51 };
52
53 let mut bullets = Vec::new();
54 let mut last_shot = get_time();
55 let mut asteroids = Vec::new();
56 let mut gameover = false;
57
58 let mut screen_center;
59
60 loop {
61 if gameover {
62 clear_background(LIGHTGRAY);
63 let mut text = "You Win!. Press [enter] to play again.";
64 let font_size = 30.;
65
66 if asteroids.len() > 0 {
67 text = "Game Over. Press [enter] to play again.";
68 }
69 let text_size = measure_text(text, None, font_size as _, 1.0);
70 draw_text(
71 text,
72 screen_width() / 2. - text_size.width / 2.,
73 screen_height() / 2. - text_size.height / 2.,
74 font_size,
75 DARKGRAY,
76 );
77 if is_key_down(KeyCode::Enter) {
78 ship = Ship {
79 pos: Vec2::new(screen_width() / 2., screen_height() / 2.),
80 rot: 0.,
81 vel: Vec2::new(0., 0.),
82 };
83 bullets = Vec::new();
84 asteroids = Vec::new();
85 gameover = false;
86 screen_center = Vec2::new(screen_width() / 2., screen_height() / 2.);
87 for _ in 0..10 {
88 asteroids.push(Asteroid {
89 pos: screen_center
90 + Vec2::new(rand::gen_range(-1., 1.), rand::gen_range(-1., 1.))
91 .normalize()
92 * screen_width().min(screen_height())
93 / 2.,
94 vel: Vec2::new(rand::gen_range(-1., 1.), rand::gen_range(-1., 1.)),
95 rot: 0.,
96 rot_speed: rand::gen_range(-2., 2.),
97 size: screen_width().min(screen_height()) / 10.,
98 sides: rand::gen_range(3, 8),
99 collided: false,
100 })
101 }
102 }
103 next_frame().await;
104 continue;
105 }
106 let frame_t = get_time();
107 let rotation = ship.rot.to_radians();
108
109 let mut acc = -ship.vel / 100.; // Friction
110
111 // Forward
112 if is_key_down(KeyCode::Up) {
113 acc = Vec2::new(rotation.sin(), -rotation.cos()) / 3.;
114 }
115
116 // Shot
117 if is_key_down(KeyCode::Space) && frame_t - last_shot > 0.5 {
118 let rot_vec = Vec2::new(rotation.sin(), -rotation.cos());
119 bullets.push(Bullet {
120 pos: ship.pos + rot_vec * SHIP_HEIGHT / 2.,
121 vel: rot_vec * 7.,
122 shot_at: frame_t,
123 collided: false,
124 });
125 last_shot = frame_t;
126 }
127
128 // Steer
129 if is_key_down(KeyCode::Right) {
130 ship.rot += 5.;
131 } else if is_key_down(KeyCode::Left) {
132 ship.rot -= 5.;
133 }
134
135 // Euler integration
136 ship.vel += acc;
137 if ship.vel.length() > 5. {
138 ship.vel = ship.vel.normalize() * 5.;
139 }
140 ship.pos += ship.vel;
141 ship.pos = wrap_around(&ship.pos);
142
143 // Move each bullet
144 for bullet in bullets.iter_mut() {
145 bullet.pos += bullet.vel;
146 }
147
148 // Move each asteroid
149 for asteroid in asteroids.iter_mut() {
150 asteroid.pos += asteroid.vel;
151 asteroid.pos = wrap_around(&asteroid.pos);
152 asteroid.rot += asteroid.rot_speed;
153 }
154
155 // Bullet lifetime
156 bullets.retain(|bullet| bullet.shot_at + 1.5 > frame_t);
157
158 let mut new_asteroids = Vec::new();
159 for asteroid in asteroids.iter_mut() {
160 // Asteroid/ship collision
161 if (asteroid.pos - ship.pos).length() < asteroid.size + SHIP_HEIGHT / 3. {
162 gameover = true;
163 break;
164 }
165
166 // Asteroid/bullet collision
167 for bullet in bullets.iter_mut() {
168 if (asteroid.pos - bullet.pos).length() < asteroid.size {
169 asteroid.collided = true;
170 bullet.collided = true;
171
172 // Break the asteroid
173 if asteroid.sides > 3 {
174 new_asteroids.push(Asteroid {
175 pos: asteroid.pos,
176 vel: Vec2::new(bullet.vel.y, -bullet.vel.x).normalize()
177 * rand::gen_range(1., 3.),
178 rot: rand::gen_range(0., 360.),
179 rot_speed: rand::gen_range(-2., 2.),
180 size: asteroid.size * 0.8,
181 sides: asteroid.sides - 1,
182 collided: false,
183 });
184 new_asteroids.push(Asteroid {
185 pos: asteroid.pos,
186 vel: Vec2::new(-bullet.vel.y, bullet.vel.x).normalize()
187 * rand::gen_range(1., 3.),
188 rot: rand::gen_range(0., 360.),
189 rot_speed: rand::gen_range(-2., 2.),
190 size: asteroid.size * 0.8,
191 sides: asteroid.sides - 1,
192 collided: false,
193 })
194 }
195 break;
196 }
197 }
198 }
199
200 // Remove the collided objects
201 bullets.retain(|bullet| bullet.shot_at + 1.5 > frame_t && !bullet.collided);
202 asteroids.retain(|asteroid| !asteroid.collided);
203 asteroids.append(&mut new_asteroids);
204
205 // You win?
206 if asteroids.len() == 0 {
207 gameover = true;
208 }
209
210 if gameover {
211 continue;
212 }
213
214 clear_background(LIGHTGRAY);
215
216 for bullet in bullets.iter() {
217 draw_circle(bullet.pos.x, bullet.pos.y, 2., BLACK);
218 }
219
220 for asteroid in asteroids.iter() {
221 draw_poly_lines(
222 asteroid.pos.x,
223 asteroid.pos.y,
224 asteroid.sides,
225 asteroid.size,
226 asteroid.rot,
227 2.,
228 BLACK,
229 )
230 }
231
232 let v1 = Vec2::new(
233 ship.pos.x + rotation.sin() * SHIP_HEIGHT / 2.,
234 ship.pos.y - rotation.cos() * SHIP_HEIGHT / 2.,
235 );
236 let v2 = Vec2::new(
237 ship.pos.x - rotation.cos() * SHIP_BASE / 2. - rotation.sin() * SHIP_HEIGHT / 2.,
238 ship.pos.y - rotation.sin() * SHIP_BASE / 2. + rotation.cos() * SHIP_HEIGHT / 2.,
239 );
240 let v3 = Vec2::new(
241 ship.pos.x + rotation.cos() * SHIP_BASE / 2. - rotation.sin() * SHIP_HEIGHT / 2.,
242 ship.pos.y + rotation.sin() * SHIP_BASE / 2. + rotation.cos() * SHIP_HEIGHT / 2.,
243 );
244 draw_triangle_lines(v1, v2, v3, 2., BLACK);
245
246 next_frame().await
247 }
248}