Commit | Line | Data |
---|---|---|
b0566120 TW |
1 | use sdl2::controller::{Axis, Button}; |
2 | use core::controller::ControllerManager; | |
3 | use std::cell::RefCell; | |
4 | use std::rc::Rc; | |
5 | use core::controller::Controller; | |
6 | use common::Point2D; | |
7 | use sdl2::rect::Rect; | |
8 | use common::Nanoseconds; | |
9 | use sdl2::event::Event; | |
10 | use sprites::SpriteManager; | |
11 | use sdl2::render::Canvas; | |
12 | use sdl2::video::Window; | |
13 | use AppState; | |
14 | use point; | |
15 | ||
16 | ////////// GAMESTATE /////////////////////////////////////////////////////////// | |
17 | ||
18 | #[derive(Default)] | |
19 | pub struct GameState { | |
20 | world: World, | |
21 | } | |
22 | ||
23 | impl GameState { | |
24 | pub fn new() -> Self { | |
25 | GameState { | |
26 | world: World::new(), | |
27 | } | |
28 | } | |
29 | } | |
30 | ||
31 | impl AppState for GameState { | |
32 | fn enter(&mut self, ctrl_man: &mut ControllerManager) { | |
33 | if let Some(ctrl) = ctrl_man.controllers.get(&0) { | |
34 | self.world.add(Box::new(Character::new(ctrl.clone()))); | |
35 | } | |
36 | } | |
37 | ||
38 | fn leave(&mut self) {} | |
39 | ||
40 | fn update(&mut self, dt: Nanoseconds) { | |
41 | self.world.update(dt); | |
42 | } | |
43 | ||
44 | fn render(&mut self, canvas: &mut Canvas<Window>, sprites: &mut SpriteManager) { | |
45 | self.world.render(canvas, sprites); | |
46 | } | |
47 | ||
48 | fn handle_event(&mut self, _event: Event) {} | |
49 | } | |
50 | ||
51 | ////////// WORLD /////////////////////////////////////////////////////////////// | |
52 | ||
53 | #[derive(Default)] | |
54 | pub struct World { | |
55 | level: Level, | |
56 | objects: Vec<Box<dyn Object>>, | |
57 | } | |
58 | ||
59 | impl World { | |
60 | pub fn new() -> Self { | |
61 | World { | |
62 | level: Level { | |
63 | gravity: point!(0.0, 0.1), | |
64 | ground: 600.0, | |
65 | }, | |
66 | ..Default::default() | |
67 | } | |
68 | } | |
69 | ||
70 | pub fn update(&mut self, dt: Nanoseconds) { | |
71 | for o in &mut self.objects { | |
72 | o.update(&self.level, dt); | |
73 | } | |
74 | } | |
75 | ||
76 | pub fn render(&mut self, canvas: &mut Canvas<Window>, sprites: &mut SpriteManager) { | |
77 | self.level.render(canvas, sprites); | |
78 | for o in &mut self.objects { | |
79 | o.render(canvas, sprites); | |
80 | } | |
81 | } | |
82 | ||
83 | pub fn add(&mut self, object: Box<dyn Object>) { | |
84 | self.objects.push(object); | |
85 | } | |
86 | } | |
87 | ||
88 | ////////// LEVEL /////////////////////////////////////////////////////////////// | |
89 | ||
90 | #[derive(Default)] | |
91 | pub struct Level { | |
92 | gravity: Point2D<f64>, | |
93 | ground: f64, // just to have something | |
94 | } | |
95 | ||
96 | impl Level { | |
97 | pub fn render(&mut self, canvas: &mut Canvas<Window>, _sprites: &mut SpriteManager) { | |
98 | let w = canvas.viewport().width() as i32; | |
99 | for i in 1..11 { | |
100 | let y = (i * i - 1) as i32 + self.ground as i32; | |
101 | canvas.set_draw_color((255 - i * 20, 255 - i * 20, 0)); | |
102 | canvas.draw_line((0, y), (w, y)).unwrap(); | |
103 | } | |
104 | } | |
105 | } | |
106 | ||
107 | ////////// OBJECT ////////////////////////////////////////////////////////////// | |
108 | ||
109 | pub trait Object { | |
110 | fn update(&mut self, lvl: &Level, dt: Nanoseconds); | |
111 | fn render(&mut self, canvas: &mut Canvas<Window>, _sprites: &mut SpriteManager); | |
112 | } | |
113 | ||
114 | pub trait Physical {} | |
115 | pub trait Drawable {} | |
116 | ||
117 | ////////// CHARACTER /////////////////////////////////////////////////////////// | |
118 | ||
119 | pub struct Character { | |
120 | ctrl: Rc<RefCell<Controller>>, | |
121 | pos: Point2D<f64>, | |
122 | vel: Point2D<f64>, | |
123 | } | |
124 | ||
125 | impl Character { | |
126 | pub fn new(ctrl: Rc<RefCell<Controller>>) -> Self { | |
127 | Character { | |
128 | ctrl, | |
129 | pos: point!(100.0, 100.0), | |
130 | vel: point!(0.0, 0.0), | |
131 | } | |
132 | } | |
133 | } | |
134 | ||
135 | impl Object for Character { | |
136 | fn update(&mut self, lvl: &Level, _dt: Nanoseconds) { | |
137 | self.vel += lvl.gravity; | |
2836f506 | 138 | self.pos += self.vel; |
b0566120 TW |
139 | |
140 | let ctrl = &self.ctrl.borrow().ctrl; | |
141 | ||
142 | if self.pos.y >= lvl.ground { | |
143 | self.pos.y = lvl.ground; | |
144 | self.vel.y = 0.0; | |
145 | self.vel.x *= 0.9; | |
146 | ||
147 | if ctrl.button(Button::A) { | |
148 | self.vel.y = -5.0; | |
149 | } | |
150 | } | |
151 | ||
152 | match ctrl.axis(Axis::LeftX) as f64 / 32768.0 { | |
153 | v if v < -0.9 => { self.vel.x -= 0.5 } | |
154 | v if v > 0.9 => { self.vel.x += 0.5 } | |
155 | _ => {} | |
156 | } | |
157 | } | |
158 | ||
159 | fn render(&mut self, canvas: &mut Canvas<Window>, sprites: &mut SpriteManager) { | |
160 | let block = sprites.get("mario"); | |
161 | let size = 32; | |
162 | canvas.copy(block, None, Rect::new(self.pos.x as i32, self.pos.y as i32 - size as i32, size, size)).unwrap(); | |
163 | } | |
164 | } |