shooter_game/
shooter_game.rs1use shadowengine2d::prelude::*;
6use winit::keyboard::KeyCode;
7use shadowengine2d::ui::{SliderStyle, TextInputStyle};
8
9struct GameState {
10 score: u32,
11 player_name: String,
12 volume: f32,
13}
14
15fn main() -> EngineResult<()> {
16 App::new()
17 .set_window(WindowConfig {
18 title: "2D Shooter Example".to_string(),
19 width: 800,
20 height: 600,
21 resizable: false,
22 })
23 .add_startup_system(setup)
24 .add_system(update)
25 .add_system(ui_system)
26 .insert_resource(GameState {
27 score: 0,
28 player_name: String::from("Player"),
29 volume: 0.5,
30 })
31 .insert_resource(UiContext::default())
32 .build()
33 .run()
34}
35
36fn setup(engine: &mut Engine, resources: &mut Resources) -> EngineResult<()> {
37 let player = engine.entities.spawn()
39 .at_position(400.0, 500.0)
40 .with_colored_square(Color::BLUE, 32.0)
41 .build();
42 resources.insert(player);
43 Ok(())
44}
45
46fn update(engine: &mut Engine, resources: &mut Resources) -> EngineResult<()> {
47 let player = *resources.get::<EntityId>().unwrap();
48 let input = &engine.input;
49 let mut pos = engine.entities.get_transform(player).unwrap().position;
50 let speed = 300.0 * engine.time.delta_time();
51 if input.is_key_pressed(KeyCode::ArrowLeft) || input.is_key_pressed(KeyCode::KeyA) {
52 pos.x -= speed;
53 }
54 if input.is_key_pressed(KeyCode::ArrowRight) || input.is_key_pressed(KeyCode::KeyD) {
55 pos.x += speed;
56 }
57 if input.is_key_pressed(KeyCode::ArrowUp) || input.is_key_pressed(KeyCode::KeyW) {
58 pos.y -= speed;
59 }
60 if input.is_key_pressed(KeyCode::ArrowDown) || input.is_key_pressed(KeyCode::KeyS) {
61 pos.y += speed;
62 }
63 if let Some(transform) = engine.entities.get_transform_mut(player) {
64 transform.position = pos;
65 }
66
67 if input.is_key_just_pressed(KeyCode::Space) {
69 engine.entities.spawn()
70 .at_position(pos.x, pos.y - 20.0)
71 .with_colored_square(Color::new(1.0, 1.0, 0.0, 1.0), 8.0)
72 .with_velocity(Velocity::new(0.0, -500.0))
73 .build();
74 }
75
76 let entity_ids: Vec<_> = engine.entities.entities().to_vec();
79 let moves: Vec<_> = entity_ids.iter()
81 .filter_map(|&entity| engine.entities.get_velocity(entity).map(|vel| (entity, vel.velocity)))
82 .collect();
83 let mut to_remove = Vec::new();
85 for (entity, velocity) in moves {
86 if let Some(transform) = engine.entities.get_transform_mut(entity) {
87 transform.position.x += velocity.x * engine.time.delta_time();
88 transform.position.y += velocity.y * engine.time.delta_time();
89 if transform.position.y < -10.0 {
90 to_remove.push(entity);
91 }
92 }
93 }
94 for entity in to_remove {
95 engine.entities.remove_entity(entity);
96 }
97
98 Ok(())
101}
102
103fn ui_system(engine: &mut Engine, resources: &mut Resources) -> EngineResult<()> {
104 let (volume, player_name, score) = {
107 let state_ref = resources.get::<GameState>().unwrap();
108 (state_ref.volume, state_ref.player_name.clone(), state_ref.score)
109 };
110 let ui = resources.get_mut::<UiContext>().unwrap();
111 ui.text("Volume", Position::new(20.0, 20.0), Color::WHITE);
112 ui.slider(
113 Rect::new(100.0, 20.0, 180.0, 24.0),
114 0.0,
115 1.0,
116 volume,
117 0.01,
118 SliderStyle::default(),
119 );
120 ui.text("Name", Position::new(20.0, 60.0), Color::WHITE);
121 ui.text_input(
122 Rect::new(100.0, 60.0, 180.0, 32.0),
123 &player_name,
124 TextInputStyle::default(),
125 );
126 ui.text(format!("Score: {}", score), Position::new(20.0, 110.0), Color::WHITE);
127 Ok(())
128}