Skip to main content

scenes/
scenes.rs

1//! # Scenes Example
2//!
3//! Demonstrates the `Scene` trait and `SceneStack` for state management.
4//! Features modern UGUI panels and sub-pixel text.
5
6use jengine::engine::{Color, Game, jEngine, KeyCode};
7use jengine::renderer::text::Font;
8use jengine::ui::{Alignment, BorderStyle, Padding};
9use jengine::ui::modern::Panel;
10use jengine::ui::widgets::{VStack, TextWidget, Widget, Spacer};
11use jengine::scene::{Scene, SceneAction, SceneStack};
12use jengine::{DEFAULT_FONT_METADATA, DEFAULT_TILE_H, DEFAULT_TILE_W, DEFAULT_TILESET};
13
14const PANEL_BG: Color = Color([0.06, 0.09, 0.09, 1.0]);
15const BORDER:   Color = Color([0.25, 0.65, 0.50, 1.0]);
16const TEXT:     Color = Color([0.85, 0.92, 0.88, 1.0]);
17
18struct TitleScene;
19impl Scene for TitleScene {
20    fn update(&mut self, engine: &mut jEngine) -> SceneAction {
21        if engine.is_key_pressed(KeyCode::Enter) { SceneAction::Switch(Box::new(GameplayScene::new())) }
22        else if engine.is_key_pressed(KeyCode::Escape) { SceneAction::Quit }
23        else { SceneAction::None }
24    }
25    fn draw(&mut self, engine: &mut jEngine) {
26        let sw = engine.grid_width() as f32 * engine.tile_width() as f32;
27        let sh = engine.grid_height() as f32 * engine.tile_height() as f32;
28        engine.ui.ui_rect(0.0, 0.0, sw, sh, Color([0.03, 0.05, 0.05, 1.0]));
29        Panel::new(sw * 0.5 - 200.0, sh * 0.5 - 100.0, 400.0, 200.0).with_color(PANEL_BG).with_border(BORDER, 1.0).with_radius(12.0).draw(engine);
30        engine.ui.ui_text(sw * 0.5 - 60.0, sh * 0.5 - 40.0, "SCENE DEMO", TEXT, Color::TRANSPARENT, Some(24.0));
31        engine.ui.ui_text(sw * 0.5 - 80.0, sh * 0.5 + 20.0, "Press [Enter] to Start", BORDER, Color::TRANSPARENT, Some(14.0));
32    }
33}
34
35struct GameplayScene { player_pos: [f32; 2] }
36impl GameplayScene { fn new() -> Self { Self { player_pos: [400.0, 300.0] } } }
37impl Scene for GameplayScene {
38    fn update(&mut self, engine: &mut jEngine) -> SceneAction {
39        if engine.is_key_pressed(KeyCode::Escape) { return SceneAction::Push(Box::new(PauseScene)); }
40        let speed = 200.0 * engine.dt();
41        if engine.is_key_held(KeyCode::ArrowUp) { self.player_pos[1] -= speed; }
42        if engine.is_key_held(KeyCode::ArrowDown) { self.player_pos[1] += speed; }
43        if engine.is_key_held(KeyCode::ArrowLeft) { self.player_pos[0] -= speed; }
44        if engine.is_key_held(KeyCode::ArrowRight) { self.player_pos[0] += speed; }
45        SceneAction::None
46    }
47    fn draw(&mut self, engine: &mut jEngine) {
48        let sw = engine.grid_width() as f32 * engine.tile_width() as f32;
49        let sh = engine.grid_height() as f32 * engine.tile_height() as f32;
50        engine.ui.ui_rect(0.0, 0.0, sw, sh, Color([0.05, 0.08, 0.08, 1.0]));
51        engine.ui.ui_text(20.0, 20.0, "Gameplay: Use Arrows to move, Esc to Pause", TEXT, Color::TRANSPARENT, Some(14.0));
52        Panel::new(self.player_pos[0] - 15.0, self.player_pos[1] - 15.0, 30.0, 30.0).with_color(Color::CYAN).with_radius(15.0).draw(engine);
53    }
54}
55
56struct PauseScene;
57impl Scene for PauseScene {
58    fn is_transparent(&self) -> bool { true }
59    fn update(&mut self, engine: &mut jEngine) -> SceneAction {
60        if engine.is_key_pressed(KeyCode::Escape) || engine.is_key_pressed(KeyCode::Enter) { SceneAction::Pop }
61        else if engine.is_key_pressed(KeyCode::Backspace) { SceneAction::ReplaceAll(Box::new(TitleScene)) }
62        else { SceneAction::None }
63    }
64    fn draw(&mut self, engine: &mut jEngine) {
65        let sw = engine.grid_width() as f32 * engine.tile_width() as f32;
66        let sh = engine.grid_height() as f32 * engine.tile_height() as f32;
67        engine.ui.ui_rect(0.0, 0.0, sw, sh, Color([0.0, 0.0, 0.0, 0.6]));
68        Panel::new(sw * 0.5 - 150.0, sh * 0.5 - 80.0, 300.0, 160.0).with_color(PANEL_BG).with_border(BORDER, 1.0).with_radius(8.0).draw(engine);
69        engine.ui.ui_text(sw * 0.5 - 40.0, sh * 0.5 - 30.0, "PAUSED", TEXT, Color::TRANSPARENT, Some(20.0));
70        engine.ui.ui_text(sw * 0.5 - 100.0, sh * 0.5 + 20.0, "[Enter] Resume  [Bksp] Menu", BORDER, Color::TRANSPARENT, Some(12.0));
71    }
72}
73
74fn main() {
75    jEngine::builder().with_title("jengine — Scenes").with_size(1280, 720).with_tileset(DEFAULT_TILESET, DEFAULT_TILE_W, DEFAULT_TILE_H).run(SceneStack::new(Box::new(TitleScene)));
76}