diff --git a/Cargo.lock b/Cargo.lock index 8b6e047..5646199 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,27 @@ name = "super-matte-bros" version = "0.0.1" dependencies = [ - "sdl2 0.0.13 (git+https://github.com/AngryLawyer/rust-sdl2)", + "sdl2 0.0.14 (git+https://github.com/AngryLawyer/rust-sdl2)", ] [[package]] -name = "sdl2" -version = "0.0.13" -source = "git+https://github.com/AngryLawyer/rust-sdl2#1e9a96755780b757ed8833c16b17396b33e5eb15" +name = "pkg-config" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "sdl2" +version = "0.0.14" +source = "git+https://github.com/AngryLawyer/rust-sdl2#7ff85a93a677ed8a02f4e49109a8613a7544aa21" +dependencies = [ + "sdl2-sys 0.0.14 (git+https://github.com/AngryLawyer/rust-sdl2)", +] + +[[package]] +name = "sdl2-sys" +version = "0.0.14" +source = "git+https://github.com/AngryLawyer/rust-sdl2#7ff85a93a677ed8a02f4e49109a8613a7544aa21" +dependencies = [ + "pkg-config 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] diff --git a/src/main.rs b/src/main.rs index 693da64..1930989 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ extern crate sdl2; -use std::num::SignedInt; use std::cmp::{max, min}; use sdl2::video::{Window, WindowPos, OPENGL}; @@ -11,7 +10,6 @@ use sdl2::rect::Rect; use sdl2::keycode::KeyCode; use sdl2::pixels::Color; -use vec::Vec2; use tile::Layer; use player::Player; @@ -30,7 +28,7 @@ const TILE_HEIGHT : i32 = 32; const MS_PER_UPDATE : uint = 10; -#[deriving(Clone)] +#[derive(Clone, Show)] enum Tile { Empty, Floor @@ -53,6 +51,10 @@ impl Camera { height: height } } + + fn get_rect(&self) -> Rect { + Rect::new(self.x, self.y, self.width, self.height) + } } @@ -69,7 +71,7 @@ fn main() { Err(err) => panic!("failed to create renderer: {}", err) }; - let mut camera = Camera::new(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + let camera = Camera::new(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); let mut layer = Layer::new(30, 20, TILE_WIDTH, TILE_HEIGHT, Tile::Empty); for x in range(0, 14) { @@ -105,6 +107,7 @@ fn main() { } else if key == KeyCode::Up { if player.on_ground { player.velocity.y = -12.0; + player.on_ground = false; } } @@ -126,59 +129,58 @@ fn main() { while lag >= MS_PER_UPDATE { player.update(); - player.on_ground = false; + layer.for_each_intersecting(&player.get_rect(), |tile: &Tile, x: i32, y: i32| { + match *tile { + Tile::Empty => (), + Tile::Floor => { + let object = Rect::new(x, y, TILE_WIDTH, TILE_HEIGHT); - let tiles_intersect = layer.get_intersecting(&player.get_rect()); + if collision_detection(&object, &player.get_rect()) { + let intersect = collision_intersect(&object, &player.get_rect()); - let mut skip = false; - - if tiles_intersect.x < 0 || tiles_intersect.x + tiles_intersect.w > 30 - 1 { - skip = true; - } - else if tiles_intersect.y < 0 || tiles_intersect.y + tiles_intersect.h > 20 - 1 { - skip = true; - } - - if skip == false { - for y in range(tiles_intersect.y, tiles_intersect.y + tiles_intersect.h + 1) { - for x in range(tiles_intersect.x, tiles_intersect.x + tiles_intersect.w + 1) { - let player_rect = player.get_rect(); - - match *layer.get_tile(x, y) { - Tile::Empty => (), - Tile::Floor => { - let object_rect = Rect::new(x * TILE_WIDTH, y * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT); - - if collision_detection(&object_rect, &player_rect) { - let intersect = collision_intersect(&object_rect, &player_rect); - - if intersect.w >= intersect.h { - let mut delta = intersect.h as f32; - - if player.velocity.y >= 0.0 { - delta *= -1.0; - } - - player.position.y += delta; - player.velocity.y = 0.0; - - player.on_ground = true; - } else { - let mut delta = intersect.w as f32; - - if player.velocity.x >= 0.0 { - delta *= -1.0; - } - - player.position.x += delta; - player.velocity.x = 0.0; - } + if intersect.w >= intersect.h { + if player.velocity.y < 0.0 { + player.position.y += intersect.h as f32; + } else { + player.position.y -= intersect.h as f32; } + + player.velocity.y = 0.0; + + player.on_ground = true; + } else { + if player.velocity.x < 0.0 { + player.position.x += intersect.w as f32; + } else { + player.position.x -= intersect.w as f32; + } + + player.velocity.x = 0.0; } } } } - } + }); + + player.on_ground = false; + + let mut ground = player.get_rect(); + + ground.y += ground.h; + ground.h = 1; + + layer.for_each_intersecting(&ground, |tile: &Tile, x: i32, y: i32| { + match *tile { + Tile::Empty => (), + Tile::Floor => { + let object = Rect::new(x, y, TILE_WIDTH, TILE_HEIGHT); + + if collision_detection(&object, &ground) { + player.on_ground = true; + } + } + } + }); lag -= MS_PER_UPDATE; } @@ -186,17 +188,15 @@ fn main() { let _ = renderer.set_draw_color(Color::RGB(0, 0, 0)); let _ = renderer.clear(); - for y in range(0, 20) { - for x in range(0, 30) { - match *layer.get_tile(x, y) { - Tile::Empty => (), - Tile::Floor => { - let _ = renderer.set_draw_color(Color::RGB(0, 0, 255)); - let _ = renderer.fill_rect(&Rect::new(x * TILE_WIDTH, y * TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT)); - } + layer.for_each_intersecting(&camera.get_rect(), |tile: &Tile, x: i32, y: i32| { + match *tile { + Tile::Empty => (), + Tile::Floor => { + let _ = renderer.set_draw_color(Color::RGB(0, 0, 255)); + let _ = renderer.fill_rect(&Rect::new(x, y, TILE_WIDTH, TILE_HEIGHT)); } } - } + }); player.render(&renderer); diff --git a/src/tile.rs b/src/tile.rs index 358e824..b6751f6 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -1,9 +1,13 @@ +use std::iter::repeat; +use std::cmp::{min, max}; + use sdl2::rect::Rect; pub struct Layer { tiles: Vec, width: i32, + height: i32, tile_width: i32, tile_height: i32 } @@ -11,8 +15,9 @@ pub struct Layer { impl Layer where T: Clone { pub fn new(width: i32, height: i32, tile_width: i32, tile_height: i32, tile: T) -> Layer { Layer { - tiles: Vec::from_elem((width * height) as uint, tile), + tiles: repeat(tile).take((width * height) as uint).collect(), width: width, + height: height, tile_width: tile_width, tile_height: tile_height } @@ -21,22 +26,38 @@ impl Layer where T: Clone { pub fn get_tile(&self, x: i32, y: i32) -> &T { let offset = (x + y * self.width) as uint; - self.tiles.index(&offset) + &self.tiles[offset] } pub fn set_tile(&mut self, x: i32, y: i32, tile: T) { let offset = (x + y * self.width) as uint; - *self.tiles.index_mut(&offset) = tile; + self.tiles[offset] = tile; } pub fn get_intersecting(&self, rect: &Rect) -> Rect { - let x = rect.x / self.tile_width; - let w = rect.w / self.tile_width; + let x1 = max(rect.x / self.tile_width, 0); + let y1 = max(rect.y / self.tile_height, 0); + let x2 = min((rect.x + rect.w - 1) / self.tile_width, self.width - 1); + let y2 = min((rect.y + rect.h - 1) / self.tile_height, self.height - 1); - let y = rect.y / self.tile_height; - let h = rect.h / self.tile_height; + Rect::new(x1, y1, x2 - x1, y2 - y1) + } - Rect::new(x, y, w, h) + pub fn for_each_intersecting(&self, rect: &Rect, mut f: F) where F: FnMut(&T, i32, i32) { + let intersect = self.get_intersecting(rect); + + if intersect.x < 0 || intersect.x + intersect.w > self.width { + return; + } + else if intersect.y < 0 || intersect.y + intersect.h > self.height { + return; + } + + for y in range(intersect.y, intersect.y + intersect.h + 1) { + for x in range(intersect.x, intersect.x + intersect.w + 1) { + f(self.get_tile(x, y), x * self.tile_width, y * self.tile_height); + } + } } } diff --git a/src/vec.rs b/src/vec.rs index a17f379..549bd87 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -1,3 +1,4 @@ +#[derive(Show)] pub struct Vec2 { pub x: T, pub y: T