diff --git a/src/main.rs b/src/main.rs index 613c9c8..2a1209c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,15 +3,12 @@ mod world; use std::time::Duration; -use crate::player::player::Player; -use crate::world::world::{BoxAreaContent, BoxAreaPosition, World}; +use crate::player::Player; +use crate::world::{BoxAreaContent, BoxAreaPosition, World}; use sdl2::event::Event; use sdl2::image::LoadTexture; use sdl2::keyboard::Keycode; use sdl2::pixels::Color; -use sdl2::rect::{Point, Rect}; -use sdl2::render::{Texture, WindowCanvas}; -use sdl2::ttf::Font; const GLASS_SPACE: u8 = 5; @@ -94,29 +91,26 @@ fn main() { None => Option::None, }; - match colliding_box_area { - Some(ba) => { - let content = match &ba.content { - BoxAreaContent::HiddenBox => BoxAreaContent::random(), - BoxAreaContent::EmptyGlass => BoxAreaContent::EmptyGlass, - BoxAreaContent::FilledBottle => BoxAreaContent::FilledBottle, - _ => BoxAreaContent::Nothing, - }; + if let Some(ba) = colliding_box_area { + let content = match &ba.content { + BoxAreaContent::HiddenBox => BoxAreaContent::random(), + BoxAreaContent::EmptyGlass => BoxAreaContent::EmptyGlass, + BoxAreaContent::FilledBottle => BoxAreaContent::FilledBottle, + _ => BoxAreaContent::Nothing, + }; - if content == BoxAreaContent::EmptyGlass && world.player.can_pick_glass() { - ba.update_content(BoxAreaContent::Nothing); - world.player.pick_glass(); - } else if content == BoxAreaContent::EmptyGlass && !world.player.can_pick_glass() { - ba.update_content(BoxAreaContent::EmptyGlass); - } else if content == BoxAreaContent::FilledBottle && world.player.can_fill_glass() { - ba.update_content(BoxAreaContent::EmptyBottle); - world.player.fill_glass(); - } else if content == BoxAreaContent::FilledBottle && !world.player.can_fill_glass() - { - ba.update_content(BoxAreaContent::FilledBottle); - } + if content == BoxAreaContent::EmptyGlass && world.player.can_pick_glass() { + ba.update_content(BoxAreaContent::Nothing); + world.player.pick_glass(); + } else if content == BoxAreaContent::EmptyGlass && !world.player.can_pick_glass() { + ba.update_content(BoxAreaContent::EmptyGlass); + } else if content == BoxAreaContent::FilledBottle && world.player.can_fill_glass() { + ba.update_content(BoxAreaContent::EmptyBottle); + world.player.fill_glass(); + } else if content == BoxAreaContent::FilledBottle && !world.player.can_fill_glass() + { + ba.update_content(BoxAreaContent::FilledBottle); } - None => {} } if chrono::Utc::now().timestamp_millis() % 1000 > 950 { diff --git a/src/player.rs b/src/player.rs index 0b35c44..546ba2f 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,128 +1,126 @@ -pub mod player { - use crate::GLASS_SPACE; - use sdl2::rect::{Point, Rect}; +use crate::GLASS_SPACE; +use sdl2::rect::{Point, Rect}; - pub struct Player { - pub position: Point, - direction: PlayerDirection, - footstep: u8, - pub empty_glasses: u8, - pub filled_glasses: u8, - pub points: u32, +pub struct Player { + pub position: Point, + direction: PlayerDirection, + footstep: u8, + pub empty_glasses: u8, + pub filled_glasses: u8, + pub points: u32, +} + +enum PlayerDirection { + Up, + Down, + Left, + Right, +} + +impl Player { + pub fn init() -> Player { + Player { + position: Point::new(380, 250), + direction: PlayerDirection::Down, + footstep: 0, + empty_glasses: 0, + filled_glasses: 0, + points: 0, + } } - enum PlayerDirection { - UP, - DOWN, - LEFT, - RIGHT, + pub fn can_pick_glass(&self) -> bool { + self.empty_glasses + self.filled_glasses < GLASS_SPACE } - impl Player { - pub fn init() -> Player { - return Player { - position: Point::new(380, 250), - direction: PlayerDirection::DOWN, - footstep: 0, - empty_glasses: 0, - filled_glasses: 0, - points: 0, - }; - } + pub fn pick_glass(&mut self) { + self.empty_glasses += 1; + self.points += 2 + } - pub fn can_pick_glass(&self) -> bool { - self.empty_glasses + self.filled_glasses < GLASS_SPACE - } + pub fn can_fill_glass(&self) -> bool { + self.empty_glasses > 0 + } - pub fn pick_glass(&mut self) { - self.empty_glasses = self.empty_glasses + 1; - self.points = self.points + 2 - } + pub fn fill_glass(&mut self) { + self.empty_glasses -= 1; + self.filled_glasses += 1; + self.points += 3 + } - pub fn can_fill_glass(&self) -> bool { - self.empty_glasses > 0 - } + pub fn can_drink_glass(&self) -> bool { + self.filled_glasses > 0 + } - pub fn fill_glass(&mut self) { - self.empty_glasses = self.empty_glasses - 1; - self.filled_glasses = self.filled_glasses + 1; - self.points = self.points + 3 - } + pub fn drink_glass(&mut self) { + self.filled_glasses -= 1; + self.points += 5 + } - pub fn can_drink_glass(&self) -> bool { - self.filled_glasses > 0 - } + pub fn center(&self) -> Point { + Point::new(self.position.x() + 19, self.position.y() + 56) + } - pub fn drink_glass(&mut self) { - self.filled_glasses = self.filled_glasses - 1; - self.points = self.points + 5 - } + pub fn bounding_rect(&self) -> Rect { + Rect::new(self.position.x(), self.position.y(), 40, 115) + } - pub fn center(&self) -> Point { - Point::new(self.position.x() + 19, self.position.y() + 56) - } + pub fn sprite(&self) -> Rect { + let x = match self.footstep { + 1 => 60, + 2 => 115, + _ => 5, + }; - pub fn bounding_rect(&self) -> Rect { - Rect::new(self.position.x(), self.position.y(), 40, 115) + match self.direction { + PlayerDirection::Down => Rect::new(x, 5, 40, 115), + PlayerDirection::Left => Rect::new(x, 255, 40, 115), + PlayerDirection::Right => Rect::new(x, 130, 40, 115), + PlayerDirection::Up => Rect::new(x, 380, 40, 115), } + } - pub fn sprite(&self) -> Rect { - let x = match self.footstep { - 1 => 60, - 2 => 115, - _ => 5, - }; + pub fn face_up(&mut self) { + self.direction = PlayerDirection::Up; + } - match self.direction { - PlayerDirection::DOWN => Rect::new(x, 5, 40, 115), - PlayerDirection::LEFT => Rect::new(x, 255, 40, 115), - PlayerDirection::RIGHT => Rect::new(x, 130, 40, 115), - PlayerDirection::UP => Rect::new(x, 380, 40, 115), - } - } + pub fn face_down(&mut self) { + self.direction = PlayerDirection::Down; + } - pub fn face_up(&mut self) { - self.direction = PlayerDirection::UP; - } + pub fn face_left(&mut self) { + self.direction = PlayerDirection::Left; + } - pub fn face_down(&mut self) { - self.direction = PlayerDirection::DOWN; - } + pub fn face_right(&mut self) { + self.direction = PlayerDirection::Right; + } - pub fn face_left(&mut self) { - self.direction = PlayerDirection::LEFT; - } + pub fn move_up(&mut self) { + self.face_up(); + self.footstep = &self.footstep % 2 + 1; + self.position.y -= 15 + } - pub fn face_right(&mut self) { - self.direction = PlayerDirection::RIGHT; - } + pub fn move_down(&mut self) { + self.face_down(); + self.footstep = &self.footstep % 2 + 1; + self.position.y += 15 + } - pub fn move_up(&mut self) { - self.face_up(); - self.footstep = &self.footstep % 2 + 1; - self.position.y = self.position.y - 15 - } + pub fn move_left(&mut self) { + self.face_left(); + self.footstep = &self.footstep % 2 + 1; + self.position.x -= 15 + } - pub fn move_down(&mut self) { - self.face_down(); - self.footstep = &self.footstep % 2 + 1; - self.position.y = self.position.y + 15 - } + pub fn move_right(&mut self) { + self.face_right(); + self.footstep = &self.footstep % 2 + 1; + self.position.x += 15 + } - pub fn move_left(&mut self) { - self.face_left(); - self.footstep = &self.footstep % 2 + 1; - self.position.x = self.position.x - 15 - } - - pub fn move_right(&mut self) { - self.face_right(); - self.footstep = &self.footstep % 2 + 1; - self.position.x = self.position.x + 15 - } - - pub fn stop(&mut self) { - self.footstep = 0; - } + pub fn stop(&mut self) { + self.footstep = 0; } } diff --git a/src/world.rs b/src/world.rs index 63ebd77..09ed7f3 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,391 +1,385 @@ -pub mod world { - use crate::{Player, GLASS_SPACE}; - use sdl2::pixels::Color; - use sdl2::rect::{Point, Rect}; - use sdl2::render::{Texture, WindowCanvas}; - use sdl2::ttf::Font; +use crate::{Player, GLASS_SPACE}; +use sdl2::pixels::Color; +use sdl2::rect::{Point, Rect}; +use sdl2::render::{Texture, WindowCanvas}; +use sdl2::ttf::Font; - pub struct World { - pub player: Player, - pub right_top_box_area: BoxArea, - pub right_bottom_box_area: BoxArea, - pub left_bottom_box_area: BoxArea, - pub left_top_box_area: BoxArea, - stops: Vec, +pub struct World { + pub player: Player, + pub right_top_box_area: BoxArea, + pub right_bottom_box_area: BoxArea, + pub left_bottom_box_area: BoxArea, + pub left_top_box_area: BoxArea, + stops: Vec, +} + +impl World { + pub fn init() -> World { + World { + player: Player::init(), + right_top_box_area: BoxArea::new(BoxAreaPosition::RightTop, BoxAreaContent::EmptyGlass), + right_bottom_box_area: BoxArea::new( + BoxAreaPosition::RightBottom, + BoxAreaContent::HiddenBox, + ), + left_bottom_box_area: BoxArea::new( + BoxAreaPosition::LeftBottom, + BoxAreaContent::Nothing, + ), + left_top_box_area: BoxArea::new(BoxAreaPosition::LeftTop, BoxAreaContent::Nothing), + stops: vec![ + Point::new(380, 60), + Point::new(590, 450), + Point::new(720, 300), + Point::new(20, 410), + Point::new(190, 560), + ], + } } - impl World { - pub fn init() -> World { - World { - player: Player::init(), - right_top_box_area: BoxArea::new( - BoxAreaPosition::RightTop, - BoxAreaContent::EmptyGlass, - ), - right_bottom_box_area: BoxArea::new( - BoxAreaPosition::RightBottom, - BoxAreaContent::HiddenBox, - ), - left_bottom_box_area: BoxArea::new( - BoxAreaPosition::LeftBottom, - BoxAreaContent::Nothing, - ), - left_top_box_area: BoxArea::new(BoxAreaPosition::LeftTop, BoxAreaContent::Nothing), - stops: vec![ - Point::new(380, 60), - Point::new(590, 450), - Point::new(720, 300), - Point::new(20, 410), - Point::new(190, 560), - ], + pub fn collides_with_box_area(&mut self) -> Option { + if self.right_top_box_area.collides_with(&self.player) { + return Some(BoxAreaPosition::RightTop); + } else if self.right_bottom_box_area.collides_with(&self.player) { + return Some(BoxAreaPosition::RightBottom); + } else if self.left_bottom_box_area.collides_with(&self.player) { + return Some(BoxAreaPosition::LeftBottom); + } else if self.left_top_box_area.collides_with(&self.player) { + return Some(BoxAreaPosition::LeftTop); + } + + None + } + + pub fn collides_with_lounge(&mut self) -> bool { + let lounge_rect = Rect::new(325, 260, 150, 95); + lounge_rect.contains_point(self.player.center()) + } + + fn collides_with_stop(&mut self) -> bool { + for s in &self.stops { + let x = s.x() + 12; + let y = s.y() + 12; + if self.player.bounding_rect().contains_point(Point::new(x, y)) { + return true; } } + false + } - pub fn collides_with_box_area(&mut self) -> Option { - if self.right_top_box_area.collides_with(&self.player) { - return Some(BoxAreaPosition::RightTop); - } else if self.right_bottom_box_area.collides_with(&self.player) { - return Some(BoxAreaPosition::RightBottom); - } else if self.left_bottom_box_area.collides_with(&self.player) { - return Some(BoxAreaPosition::LeftBottom); - } else if self.left_top_box_area.collides_with(&self.player) { - return Some(BoxAreaPosition::LeftTop); - } - - None - } - - pub fn collides_with_lounge(&mut self) -> bool { - let lounge_rect = Rect::new(325, 260, 150, 95); - lounge_rect.contains_point(self.player.center()) - } - - fn collides_with_stop(&mut self) -> bool { - for s in &self.stops { - let x = s.x() + 12; - let y = s.y() + 12; - if self.player.bounding_rect().contains_point(Point::new(x, y)) { - return true; - } - } - return false; - } - - pub fn move_up(&mut self) { - if self.player.position.y > 50 { - self.player.move_up(); - if self.collides_with_stop() { - self.player.move_down(); - self.player.face_up(); - } - } - } - - pub fn move_down(&mut self) { - if self.player.position.y < 600 - 110 { + pub fn move_up(&mut self) { + if self.player.position.y > 50 { + self.player.move_up(); + if self.collides_with_stop() { self.player.move_down(); - if self.collides_with_stop() { - self.player.move_up(); - self.player.face_down(); - } + self.player.face_up(); } } + } - pub fn move_left(&mut self) { - if self.player.position.x > 0 { - self.player.move_left(); - if self.collides_with_stop() { - self.player.move_right(); - self.player.face_left(); - } + pub fn move_down(&mut self) { + if self.player.position.y < 600 - 110 { + self.player.move_down(); + if self.collides_with_stop() { + self.player.move_up(); + self.player.face_down(); } } + } - pub fn move_right(&mut self) { - if self.player.position.x < 800 - 40 { + pub fn move_left(&mut self) { + if self.player.position.x > 0 { + self.player.move_left(); + if self.collides_with_stop() { self.player.move_right(); - if self.collides_with_stop() { - self.player.move_left(); - self.player.face_right(); - } + self.player.face_left(); } } + } - pub fn stop_player(&mut self) { - self.player.stop() - } - - pub fn update_box_areas(&mut self) { - World::update_box_area(&mut self.right_top_box_area); - World::update_box_area(&mut self.right_bottom_box_area); - World::update_box_area(&mut self.left_bottom_box_area); - World::update_box_area(&mut self.left_top_box_area); - } - - fn update_box_area(box_area: &mut BoxArea) { - let now = chrono::Utc::now().timestamp(); - let r: i64 = (rand::random::() % 10) + 3; - - if box_area.content == BoxAreaContent::Nothing && box_area.last_update + 10 < now { - box_area.content = BoxAreaContent::HiddenBox; - box_area.last_update = now; - } else if box_area.content != BoxAreaContent::Nothing - && box_area.last_update + 30 < now - r - { - box_area.content = BoxAreaContent::Nothing; - box_area.last_update = now; + pub fn move_right(&mut self) { + if self.player.position.x < 800 - 40 { + self.player.move_right(); + if self.collides_with_stop() { + self.player.move_left(); + self.player.face_right(); } } + } - pub fn render(&self, canvas: &mut WindowCanvas, texture: &Texture, font: &Font) { - canvas.clear(); + pub fn stop_player(&mut self) { + self.player.stop() + } - canvas.set_draw_color(Color::RGB(160, 90, 44)); - canvas.fill_rect(Rect::new(0, 0, 800, 45)); + pub fn update_box_areas(&mut self) { + World::update_box_area(&mut self.right_top_box_area); + World::update_box_area(&mut self.right_bottom_box_area); + World::update_box_area(&mut self.left_bottom_box_area); + World::update_box_area(&mut self.left_top_box_area); + } - canvas.set_draw_color(Color::RGB(206, 182, 115)); + fn update_box_area(box_area: &mut BoxArea) { + let now = chrono::Utc::now().timestamp(); + let r: i64 = (rand::random::() % 10) + 3; - // Points/Glasses - (1..=GLASS_SPACE).for_each(|i| { - canvas.set_draw_color(Color::RGB(128, 51, 0)); - canvas.fill_rect(Rect::new(5, 37, GLASS_SPACE as u32 * 25 + 5, 4)); + if box_area.content == BoxAreaContent::Nothing && box_area.last_update + 10 < now { + box_area.content = BoxAreaContent::HiddenBox; + box_area.last_update = now; + } else if box_area.content != BoxAreaContent::Nothing && box_area.last_update + 30 < now - r + { + box_area.content = BoxAreaContent::Nothing; + box_area.last_update = now; + } + } - if self.player.filled_glasses + self.player.empty_glasses >= i { - canvas.copy( - texture, - Rect::new(35, 510, 20, 25), - Rect::new((i as i32) * 25 - 15, 10, 20, 25), - ); - } - if self.player.filled_glasses >= i { - canvas.copy( - texture, - Rect::new(5, 510, 20, 25), - Rect::new((i as i32) * 25 - 15, 10, 20, 25), - ); - } - }); + pub fn render(&self, canvas: &mut WindowCanvas, texture: &Texture, font: &Font) { + canvas.clear(); - // Lounge - canvas.copy( - texture, - Rect::new(5, 700, 150, 95), - Rect::new(325, 260, 150, 95), - ); + canvas.set_draw_color(Color::RGB(160, 90, 44)); + canvas.fill_rect(Rect::new(0, 0, 800, 45)); - // Box Areas - self.right_top_box_area.render(canvas, texture); - self.right_bottom_box_area.render(canvas, texture); - self.left_bottom_box_area.render(canvas, texture); - self.left_top_box_area.render(canvas, texture); + canvas.set_draw_color(Color::RGB(206, 182, 115)); - // Decoration - canvas.copy( - texture, - Rect::new(130, 550, 25, 25), - Rect::new(235, 130, 25, 25), - ); - canvas.copy( - texture, - Rect::new(130, 550, 25, 25), - Rect::new(120, 210, 25, 25), - ); - canvas.copy( - texture, - Rect::new(130, 550, 25, 25), - Rect::new(535, 150, 25, 25), - ); - canvas.copy( - texture, - Rect::new(130, 550, 25, 25), - Rect::new(435, 370, 25, 25), - ); - canvas.copy( - texture, - Rect::new(130, 550, 25, 25), - Rect::new(235, 470, 25, 25), - ); - canvas.copy( - texture, - Rect::new(130, 550, 25, 25), - Rect::new(555, 510, 25, 25), - ); + // Points/Glasses + (1..=GLASS_SPACE).for_each(|i| { + canvas.set_draw_color(Color::RGB(128, 51, 0)); + canvas.fill_rect(Rect::new(5, 37, GLASS_SPACE as u32 * 25 + 5, 4)); - // Stops - for s in &self.stops { + if self.player.filled_glasses + self.player.empty_glasses >= i { canvas.copy( texture, - Rect::new(130, 510, 25, 25), - Rect::new(s.x(), s.y(), 25, 25), + Rect::new(35, 510, 20, 25), + Rect::new((i as i32) * 25 - 15, 10, 20, 25), ); } - - // Player - canvas.copy( - texture, - self.player.sprite(), - Rect::new(self.player.position.x(), self.player.position.y(), 40, 115), - ); - - // Points - let x = font - .render(format!("Score: {:#04}", self.player.points).as_str()) - .blended(Color::RGBA(246, 222, 155, 255)) - .unwrap(); - let t2 = canvas.texture_creator(); - let t2 = t2.create_texture_from_surface(&x).unwrap(); - - canvas.copy( - &t2, - x.rect(), - Some(Rect::new(790 - x.width() as i32, 8, x.width(), x.height())), - ); - canvas.set_draw_color(Color::RGB(206, 182, 115)); - - canvas.present(); - } - } - - #[derive(Debug)] - pub struct BoxArea { - position: BoxAreaPosition, - pub content: BoxAreaContent, - last_update: i64, - } - - impl BoxArea { - fn new(position: BoxAreaPosition, content: BoxAreaContent) -> BoxArea { - return BoxArea { - position, - content, - last_update: chrono::Utc::now().timestamp(), - }; - } - - pub fn update_content(&mut self, content: BoxAreaContent) { - self.content = content; - self.last_update = chrono::Utc::now().timestamp(); - } - - fn bounding_rect(&self) -> Rect { - let x_offset = match self.position { - BoxAreaPosition::RightTop => 685, - BoxAreaPosition::RightBottom => 685, - BoxAreaPosition::LeftBottom => 5, - BoxAreaPosition::LeftTop => 5, - }; - let y_offset = match self.position { - BoxAreaPosition::RightTop => 50, - BoxAreaPosition::RightBottom => 480, - BoxAreaPosition::LeftBottom => 480, - BoxAreaPosition::LeftTop => 50, - }; - - Rect::new(x_offset, y_offset, 110, 110) - } - - fn enter_rect(&self) -> Rect { - match self.position { - BoxAreaPosition::RightTop => { - Rect::new(self.bounding_rect().x(), self.bounding_rect().y(), 25, 110) - } - BoxAreaPosition::RightBottom => { - Rect::new(self.bounding_rect().x(), self.bounding_rect().y(), 25, 110) - } - BoxAreaPosition::LeftBottom => Rect::new( - self.bounding_rect().x() + 85, - self.bounding_rect().y(), - 25, - 110, - ), - BoxAreaPosition::LeftTop => Rect::new( - self.bounding_rect().x() + 85, - self.bounding_rect().y(), - 25, - 110, - ), + if self.player.filled_glasses >= i { + canvas.copy( + texture, + Rect::new(5, 510, 20, 25), + Rect::new((i as i32) * 25 - 15, 10, 20, 25), + ); } + }); + + // Lounge + canvas.copy( + texture, + Rect::new(5, 700, 150, 95), + Rect::new(325, 260, 150, 95), + ); + + // Box Areas + self.right_top_box_area.render(canvas, texture); + self.right_bottom_box_area.render(canvas, texture); + self.left_bottom_box_area.render(canvas, texture); + self.left_top_box_area.render(canvas, texture); + + // Decoration + canvas.copy( + texture, + Rect::new(130, 550, 25, 25), + Rect::new(235, 130, 25, 25), + ); + canvas.copy( + texture, + Rect::new(130, 550, 25, 25), + Rect::new(120, 210, 25, 25), + ); + canvas.copy( + texture, + Rect::new(130, 550, 25, 25), + Rect::new(535, 150, 25, 25), + ); + canvas.copy( + texture, + Rect::new(130, 550, 25, 25), + Rect::new(435, 370, 25, 25), + ); + canvas.copy( + texture, + Rect::new(130, 550, 25, 25), + Rect::new(235, 470, 25, 25), + ); + canvas.copy( + texture, + Rect::new(130, 550, 25, 25), + Rect::new(555, 510, 25, 25), + ); + + // Stops + for s in &self.stops { + canvas.copy( + texture, + Rect::new(130, 510, 25, 25), + Rect::new(s.x(), s.y(), 25, 25), + ); } - fn collides_with(&self, player: &Player) -> bool { - self.bounding_rect().contains_point(player.center()) - } + // Player + canvas.copy( + texture, + self.player.sprite(), + Rect::new(self.player.position.x(), self.player.position.y(), 40, 115), + ); - fn render(&self, canvas: &mut WindowCanvas, texture: &Texture) { - let x_offset = self.bounding_rect().x(); - let y_offset = self.bounding_rect().y(); + // Points + let x = font + .render(format!("Score: {:#04}", self.player.points).as_str()) + .blended(Color::RGBA(246, 222, 155, 255)) + .unwrap(); + let t2 = canvas.texture_creator(); + let t2 = t2.create_texture_from_surface(&x).unwrap(); - // Border - canvas.copy( - texture, - Rect::new(70, 510, 50, 25), - Rect::new(x_offset + 30, y_offset, 50, 25), - ); - canvas.copy( - texture, - Rect::new(70, 510, 50, 25), - Rect::new(x_offset + 30, y_offset + 85, 50, 25), - ); - let dst = match self.position { - BoxAreaPosition::RightTop => Rect::new(x_offset + 85, y_offset + 30, 25, 50), - BoxAreaPosition::RightBottom => Rect::new(x_offset + 85, y_offset + 30, 25, 50), - BoxAreaPosition::LeftBottom => Rect::new(x_offset, y_offset + 30, 25, 50), - BoxAreaPosition::LeftTop => Rect::new(x_offset, y_offset + 30, 25, 50), - }; - canvas.copy(texture, Rect::new(70, 550, 25, 50), dst); + canvas.copy( + &t2, + x.rect(), + Some(Rect::new(790 - x.width() as i32, 8, x.width(), x.height())), + ); + canvas.set_draw_color(Color::RGB(206, 182, 115)); - // Box - let box_src = match self.content { - BoxAreaContent::Nothing => Rect::new(70, 620, 50, 50), - BoxAreaContent::HiddenBox => Rect::new(5, 620, 50, 50), - BoxAreaContent::EmptyGlass => Rect::new(35, 510, 20, 25), - BoxAreaContent::FilledBottle => Rect::new(5, 550, 20, 50), - BoxAreaContent::EmptyBottle => Rect::new(35, 550, 20, 50), - }; - let (box_width, box_height) = match self.content { - BoxAreaContent::Nothing => (50, 50), - BoxAreaContent::HiddenBox => (50, 50), - BoxAreaContent::EmptyGlass => (20, 25), - BoxAreaContent::FilledBottle => (20, 50), - BoxAreaContent::EmptyBottle => (20, 50), - }; - canvas.copy( - texture, - box_src, - Rect::new( - x_offset + 30 + (50 - box_width) / 2, - y_offset + 30 + (50 - box_height) / 2, - box_width as u32, - box_height as u32, - ), - ); + canvas.present(); + } +} + +#[derive(Debug)] +pub struct BoxArea { + position: BoxAreaPosition, + pub content: BoxAreaContent, + last_update: i64, +} + +impl BoxArea { + fn new(position: BoxAreaPosition, content: BoxAreaContent) -> BoxArea { + BoxArea { + position, + content, + last_update: chrono::Utc::now().timestamp(), } } - #[derive(Debug)] - pub enum BoxAreaPosition { - RightTop, - RightBottom, - LeftBottom, - LeftTop, + pub fn update_content(&mut self, content: BoxAreaContent) { + self.content = content; + self.last_update = chrono::Utc::now().timestamp(); } - #[derive(Debug, PartialEq, Eq)] - pub enum BoxAreaContent { - Nothing, - HiddenBox, - EmptyGlass, - FilledBottle, - EmptyBottle, + fn bounding_rect(&self) -> Rect { + let x_offset = match self.position { + BoxAreaPosition::RightTop => 685, + BoxAreaPosition::RightBottom => 685, + BoxAreaPosition::LeftBottom => 5, + BoxAreaPosition::LeftTop => 5, + }; + let y_offset = match self.position { + BoxAreaPosition::RightTop => 50, + BoxAreaPosition::RightBottom => 480, + BoxAreaPosition::LeftBottom => 480, + BoxAreaPosition::LeftTop => 50, + }; + + Rect::new(x_offset, y_offset, 110, 110) } - impl BoxAreaContent { - pub fn random() -> BoxAreaContent { - match rand::random::() % 5 { - 1 | 4 => BoxAreaContent::EmptyGlass, - 2 | 3 => BoxAreaContent::FilledBottle, - _ => BoxAreaContent::Nothing, + fn enter_rect(&self) -> Rect { + match self.position { + BoxAreaPosition::RightTop => { + Rect::new(self.bounding_rect().x(), self.bounding_rect().y(), 25, 110) } + BoxAreaPosition::RightBottom => { + Rect::new(self.bounding_rect().x(), self.bounding_rect().y(), 25, 110) + } + BoxAreaPosition::LeftBottom => Rect::new( + self.bounding_rect().x() + 85, + self.bounding_rect().y(), + 25, + 110, + ), + BoxAreaPosition::LeftTop => Rect::new( + self.bounding_rect().x() + 85, + self.bounding_rect().y(), + 25, + 110, + ), + } + } + + fn collides_with(&self, player: &Player) -> bool { + self.bounding_rect().contains_point(player.center()) + } + + fn render(&self, canvas: &mut WindowCanvas, texture: &Texture) { + let x_offset = self.bounding_rect().x(); + let y_offset = self.bounding_rect().y(); + + // Border + canvas.copy( + texture, + Rect::new(70, 510, 50, 25), + Rect::new(x_offset + 30, y_offset, 50, 25), + ); + canvas.copy( + texture, + Rect::new(70, 510, 50, 25), + Rect::new(x_offset + 30, y_offset + 85, 50, 25), + ); + let dst = match self.position { + BoxAreaPosition::RightTop => Rect::new(x_offset + 85, y_offset + 30, 25, 50), + BoxAreaPosition::RightBottom => Rect::new(x_offset + 85, y_offset + 30, 25, 50), + BoxAreaPosition::LeftBottom => Rect::new(x_offset, y_offset + 30, 25, 50), + BoxAreaPosition::LeftTop => Rect::new(x_offset, y_offset + 30, 25, 50), + }; + canvas.copy(texture, Rect::new(70, 550, 25, 50), dst); + + // Box + let box_src = match self.content { + BoxAreaContent::Nothing => Rect::new(70, 620, 50, 50), + BoxAreaContent::HiddenBox => Rect::new(5, 620, 50, 50), + BoxAreaContent::EmptyGlass => Rect::new(35, 510, 20, 25), + BoxAreaContent::FilledBottle => Rect::new(5, 550, 20, 50), + BoxAreaContent::EmptyBottle => Rect::new(35, 550, 20, 50), + }; + let (box_width, box_height) = match self.content { + BoxAreaContent::Nothing => (50, 50), + BoxAreaContent::HiddenBox => (50, 50), + BoxAreaContent::EmptyGlass => (20, 25), + BoxAreaContent::FilledBottle => (20, 50), + BoxAreaContent::EmptyBottle => (20, 50), + }; + canvas.copy( + texture, + box_src, + Rect::new( + x_offset + 30 + (50 - box_width) / 2, + y_offset + 30 + (50 - box_height) / 2, + box_width as u32, + box_height as u32, + ), + ); + } +} + +#[derive(Debug)] +pub enum BoxAreaPosition { + RightTop, + RightBottom, + LeftBottom, + LeftTop, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum BoxAreaContent { + Nothing, + HiddenBox, + EmptyGlass, + FilledBottle, + EmptyBottle, +} + +impl BoxAreaContent { + pub fn random() -> BoxAreaContent { + match rand::random::() % 5 { + 1 | 4 => BoxAreaContent::EmptyGlass, + 2 | 3 => BoxAreaContent::FilledBottle, + _ => BoxAreaContent::Nothing, } } }