Can move tiles left/right
This commit is contained in:
parent
57b9c1d04d
commit
1e9e8ac303
5 changed files with 181 additions and 42 deletions
|
|
@ -27,6 +27,8 @@ impl Game for App {
|
|||
}
|
||||
|
||||
fn load(&mut self, _asset_store: &mut AssetStore) {
|
||||
self.board.generate_tile();
|
||||
self.board.generate_tile();
|
||||
}
|
||||
|
||||
fn key_press(
|
||||
|
|
@ -35,10 +37,10 @@ impl Game for App {
|
|||
_asset_store: &mut AssetStore
|
||||
) {
|
||||
if key == keyboard::Left {
|
||||
self.board.test_tile.start_moving(settings::TILE_MOVE_TIME, 0, 0);
|
||||
self.board.merge_from_right_to_left();
|
||||
}
|
||||
if key == keyboard::Right {
|
||||
self.board.test_tile.start_moving(settings::TILE_MOVE_TIME, 3, 0);
|
||||
self.board.merge_from_left_to_right();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
170
src/board.rs
170
src/board.rs
|
|
@ -1,37 +1,177 @@
|
|||
|
||||
use std::iter::range_step;
|
||||
use rand::random;
|
||||
use graphics::*;
|
||||
use piston::*;
|
||||
use settings;
|
||||
use tile::Tile;
|
||||
use tile::{
|
||||
Tile,
|
||||
TileStatic,
|
||||
};
|
||||
|
||||
pub struct Board {
|
||||
center: [f64, ..2],
|
||||
tiles: [[Option<Tile>, ..settings::TILE_WIDTH], ..settings::TILE_HEIGHT],
|
||||
pub test_tile: Tile,
|
||||
tiles: Vec<Tile>,
|
||||
}
|
||||
|
||||
impl Board {
|
||||
pub fn new() -> Board {
|
||||
Board {
|
||||
center: [0.0, 0.0],
|
||||
tiles: [
|
||||
[None, None, None, None],
|
||||
[None, None, None, None],
|
||||
[None, None, None, None],
|
||||
[None, None, None, None],
|
||||
],
|
||||
test_tile: Tile::new(16, 0, 0),
|
||||
tiles: Vec::<Tile>::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_tile(&mut self) {
|
||||
if self.tiles.len() == (settings::TILE_WIDTH * settings::TILE_HEIGHT) as uint {
|
||||
return;
|
||||
}
|
||||
|
||||
'generating: loop {
|
||||
let x = (random::<uint>() % settings::TILE_WIDTH as uint) as int;
|
||||
let y = (random::<uint>() % settings::TILE_HEIGHT as uint) as int;
|
||||
if self.get_tile(x, y).is_none() {
|
||||
self.tiles.push(Tile::new(2, x, y));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, dt: f64) {
|
||||
self.test_tile.update(dt);
|
||||
for tile in self.tiles.mut_iter() {
|
||||
tile.update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&self, c: &Context, gl: &mut Gl) {
|
||||
self.render_board(c, gl);
|
||||
self.render_tiles(c, gl);
|
||||
self.test_tile.render(c, gl);
|
||||
}
|
||||
|
||||
pub fn can_merge(&self) -> bool {
|
||||
for row in range(0, settings::TILE_HEIGHT) {
|
||||
if !self.can_merge_row(row) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn merge_from_left_to_right(&mut self) {
|
||||
self.merge_row(settings::TILE_WIDTH - 1, -1, -1);
|
||||
}
|
||||
|
||||
pub fn merge_from_right_to_left(&mut self) {
|
||||
self.merge_row(0, settings::TILE_WIDTH, 1);
|
||||
}
|
||||
|
||||
fn merge_row(&mut self, x_start: int, x_end: int, x_step: int) {
|
||||
if self.is_locking() {
|
||||
return;
|
||||
}
|
||||
|
||||
// move all tiles to right place
|
||||
for row in range(0, settings::TILE_HEIGHT) {
|
||||
for col in range_step(x_start, x_end, x_step) {
|
||||
match self.get_mut_tile(col, row) {
|
||||
None => {
|
||||
match self.get_mut_next_tile(col, row, x_step, 0) {
|
||||
Some(ref mut tile) => {
|
||||
tile.start_moving(col, row);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// merge
|
||||
|
||||
self.generate_tile();
|
||||
}
|
||||
|
||||
fn can_merge_row(&self, row: int) -> bool {
|
||||
for col in range(0, settings::TILE_WIDTH) {
|
||||
match self.get_tile(col, row) {
|
||||
Some(ref tile) => {
|
||||
match self.get_next_tile(tile.tile_x, tile.tile_y, 1, 0) {
|
||||
Some(ref s_tile) => {
|
||||
if tile.score == s_tile.score {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_locking(&self) -> bool {
|
||||
for tile in self.tiles.iter() {
|
||||
if tile.status != TileStatic {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns next tile right besides (x, y)
|
||||
fn get_next_tile<'a>(&'a self, x: int, y: int, step_x: int, step_y: int) -> Option<&'a Tile> {
|
||||
let mut x = x + step_x;
|
||||
let mut y = y + step_y;
|
||||
while x >= 0 && x < settings::TILE_WIDTH
|
||||
&& y >= 0 && y < settings::TILE_HEIGHT {
|
||||
let tile = self.get_tile(x, y);
|
||||
if tile.is_some() {
|
||||
return tile;
|
||||
}
|
||||
x += step_x;
|
||||
y += step_y;
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn get_mut_next_tile<'a>(&'a mut self, x: int, y: int, step_x: int, step_y: int) -> Option<&'a mut Tile> {
|
||||
let mut x = x + step_x;
|
||||
let mut y = y + step_y;
|
||||
let mut found = false;
|
||||
while x >= 0 && x < settings::TILE_WIDTH
|
||||
&& y >= 0 && y < settings::TILE_HEIGHT {
|
||||
let tile = self.get_tile(x, y);
|
||||
if tile.is_some() {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
x += step_x;
|
||||
y += step_y;
|
||||
}
|
||||
|
||||
if found {
|
||||
self.get_mut_tile(x, y)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_tile<'a>(&'a self, x: int, y: int) -> Option<&'a Tile> {
|
||||
for tile in self.tiles.iter() {
|
||||
if tile.tile_x == x && tile.tile_y == y {
|
||||
return Some(tile);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn get_mut_tile<'a>(&'a mut self, x: int, y: int) -> Option<&'a mut Tile> {
|
||||
for tile in self.tiles.mut_iter() {
|
||||
if tile.tile_x == x && tile.tile_y == y {
|
||||
return Some(tile);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn render_board(&self, c: &Context, gl: &mut Gl) {
|
||||
|
|
@ -70,7 +210,7 @@ impl Board {
|
|||
fn render_tiles(&self, c: &Context, gl: &mut Gl) {
|
||||
for row in range(0, settings::TILE_HEIGHT) {
|
||||
for col in range(0, settings::TILE_WIDTH) {
|
||||
match self.tiles[row][col] {
|
||||
match self.get_tile(col, row) {
|
||||
Some(ref tile) => {
|
||||
tile.render(c, gl);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#![feature(globs)]
|
||||
|
||||
extern crate collections;
|
||||
extern crate rand;
|
||||
|
||||
extern crate graphics;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ pub static BOARD_SIZE: [f64, ..2] = [
|
|||
];
|
||||
pub static BOARD_OFFSET_Y: f64 = 128.0;
|
||||
|
||||
pub static TILE_WIDTH: uint = 4;
|
||||
pub static TILE_HEIGHT: uint = 4;
|
||||
pub static TILE_WIDTH: int = 4;
|
||||
pub static TILE_HEIGHT: int = 4;
|
||||
pub static TILE_SIZE: f64 = 96.0;
|
||||
pub static TILE_PADDING: f64 = 16.0;
|
||||
pub static TILE_BACKGROUND_COLOR: [f32, ..4] = [187.0 / 255.0, 173.0 / 255.0, 160.0 / 255.0, 1.0];
|
||||
|
|
|
|||
40
src/tile.rs
40
src/tile.rs
|
|
@ -3,17 +3,18 @@ use graphics::*;
|
|||
use piston::*;
|
||||
use settings;
|
||||
|
||||
enum TileState {
|
||||
#[deriving(Eq)]
|
||||
pub enum TileState {
|
||||
TileStatic,
|
||||
/// (t, x, y, destination_tile_x, destination_tile_y)
|
||||
TileMoving(f64, f64, f64, int, int),
|
||||
/// (t, x, y)
|
||||
TileMoving(f64, f64, f64),
|
||||
}
|
||||
|
||||
pub struct Tile {
|
||||
score: int,
|
||||
tile_x: int,
|
||||
tile_y: int,
|
||||
status: TileState,
|
||||
pub score: int,
|
||||
pub tile_x: int,
|
||||
pub tile_y: int,
|
||||
pub status: TileState,
|
||||
}
|
||||
|
||||
impl Tile {
|
||||
|
|
@ -32,27 +33,22 @@ impl Tile {
|
|||
(x, y)
|
||||
}
|
||||
|
||||
pub fn start_moving(&mut self, t: f64, destination_tile_x: int, destination_tile_y: int) {
|
||||
match self.status {
|
||||
TileStatic => {
|
||||
pub fn start_moving(&mut self, destination_tile_x: int, destination_tile_y: int) {
|
||||
let (x, y) = Tile::tile_to_pos(self.tile_x, self.tile_y);
|
||||
self.status = TileMoving(t, x, y, destination_tile_x, destination_tile_y);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
self.status = TileMoving(settings::TILE_MOVE_TIME, x, y);
|
||||
self.tile_x = destination_tile_x;
|
||||
self.tile_y = destination_tile_y;
|
||||
}
|
||||
|
||||
pub fn update(&mut self, dt: f64) {
|
||||
match self.status {
|
||||
TileMoving(t, x, y, dtx, dty) => {
|
||||
TileMoving(t, x, y) => {
|
||||
if dt >= t {
|
||||
self.tile_x = dtx;
|
||||
self.tile_y = dty;
|
||||
self.status = TileStatic;
|
||||
} else {
|
||||
let (dx, dy) = Tile::tile_to_pos(dtx, dty);
|
||||
let (dx, dy) = Tile::tile_to_pos(self.tile_x, self.tile_y);
|
||||
let factor = dt / t;
|
||||
self.status = TileMoving(t - dt, x + factor * (dx - x), y + factor * (dy - y), dtx, dty);
|
||||
self.status = TileMoving(t - dt, x + factor * (dx - x), y + factor * (dy - y));
|
||||
}
|
||||
},
|
||||
TileStatic => {},
|
||||
|
|
@ -62,12 +58,12 @@ impl Tile {
|
|||
pub fn render(&self, c: &Context, gl: &mut Gl) {
|
||||
let mut pos = (0.0, 0.0);
|
||||
match self.status {
|
||||
TileMoving(_, x, y) => {
|
||||
pos = (x, y);
|
||||
},
|
||||
TileStatic => {
|
||||
pos = Tile::tile_to_pos(self.tile_x, self.tile_y);
|
||||
},
|
||||
TileMoving(_, x, y, _, _) => {
|
||||
pos = (x, y);
|
||||
}
|
||||
}
|
||||
let (x, y) = pos;
|
||||
let color = self.get_color();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue