//! Global game stuff used by all objs/rooms use std::collections::HashMap; use sdl2::{ pixels::Color, render::{ Canvas, TextureCreator }, video::{ Window, WindowContext } }; use ycraft::{ obj::{ ControlObjectBehavior, GameObjectBehavior }, res::{ Font, Image, Sound } }; use crate::play::Dir; pub const BASE_MOVE_SPD: f64 = 24.0; pub const MOVE_SPD_INC: f64 = 4.0; const END_STATE: usize = ((640 - 64) / 32) * ((360 - 64) / 32); #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Img { Title, Snake, Mouse, Board, Dead, Win } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Snd { Music, Bite } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Fnt { Geist } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Spr { Title, Head, Body, Tail, Mouse, Board, Dead, Win } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Rm { Title, Play, Dead, Win } /// Used for sharing data between objects via GameObjectBehavior trait #[derive(Clone, Copy)] pub enum Data { Title, Head { dir: Dir, lurch_propagation: usize }, Body { index: isize, dir: Dir }, Tail, Mouse, Board, Dead, Score(usize), Win } #[derive(Clone)] pub struct Score { data: Data } impl Score { pub fn new() -> Self { Self { data: Data::Score(4) } } } impl ControlObjectBehavior for Score { fn data(&self) -> Data { self.data.clone() } fn update( &mut self, _delta: f64, cur_room: &Rm, _others: &Vec>>, room_objs: &Vec>>) -> ( Option, Vec>> ) { match cur_room { Rm::Title => self.data = Data::Score(4), Rm::Play => if let Data::Score(ref mut score) = self.data { *score = 2; // Start with tail and head for obj in room_objs.iter() { if let Data::Body { .. } = obj.state().custom { *score += 1; } } if *score >= END_STATE { return (Some(Rm::Win), vec![]); } }, Rm::Dead => {}, Rm::Win => {} } (None, vec![]) } fn render( &mut self, cnv: &mut Canvas, cur_room: &Rm, _imgs: &HashMap, snds: &HashMap, fonts: &HashMap, creator: &TextureCreator, _elapsed: f64) -> Result<(), String> { if !Sound::is_music_playing() { snds[&Snd::Music].play()?; } match cur_room { Rm::Play | Rm::Dead => if let Data::Score(score) = self.data { fonts[&Fnt::Geist].render( cnv, creator, format!("Score: {}", score).as_str(), &Color::WHITE, (16, 16), 0.0, (false, false) )?; }, _ => {} } Ok(()) } }