custom_shape/
custom-shape.rs

1use sfml::{
2    graphics::{
3        Color, CustomShape, CustomShapePoints, RenderTarget, RenderWindow, Shape, Transformable,
4    },
5    system::{Clock, Vector2f},
6    window::{Event, Key, Style},
7    SfResult,
8};
9
10#[derive(Clone, Copy)]
11pub struct TriangleShape;
12
13impl CustomShapePoints for TriangleShape {
14    fn point_count(&self) -> usize {
15        3
16    }
17
18    fn point(&self, point: usize) -> Vector2f {
19        match point {
20            0 => Vector2f { x: 20., y: 580. },
21            1 => Vector2f { x: 400., y: 20. },
22            2 => Vector2f { x: 780., y: 580. },
23            p => panic!("Non-existent point: {p}"),
24        }
25    }
26}
27
28fn hue_time(t: f32) -> Color {
29    const fn lerp(from: f32, to: f32, amount: f32) -> f32 {
30        from + amount * (to - from)
31    }
32
33    let frac = t.fract();
34
35    let [r, g, b] = match (t % 6.0).floor() {
36        0.0 => [255., lerp(0., 255., frac), 0.],
37        1.0 => [lerp(255., 0., frac), 255., 0.],
38        2.0 => [0., 255., lerp(0., 255., frac)],
39        3.0 => [0., lerp(255., 0., frac), 255.],
40        4.0 => [lerp(0., 255., frac), 0., 255.],
41        _ => [255., 0., lerp(255., 0., frac)],
42    };
43    Color::rgb(r as u8, g as u8, b as u8)
44}
45
46fn main() -> SfResult<()> {
47    let mut window = RenderWindow::new(
48        (800, 600),
49        "Custom shape",
50        Style::DEFAULT,
51        &Default::default(),
52    )?;
53    let clock = Clock::start()?;
54    window.set_vertical_sync_enabled(true);
55
56    let mut shape = CustomShape::new(Box::new(TriangleShape));
57    shape.set_position((400., 300.));
58    shape.set_origin((400., 300.));
59    shape.set_outline_thickness(3.);
60
61    'mainloop: loop {
62        while let Some(event) = window.poll_event() {
63            match event {
64                Event::Closed
65                | Event::KeyPressed {
66                    code: Key::Escape, ..
67                } => break 'mainloop,
68                _ => {}
69            }
70        }
71
72        let t = clock.elapsed_time().as_seconds();
73
74        shape.set_rotation(t.sin().abs() * 360.0);
75        let scale = t.cos().abs();
76        shape.set_scale(scale);
77        shape.set_fill_color(hue_time(t));
78        shape.set_outline_color(hue_time(t / 2.0));
79        window.clear(Color::BLACK);
80        window.draw(&shape);
81        window.display();
82    }
83    Ok(())
84}