From e8c81d20cf24dfe5781ce1d9771911553459dacf Mon Sep 17 00:00:00 2001 From: Alexander Kuvaev Date: Sat, 29 Aug 2015 16:50:11 +0300 Subject: [PATCH] feat(UI): added ui drawing --- src/field.rs | 29 +++++++++--------- src/game.rs | 31 ++++++++++++++----- src/main.rs | 3 +- src/ui.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 24 deletions(-) create mode 100644 src/ui.rs diff --git a/src/field.rs b/src/field.rs index 7644040..7413125 100644 --- a/src/field.rs +++ b/src/field.rs @@ -5,7 +5,7 @@ use piston_window::*; pub enum Content { Number(u8), - Bomb, + Mine, None } @@ -70,7 +70,7 @@ impl Field { self.clear(); for _i in 0..self.mines { let ind = rand::thread_rng().gen_range(0, self.size); - self.get_cell_mut(ind).content = Content::Bomb + self.get_cell_mut(ind).content = Content::Mine } let mut i: i32 = -1; let w = self.width as i32; @@ -78,24 +78,24 @@ impl Field { i += 1; match self.get_content_safe(i) { Some(&Content::None) => { - let ct_bomb = |b| { + let ct_mine = |b| { match b { true => 1, false => 0 } }; // don`t care about row - let mut ct = ct_bomb(self.is_bomb_safe(i-w)) + - ct_bomb(self.is_bomb_safe(i+w)); + let mut ct = ct_mine(self.is_mine_safe(i-w)) + + ct_mine(self.is_mine_safe(i+w)); if i % w > 0 { // check left side position - ct += ct_bomb(self.is_bomb_safe(i-w-1)) + - ct_bomb(self.is_bomb_safe(i-1)) + - ct_bomb(self.is_bomb_safe(i+w-1)); + ct += ct_mine(self.is_mine_safe(i-w-1)) + + ct_mine(self.is_mine_safe(i-1)) + + ct_mine(self.is_mine_safe(i+w-1)); } if i % w < w - 1 { // check right side position - ct += ct_bomb(self.is_bomb_safe(i-w+1)) + - ct_bomb(self.is_bomb_safe(i+1)) + - ct_bomb(self.is_bomb_safe(i+w+1)); + ct += ct_mine(self.is_mine_safe(i-w+1)) + + ct_mine(self.is_mine_safe(i+1)) + + ct_mine(self.is_mine_safe(i+w+1)); } if ct > 0 { self.get_cell_mut(i as u32).content = Content::Number(ct); @@ -150,9 +150,9 @@ impl Field { &self.get_cell(i).content } - fn is_bomb_safe(&self, i: i32) -> bool { + fn is_mine_safe(&self, i: i32) -> bool { match self.get_content_safe(i) { - Some(&Content::Bomb) => true, + Some(&Content::Mine) => true, _ => false } } @@ -228,7 +228,7 @@ impl Field { continue; } match *self.get_content(i + j*self.get_width()) { - Content::Bomb => { + Content::Mine => { rectangle([1.0, 0.0, 0.0, 1.0], [ (field_rect[0] + i*cell_w) as f64, @@ -238,7 +238,6 @@ impl Field { ], context.transform, graphics); - }, Content::Number(n) => { let transform = context.transform.trans((field_rect[0] + i*cell_w) as f64 + 5.0, diff --git a/src/game.rs b/src/game.rs index a97f51c..6410020 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,22 +1,27 @@ use field::{Field, Content, MoveDestination}; +use ui::UI; use piston_window::*; -pub struct Game { +pub struct Game<'a> { field: Field, + ui: UI<'a>, glyphs: Glyphs, mouse_x: f64, mouse_y: f64, - game_ended: bool + game_ended: bool, + panel_width: u32 } -impl Game { - pub fn new(glyphs: Glyphs) -> Game { +impl<'a> Game<'a> { + pub fn new(glyphs: Glyphs, width: u32, height: u32, mines: u32) -> Game<'a> { Game { - field: Field::new(20, 15, 50), + field: Field::new(width, height, mines), + ui: UI::new(width, height, mines), glyphs: glyphs, mouse_x: 0.0, mouse_y: 0.0, - game_ended: false + game_ended: false, + panel_width: 350 } } @@ -25,17 +30,27 @@ impl Game { clear([0.0, 0.0, 0.0, 1.0], g); let field_rect = self.get_field_rect(window); self.field.draw(c, g, field_rect, &mut self.glyphs); + let ui_rect = self.get_ui_rect(window); + self.ui.draw(c, g, ui_rect, &mut self.glyphs); }); } fn get_field_rect(&self, window: &PistonWindow) -> [u32; 4] { - let mut w = 2*window.size().width/3; + let mut w = window.size().width - self.panel_width; w = (w /self.field.get_width()) * self.field.get_width(); let mut h = window.size().height; h = (h /self.field.get_height()) * self.field.get_height(); [0, 0, w, h] } + fn get_ui_rect(&self, window: &PistonWindow) -> [u32; 4] { + let mut field_w = window.size().width - self.panel_width; + field_w = (field_w /self.field.get_width()) * self.field.get_width(); + let w = window.size().width - field_w; + let h = window.size().height; + [field_w, 0, w, h] + } + pub fn proc_key(&mut self, button: Button, window: &PistonWindow) { match button { Button::Keyboard(key) => { @@ -80,7 +95,7 @@ impl Game { return; } match *self.field.reveal(i) { - Content::Bomb => { + Content::Mine => { self.field.reveal_all(); self.game_ended = true; println!("Game over :("); diff --git a/src/main.rs b/src/main.rs index cdba903..a519705 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ extern crate find_folder; mod game; mod field; +mod ui; use piston_window::*; use clap::{Arg, App}; @@ -39,7 +40,7 @@ fn main() { let factory = window.factory.borrow().clone(); let glyphs = Glyphs::new(font, factory).unwrap(); - let mut game = game::Game::new(glyphs); + let mut game = game::Game::new(glyphs, 20, 20, 50); for e in window { game.render(&e); diff --git a/src/ui.rs b/src/ui.rs new file mode 100644 index 0000000..ac24879 --- /dev/null +++ b/src/ui.rs @@ -0,0 +1,85 @@ +use piston_window::*; + +struct Block<'a> { + name: &'a str, + num: u32, + hotkey: char +} + +impl<'a> Block<'a> { + pub fn new(name: &'a str, num: u32, hotkey: char) -> Block<'a> { + Block { + name: name, + num: num, + hotkey: hotkey + } + } + + pub fn draw(&self, + context: Context, + graphics: &mut G2d, + rect: &mut [u32; 4], + glyps: &mut Glyphs) + { + let margin = 10; + let text_height = 20; + let block_height = 30; + let text_padding = 7; + rect[1] += 20; + rectangle([1.0, 1.0, 1.0, 1.0], + [ + (rect[0] + margin) as f64, + (rect[1]) as f64, + (rect[2] - 2*margin) as f64, + block_height as f64 + ], + context.transform, + graphics); + rect[1] += block_height; + let transform = context.transform.trans((rect[0] + margin + text_padding) as f64, + (rect[1] - text_padding) as f64); + text::Text::colored([0.0, 0.0, 0.0, 1.0], text_height).draw( + &*format!("{}: {}", self.name, self.num), + glyps, + &context.draw_state, + transform, + graphics + ); + rect[1] += margin + text_height/2; + let transform = context.transform.trans((rect[0] + margin) as f64, + (rect[1]) as f64); + text::Text::colored([1.0, 1.0, 1.0, 1.0], text_height).draw( + &*format!("press \"{}\" to change", self.hotkey), + glyps, + &context.draw_state, + transform, + graphics + ); + } +} + +pub struct UI<'a> { + blocks: Vec> +} + +impl<'a> UI<'a> { + pub fn new(height: u32, width: u32, mines: u32) -> UI<'a> { + UI { + blocks: vec![Block::new("Field height:", height, 'H'), + Block::new("Field width:", width, 'W'), + Block::new("Mines:", mines, 'M'), + ] + } + } + + pub fn draw(&mut self, + context: Context, + graphics: &mut G2d, + mut rect: [u32; 4], + glyps: &mut Glyphs) + { + for b in self.blocks.iter() { + b.draw(context, graphics, &mut rect, glyps); + } + } +} \ No newline at end of file