extern crate gate; use gate::{App, Audio}; use gate::app_info::AppInfo; use gate::input::*; use gate::renderer::{Renderer, Affine}; mod asset_id { include!(concat!(env!("OUT_DIR"), "/asset_id.rs")); } use asset_id::*; mod geometry; use geometry::*; mod hitbox; use hitbox::*; mod entities; use entities::bug::Bug; use entities::home::Home; struct BugBasherGame { bugs: Vec, home: Home, points: i64, lives: i64, game_over: bool } impl App for BugBasherGame { fn start(&mut self, _audio: &mut Audio) { } fn advance(&mut self, seconds: f64, _audio: &mut Audio) -> bool { self.bugs.retain(|b| b.alive); for bug in self.bugs.iter_mut() { bug.advance(seconds); if self.home.touches_circle(bug) { bug.alive = false; self.lives -= 1; } } true } fn input(&mut self, evt: InputEvent, _audio: &mut Audio) -> bool { match evt { InputEvent::MousePressed(MouseButton::Left, x, y) => { for bug in self.bugs.iter_mut().filter(|bug| bug.touches_point(Vec2d { x, y })) { bug.alive = false; self.points += 1; } }, _ => {} } true } fn render(&mut self, renderer: &mut Renderer) { let (app_width, app_height) = (renderer.app_width(), renderer.app_height()); renderer.clear((255,255,255)); { let points_str = format!("{}", self.points); let lives_str = format!("{}", self.lives); BugBasherGame::print_string(renderer, &points_str, - app_width / 2. + 50., app_height / 2. - 50.); BugBasherGame::print_string(renderer, &lives_str, app_width / 2. - 50. - lives_str.len() as f64 * 25., app_height / 2. - 50.); } { let mut renderer = renderer.sprite_mode(); renderer.draw( &Affine::translate(self.home.pos.x, self.home.pos.y), SpriteId::Home ); for bug in &self.bugs { renderer.draw( &Affine::translate(bug.pos.x, bug.pos.y).pre_rotate(bug.rotation), SpriteId::Bug ); } } } } impl BugBasherGame { fn new() -> BugBasherGame { let mut game = BugBasherGame { home: Home::new(0., 0.), bugs: Vec::new(), points: 0, lives: 0, game_over: true }; game.reset(); game } fn reset(&mut self) { self.points = 0; self.lives = 3; self.game_over = false; } fn print_string(renderer: &mut Renderer, string: &str, x: f64, y: f64) { let mut renderer = renderer.tiled_mode(-x, -y); let spacing = 25.; for (i, c) in string.chars().enumerate() { let affine = Affine::translate(i as f64 * spacing, 0.); let tile = match c { '-' => TileId::NumberFontR0C0, '0' => TileId::NumberFontR0C1, '1' => TileId::NumberFontR0C2, '2' => TileId::NumberFontR0C3, '3' => TileId::NumberFontR0C4, '4' => TileId::NumberFontR0C5, '5' => TileId::NumberFontR0C6, '6' => TileId::NumberFontR0C7, '7' => TileId::NumberFontR0C8, '8' => TileId::NumberFontR0C9, '9' => TileId::NumberFontR0C10, _ => TileId::NumberFontR0C0, }; renderer.draw(&affine, tile); }; } } fn main() { let info = AppInfo::with_app_height(1000.).title("Bug Basher").build(); gate::run(info, BugBasherGame::new()); }