d9af79edc486635a9c01aa417b7361127c244073
[kaka/rust-sdl-test.git] / src / core / game.rs
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;
138         self.pos = self.pos + self.vel;
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 }