Skip to main content

window_width

Function window_width 

Source
pub fn window_width() -> f32
Examples found in repository?
examples/space_game.rs (line 161)
158    fn update(&mut self) -> bool {
159        self.pos += self.vel;
160
161        let half_w = screen_distance_to_world(window_width()) / 2.0;
162        let half_h = screen_distance_to_world(window_height()) / 2.0;
163
164        self.pos.x.abs() <= half_w && self.pos.y.abs() <= half_h
165    }
166
167    fn draw(&self) {
168        draw_circle_world(self.pos, BULLET_RADIUS, FG);
169    }
170}
171
172struct Player {
173    pos: Vec2,
174    rotation: f32,
175    health: usize,
176    last_hit: f32,
177    speed: f32,
178    angvel: f32,
179    bullets: Vec<Bullet>,
180}
181
182impl Player {
183    fn new() -> Self {
184        Self {
185            pos: Vec2::ZERO,
186            rotation: 0.0,
187            health: MAX_PLAYER_HEALTH,
188            last_hit: f32::MIN,
189            speed: 0.0,
190            angvel: 0.0,
191            bullets: vec![],
192        }
193    }
194
195    fn vel(&self) -> Vec2 {
196        self.speed * Vec2::new(self.rotation.sin(), self.rotation.cos())
197    }
198
199    fn update(&mut self) {
200        self.update_input();
201        self.update_velocities();
202        self.pos = wrap_position(self.pos, PLAYER_SIZE);
203
204        for bullet in self.bullets.iter_mut() {
205            bullet.update();
206        }
207    }
208
209    fn emit_movement_particles(&self) {
210        let batch = ParticleOneshot::builder()
211            .shape(&Circle::new(
212                Vec2::ZERO,
213                Vec2::splat(LINE_THICKNESS * 1.5),
214                FG,
215            ))
216            .end_color(RED.with_alpha(0.0))
217            .speed(self.speed * 0.8)
218            .direction(-self.rotation)
219            .direction_randomness(0.2)
220            .speed_randomness(self.speed * 0.5)
221            .lifetime(0.8)
222            .lifetime_randomness(0.4)
223            .quantity((self.speed * 5.0).max(1.0) as usize)
224            .position_randomness(Vec2::splat(PLAYER_SIZE * 0.3))
225            .build();
226        get_particles().spawn_oneshot(
227            &batch,
228            self.pos + vec2(0.0, -PLAYER_SIZE * 0.3).rotated_around_origin(-self.rotation),
229        );
230    }
231
232    fn update_input(&mut self) {
233        if action_held(UP) {
234            self.speed += PLAYER_ACCEL;
235            self.emit_movement_particles();
236
237            if once_per_n_seconds(0.1) {
238                play_sound_ex(get_sounds().engine).volume(0.1).start();
239            }
240        }
241
242        if action_held(DOWN) {
243            self.speed -= PLAYER_ACCEL;
244        }
245
246        if action_held(RIGHT) {
247            self.angvel -= PLAYER_TURN_SPEED;
248        }
249
250        if action_held(LEFT) {
251            self.angvel += PLAYER_TURN_SPEED;
252        }
253
254        if action_pressed(SHOOT) {
255            play_sound(get_sounds().shoot);
256            let tip = self.pos + vec2(0.0, PLAYER_SIZE).rotated_around_origin(-self.rotation);
257            self.bullets
258                .push(Bullet::new(tip, self.rotation, self.vel()));
259        }
260    }
261
262    fn update_velocities(&mut self) {
263        self.pos += self.vel();
264        self.rotation += self.angvel;
265
266        self.speed *= PLAYER_LIN_DECEL;
267        self.angvel *= PLAYER_ANG_DECEL;
268
269        if self.speed.abs() < 0.1 {
270            self.speed = 0.0;
271        }
272
273        if self.angvel.abs() < 0.1 {
274            self.angvel = 0.0;
275        }
276    }
277
278    fn draw(&self) {
279        for bullet in &self.bullets {
280            bullet.draw();
281        }
282
283        let c = self.pos;
284        let tip = c + vec2(0.0, PLAYER_SIZE);
285        let elbow = c + vec2(0.0, -PLAYER_SIZE * 0.5);
286        let left_wing = c + vec2(-PLAYER_SIZE, -PLAYER_SIZE);
287        let right_wing = c + vec2(PLAYER_SIZE, -PLAYER_SIZE);
288
289        let now = time();
290        let time = (now - self.last_hit) * 10.0;
291        let blink_on = time as i32 % 2 == 0;
292        let currently_invincible = now - self.last_hit < PLAYER_INVINCIBILITY_DURATION;
293        let color = if currently_invincible && blink_on {
294            FG.with_alpha(0.3)
295        } else {
296            FG
297        };
298
299        if currently_invincible && blink_on {
300            vignette_screen(RED, 0.5);
301        }
302
303        draw_circle_path_world(
304            &[tip, left_wing, elbow, right_wing, tip]
305                .map(|p| p.rotated_around_point(c, -self.rotation)),
306            LINE_THICKNESS,
307            color,
308        );
309
310        self.draw_healthbar();
311    }
312
313    fn draw_healthbar(&self) {
314        let width = PLAYER_HEALTHBAR_WIDTH / MAX_PLAYER_HEALTH as f32;
315        let height = PLAYER_HEALTHBAR_HEIGHT;
316
317        for i in 0..self.health {
318            let offset = (width + PLAYER_HEALTHBAR_PADDING) * i as f32 + PLAYER_HEALTHBAR_PADDING;
319            draw_rect(
320                vec2(offset, window_height() - height - PLAYER_HEALTHBAR_PADDING),
321                vec2(width, height),
322                FG,
323            );
324        }
325    }
326}
327
328struct Asteroid {
329    health: usize,
330    max_health: usize,
331    last_hit: f32,
332    points: Vec<Vec2>,
333    pos: Vec2,
334    velocity: Vec2,
335    rotation: f32,
336    angvel: f32,
337    radius: f32,
338}
339
340impl Asteroid {
341    fn new() -> Self {
342        let radius = rand_range(MIN_ASTEROID_RADIUS..MAX_ASTEROID_RADIUS);
343        let health = (radius / MIN_ASTEROID_RADIUS) as usize * 2;
344        let last_hit = f32::MIN;
345        let pos = rand_vec2() * BASE_WINDOW_SIZE / 2.0;
346        let velocity = rand_vec2() * MAX_ASTEROID_SPEED;
347        let rotation = rand_f32() * TAU;
348        let angvel = rand_f32() * MAX_ASTEROID_ANGVEL;
349
350        let num_points = (radius * MAX_ASTEROID_POINTS) as usize;
351        let max_offset = radius * MAX_ASTEROID_POINT_OFFSET / 2.0;
352
353        let mut points = Vec::with_capacity(num_points + 1);
354
355        for i in 0..num_points {
356            let angle = (TAU / num_points as f32) * i as f32;
357            let offset = rand_range(-max_offset..max_offset) + radius;
358            let pos = Vec2::new(0.0, offset).rotated_around_origin(angle);
359            points.push(pos);
360        }
361
362        points.push(points[0]);
363
364        Self {
365            health,
366            last_hit,
367            points,
368            pos,
369            velocity,
370            rotation,
371            angvel,
372            radius,
373            max_health: health,
374        }
375    }
376
377    fn update(&mut self) {
378        self.pos += self.velocity;
379        self.rotation += self.angvel;
380        self.pos = wrap_position(self.pos, self.radius);
381    }
382
383    fn draw(&self) {
384        let points = &self
385            .points
386            .iter()
387            .map(|p| p.rotated_around_origin(self.rotation) + self.pos)
388            .collect::<Vec<_>>();
389
390        let blinking = time() - self.last_hit < ASTEROID_BLINK_DURATION;
391        let fill = if blinking { FG } else { BG };
392
393        draw_custom_shape_world(points, fill);
394        draw_circle_path_world(points, LINE_THICKNESS, FG);
395    }
396}
397
398struct Sounds {
399    shoot: SoundRef,
400    asteroid_hit: SoundRef,
401    asteroid_death: SoundRef,
402    player_hit: SoundRef,
403    game_over: SoundRef,
404    engine: SoundRef,
405}
406
407impl Sounds {
408    fn new() -> Result<Self, SoundLoadError> {
409        Ok(Self {
410            shoot: include_sound!("../assets/sounds/Gun.wav")?,
411            asteroid_hit: include_sound!("../assets/sounds/Click.wav")?,
412            asteroid_death: include_sound!("../assets/sounds/Explosion.wav")?,
413            player_hit: include_sound!("../assets/sounds/Hurt.wav")?,
414            game_over: include_sound!("../assets/sounds/Powerdown.wav")?,
415            engine: include_sound!("../assets/sounds/Crunch.wav")?,
416        })
417    }
418}
419
420#[main("Space game")]
421fn main() -> anyhow::Result<()> {
422    storage_store_state(ParticleSystem::new());
423    storage_store_state(Sounds::new()?);
424
425    bind! {
426        UP => KeyCode::ArrowUp;
427        UP => KeyCode::KeyW;
428        DOWN => KeyCode::ArrowDown;
429        DOWN => KeyCode::KeyS;
430        LEFT => KeyCode::ArrowLeft;
431        LEFT => KeyCode::KeyA;
432        RIGHT => KeyCode::ArrowRight;
433        RIGHT => KeyCode::KeyD;
434        SHOOT => KeyCode::Space;
435    }
436
437    let mut state = State::new();
438
439    loop {
440        clear_screen(BG);
441        let scale = window_size() / BASE_WINDOW_SIZE * BASE_SCALE;
442        let scale = scale.x.min(scale.y);
443        get_camera_2d_mut().set_scale(scale);
444
445        state.update();
446
447        get_particles().update();
448        get_particles().draw_world();
449        state.draw();
450
451        if should_quit() {
452            break;
453        }
454
455        next_frame().await;
456    }
457
458    Ok(())
459}
460
461fn get_particles() -> &'static mut ParticleSystem {
462    storage_get_state_mut()
463}
464
465fn get_sounds() -> &'static Sounds {
466    storage_get_state()
467}
468
469fn spawn_hit_particles(pos: Vec2, impact_dir: Vec2) {
470    play_sound(get_sounds().asteroid_hit);
471    let batch = ParticleOneshot::builder()
472        .shape(&Circle::new(
473            Vec2::ZERO,
474            Vec2::splat(LINE_THICKNESS * 1.5),
475            FG.with_alpha(0.5),
476        ))
477        .end_color(FG.with_alpha(0.0))
478        .speed(3.0)
479        .direction(impact_dir.to_angle() + FRAC_PI_2)
480        .direction_randomness(1.5)
481        .speed_randomness(2.0)
482        .lifetime(0.4)
483        .lifetime_randomness(0.2)
484        .quantity(8)
485        .build();
486    get_particles().spawn_oneshot(&batch, pos);
487}
488
489fn spawn_death_particles(pos: Vec2, radius: f32) {
490    play_sound(get_sounds().asteroid_death);
491    let batch = ParticleOneshot::builder()
492        .shape(&Circle::new(
493            Vec2::ZERO,
494            Vec2::splat(LINE_THICKNESS * 2.0),
495            FG.with_alpha(0.7),
496        ))
497        .end_color(FG.with_alpha(0.0))
498        .speed(radius * 0.1)
499        .direction(0.0)
500        .direction_randomness(std::f32::consts::TAU)
501        .speed_randomness(radius * 0.2)
502        .lifetime(0.8)
503        .lifetime_randomness(0.4)
504        .quantity((radius * 1.5) as usize)
505        .position_randomness(Vec2::splat(radius * 0.5))
506        .build();
507    get_particles().spawn_oneshot(&batch, pos);
508}
509
510fn wrap_position(pos: Vec2, size: f32) -> Vec2 {
511    let half_w = screen_distance_to_world(window_width()) / 2.0 + size;
512    let half_h = screen_distance_to_world(window_height()) / 2.0 + size;
513
514    let x = if pos.x > half_w {
515        -half_w
516    } else if pos.x < -half_w {
517        half_w
518    } else {
519        pos.x
520    };
521
522    let y = if pos.y > half_h {
523        -half_h
524    } else if pos.y < -half_h {
525        half_h
526    } else {
527        pos.y
528    };
529
530    Vec2::new(x, y)
531}
More examples
Hide additional examples
examples/interpolation.rs (line 6)
5fn random_rect() -> Rect {
6    let sf = window_height().min(window_width());
7    let center: Vec2 = rand::<Vec2>() * sf;
8    let size: Vec2 = rand::<Vec2>() * sf;
9    let color = rand_choice(&Palette::PALETTES).v500;
10
11    Rect::from_center(center, size, color).with_rotation(rand::<f32>() * TAU)
12}
examples/custom_init.rs (line 36)
8fn main() -> anyhow::Result<()> {
9    let opts = EngineCreationOptions::builder()
10        .window_transparent(true)
11        .opengl_debug(true)
12        .dithering(false)
13        .opengl_profile(GlProfile::Core)
14        .default_magnify_filter(MagnifySamplerFilter::Nearest)
15        .log_verbosity(Verbosity::Medium)
16        .window_blur(true)
17        // .swap_interval(SwapInterval::DontWait)
18        .title("Custom init".to_string())
19        .build();
20
21    init_custom(opts)?;
22
23    let mut obj = PhysicsCircle {
24        circle: Circle {
25            center: Vec2::splat(300.0),
26            radius: Vec2::splat(100.0),
27            color: Color::RED_400,
28        },
29        velocity: vec2(100.0, 200.0),
30    };
31
32    run_async(async move {
33        loop {
34            clear_screen(Color::TRANSPARENT);
35
36            if obj.circle.center.x >= window_width() - obj.circle.radius.x
37                || obj.circle.center.x <= obj.circle.radius.x
38            {
39                obj.velocity.x = -obj.velocity.x;
40            }
41
42            if obj.circle.center.y >= window_height() - obj.circle.radius.y
43                || obj.circle.center.y <= obj.circle.radius.y
44            {
45                obj.velocity.y = -obj.velocity.y;
46            }
47
48            obj.circle.center += obj.velocity * physics_delta_time();
49            dbg!(obj.circle.center);
50
51            draw(&obj.circle);
52            draw_fps();
53
54            if should_quit() {
55                break;
56            }
57
58            next_frame().await;
59        }
60    });
61
62    Ok(())
63}