use crate::constants; use ggez::graphics::{self, DrawParam, FilterMode, Image, Rect}; use ggez::mint::{Point2, Vector2}; use ggez::{Context, GameResult}; use std::time::Instant; #[derive(Clone, Copy)] enum CosmonautFrames { None, One, Two, Three, Four, } impl CosmonautFrames { pub fn next(&mut self) { *self = match self { CosmonautFrames::None => CosmonautFrames::One, CosmonautFrames::One => CosmonautFrames::Two, CosmonautFrames::Two => CosmonautFrames::Three, CosmonautFrames::Three => CosmonautFrames::Four, CosmonautFrames::Four => CosmonautFrames::None, }; } } pub struct Cosmonaut { destination: Point2, image: Image, frame: CosmonautFrames, timer: Instant, scale: Vector2, } impl Cosmonaut { pub fn new(context: &mut Context) -> GameResult { let mut image = Image::new(context, "/cosmonaut.png")?; image.set_filter(FilterMode::Nearest); Ok(Cosmonaut { image, destination: Point2 { x: 600.0, y: 350.0 }, frame: CosmonautFrames::None, timer: Instant::now(), scale: Vector2 { x: constants::TILE_SCALE * 2.0, y: constants::TILE_SCALE * 2.0, }, }) } pub fn draw(&self, context: &mut Context) -> GameResult { graphics::draw( context, &self.image, DrawParam::default() .dest(self.destination) .scale(self.scale) .src(Rect::new(0.0, 0.0, 1.0 / 3.0, 1.0)), )?; let source = match self.frame { CosmonautFrames::None => None, CosmonautFrames::One => Some(Rect::new(1.0 / 3.0, 0.0, 1.0 / 3.0, 1.0 / 2.0)), CosmonautFrames::Two => Some(Rect::new(2.0 / 3.0, 0.0, 1.0, 1.0 / 2.0)), CosmonautFrames::Three => Some(Rect::new(1.0 / 3.0, 1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0)), CosmonautFrames::Four => Some(Rect::new(2.0 / 3.0, 1.0 / 2.0, 1.0, 1.0)), }; if let Some(source) = source { graphics::draw( context, &self.image, DrawParam::default() .dest(self.destination) .src(source) .scale(self.scale), )?; } Ok(()) } pub fn update(&mut self) { match self.frame { CosmonautFrames::None => (), _ => { if self.timer.elapsed().as_millis() > 50 { self.frame.next(); self.timer = Instant::now(); } } } } pub fn start(&mut self) { if let CosmonautFrames::None = self.frame { if self.timer.elapsed().as_secs() > 5 { self.timer = Instant::now(); self.frame.next() } } } pub fn contains(&self, position: Point2) -> bool { position.x > self.destination.x && position.y > self.destination.y && position.x < self.destination.x + constants::TILE_WIDTH * constants::TILE_SCALE * 2.0 && position.y < self.destination.y + constants::TILE_WIDTH * constants::TILE_SCALE * 2.0 } }