daa36c894e5958803fff5e7c3ee0d0d9dd2134be
[bug-basher.git] / src / main.rs
1 extern crate gate;
2
3 use gate::{App, Audio};
4 use gate::app_info::AppInfo;
5 use gate::input::*;
6 use gate::renderer::{Renderer, Affine};
7
8 mod asset_id { include!(concat!(env!("OUT_DIR"), "/asset_id.rs")); }
9 use asset_id::*;
10
11 mod geometry;
12 use geometry::*;
13
14 mod hitbox;
15 use hitbox::*;
16
17 mod entities;
18 use entities::bug::Bug;
19 use entities::home::Home;
20
21 struct BugBasherGame {
22     bugs: Vec<Bug>,
23     home: Home,
24     points: i64,
25     lives: i64,
26     game_over: bool
27 }
28
29 impl App<AssetId> for BugBasherGame {
30     fn start(&mut self, _audio: &mut Audio<AssetId>) {
31     }
32
33     fn advance(&mut self, seconds: f64, _audio: &mut Audio<AssetId>) -> bool {
34         self.bugs.retain(|b| b.alive);
35         for bug in self.bugs.iter_mut() {
36             bug.advance(seconds);
37             if self.home.touches_circle(bug) {
38                 bug.alive = false;
39                 self.lives -= 1;
40             }
41         }
42         
43         true
44     }
45
46     fn input(&mut self, evt: InputEvent, _audio: &mut Audio<AssetId>) -> bool {
47         match evt {
48             InputEvent::MousePressed(MouseButton::Left, x, y) => {
49                 for bug in self.bugs.iter_mut().filter(|bug| bug.touches_point(Vec2d { x, y })) {
50                     bug.alive = false;
51                     self.points += 1;
52                 }
53             },
54             _ => {}
55         }
56         true
57     }
58
59     fn render(&mut self, renderer: &mut Renderer<AssetId>) {
60         let (app_width, app_height) = (renderer.app_width(), renderer.app_height());
61         renderer.clear((255,255,255));
62         {
63             let points_str = format!("{}", self.points);
64             let lives_str = format!("{}", self.lives);
65             BugBasherGame::print_string(renderer, &points_str, - app_width / 2. + 50., app_height / 2. - 50.);
66             BugBasherGame::print_string(renderer, &lives_str, app_width / 2. - 50. - lives_str.len() as f64 * 25., app_height / 2. - 50.);
67         }
68         {
69             let mut renderer = renderer.sprite_mode();
70             renderer.draw(
71                 &Affine::translate(self.home.pos.x, self.home.pos.y),
72                 SpriteId::Home
73             );
74             for bug in &self.bugs {
75                 renderer.draw(
76                     &Affine::translate(bug.pos.x, bug.pos.y).pre_rotate(bug.rotation),
77                     SpriteId::Bug
78                 );
79             }
80         }
81     }
82 }
83
84 impl BugBasherGame {
85     fn new() -> BugBasherGame {
86         let mut game = BugBasherGame {
87             home: Home::new(0., 0.),
88             bugs: Vec::new(),
89             points: 0,
90             lives: 0,
91             game_over: true
92         };
93         game.reset();
94         game
95     }
96
97     fn reset(&mut self) {
98         self.points = 0;
99         self.lives = 3;
100         self.game_over = false;
101     }
102
103     fn print_string(renderer: &mut Renderer<AssetId>, string: &str, x: f64, y: f64) {
104         let mut renderer = renderer.tiled_mode(-x, -y);
105         let spacing = 25.;
106         for (i, c) in string.chars().enumerate() {
107             let affine = Affine::translate(i as f64 * spacing, 0.);
108             let tile = match c {
109                 '-' => TileId::NumberFontR0C0,
110                 '0' => TileId::NumberFontR0C1,
111                 '1' => TileId::NumberFontR0C2,
112                 '2' => TileId::NumberFontR0C3,
113                 '3' => TileId::NumberFontR0C4,
114                 '4' => TileId::NumberFontR0C5,
115                 '5' => TileId::NumberFontR0C6,
116                 '6' => TileId::NumberFontR0C7,
117                 '7' => TileId::NumberFontR0C8,
118                 '8' => TileId::NumberFontR0C9,
119                 '9' => TileId::NumberFontR0C10,
120                 _ => TileId::NumberFontR0C0,
121             };
122             renderer.draw(&affine, tile);
123         };
124     }
125 }
126
127 fn main() {
128     let info = AppInfo::with_app_height(1000.).title("Bug Basher").build();
129     gate::run(info, BugBasherGame::new());
130 }