1use micro_games_kit::{
2 assets::{make_directory_database, ShaderAsset},
3 config::Config,
4 context::GameContext,
5 game::{GameInstance, GameState, GameStateChange},
6 third_party::{
7 raui_core::layout::CoordsMappingScaling,
8 raui_immediate_widgets::core::{
9 text_box, Color, TextBoxFont, TextBoxHorizontalAlign, TextBoxProps,
10 TextBoxVerticalAlign,
11 },
12 spitfire_draw::{
13 sprite::{Sprite, SpriteTexture},
14 utils::{Drawable, TextureRef},
15 },
16 spitfire_glow::{
17 graphics::{CameraScaling, Shader},
18 renderer::GlowTextureFiltering,
19 },
20 spitfire_input::{
21 CardinalInputCombinator, InputActionRef, InputConsume, InputMapping, VirtualAction,
22 },
23 vek::Vec2,
24 windowing::event::VirtualKeyCode,
25 },
26 GameLauncher,
27};
28use std::error::Error;
29
30const SPEED: f32 = 100.0;
31
32#[derive(Default)]
33struct Preloader;
34
35impl GameState for Preloader {
36 fn enter(&mut self, context: GameContext) {
37 context.graphics.color = [0.2, 0.2, 0.2, 1.0];
38 context.graphics.main_camera.screen_alignment = 0.5.into();
39 context.graphics.main_camera.scaling = CameraScaling::FitVertical(500.0);
40 context.gui.coords_map_scaling = CoordsMappingScaling::FitVertical(500.0);
41
42 context
43 .assets
44 .spawn(
45 "shader://color",
46 (ShaderAsset::new(
47 Shader::COLORED_VERTEX_2D,
48 Shader::PASS_FRAGMENT,
49 ),),
50 )
51 .unwrap();
52 context
53 .assets
54 .spawn(
55 "shader://image",
56 (ShaderAsset::new(
57 Shader::TEXTURED_VERTEX_2D,
58 Shader::TEXTURED_FRAGMENT,
59 ),),
60 )
61 .unwrap();
62 context
63 .assets
64 .spawn(
65 "shader://text",
66 (ShaderAsset::new(Shader::TEXT_VERTEX, Shader::TEXT_FRAGMENT),),
67 )
68 .unwrap();
69
70 context.assets.ensure("texture://ferris.png").unwrap();
71
72 context.assets.ensure("font://roboto.ttf").unwrap();
73
74 *context.state_change = GameStateChange::Swap(Box::new(State::default()));
75 }
76}
77
78#[derive(Default)]
79struct State {
80 ferris: Sprite,
81 movement: CardinalInputCombinator,
82 exit: InputActionRef,
83}
84
85impl GameState for State {
86 fn enter(&mut self, context: GameContext) {
87 self.ferris = Sprite::single(SpriteTexture {
88 sampler: "u_image".into(),
89 texture: TextureRef::name("ferris.png"),
90 filtering: GlowTextureFiltering::Linear,
91 })
92 .pivot(0.5.into());
93
94 let move_left = InputActionRef::default();
95 let move_right = InputActionRef::default();
96 let move_up = InputActionRef::default();
97 let move_down = InputActionRef::default();
98 self.movement = CardinalInputCombinator::new(
99 move_left.clone(),
100 move_right.clone(),
101 move_up.clone(),
102 move_down.clone(),
103 );
104 context.input.push_mapping(
105 InputMapping::default()
106 .consume(InputConsume::Hit)
107 .action(
108 VirtualAction::KeyButton(VirtualKeyCode::A),
109 move_left.clone(),
110 )
111 .action(
112 VirtualAction::KeyButton(VirtualKeyCode::D),
113 move_right.clone(),
114 )
115 .action(VirtualAction::KeyButton(VirtualKeyCode::W), move_up.clone())
116 .action(
117 VirtualAction::KeyButton(VirtualKeyCode::S),
118 move_down.clone(),
119 )
120 .action(VirtualAction::KeyButton(VirtualKeyCode::Left), move_left)
121 .action(VirtualAction::KeyButton(VirtualKeyCode::Right), move_right)
122 .action(VirtualAction::KeyButton(VirtualKeyCode::Up), move_up)
123 .action(VirtualAction::KeyButton(VirtualKeyCode::Down), move_down)
124 .action(
125 VirtualAction::KeyButton(VirtualKeyCode::Escape),
126 self.exit.clone(),
127 ),
128 );
129 }
130
131 fn exit(&mut self, context: GameContext) {
132 context.input.pop_mapping();
133 }
134
135 fn fixed_update(&mut self, context: GameContext, delta_time: f32) {
136 let movement = Vec2::<f32>::from(self.movement.get());
137 self.ferris.transform.position += movement * SPEED * delta_time;
138
139 if self.exit.get().is_pressed() {
140 *context.state_change = GameStateChange::Pop;
141 }
142 }
143
144 fn draw(&mut self, context: GameContext) {
145 self.ferris.draw(context.draw, context.graphics);
146 }
147
148 fn draw_gui(&mut self, _: GameContext) {
149 text_box(TextBoxProps {
150 text: "Hello, World!".to_owned(),
151 horizontal_align: TextBoxHorizontalAlign::Center,
152 vertical_align: TextBoxVerticalAlign::Bottom,
153 font: TextBoxFont {
154 name: "roboto.ttf".to_owned(),
155 size: 50.0,
156 },
157 color: Color {
158 r: 1.0,
159 g: 1.0,
160 b: 0.0,
161 a: 1.0,
162 },
163 ..Default::default()
164 });
165 }
166}
167
168fn main() -> Result<(), Box<dyn Error>> {
169 GameLauncher::new(GameInstance::new(Preloader).setup_assets(|assets| {
170 *assets = make_directory_database("./resources/").unwrap();
171 }))
172 .title("Hello World!")
173 .config(Config::load_from_file("./resources/GameConfig.toml")?)
174 .run();
175 Ok(())
176}