better collision logic for tiles
This commit is contained in:
122
src/main.rs
122
src/main.rs
@@ -1,7 +1,7 @@
|
|||||||
extern crate sdl2;
|
extern crate sdl2;
|
||||||
|
|
||||||
use std::num::Float;
|
use std::num::Float;
|
||||||
use std::iter::range_step_inclusive;
|
use std::iter::range_step;
|
||||||
|
|
||||||
use sdl2::video::{Window, WindowPos, OPENGL};
|
use sdl2::video::{Window, WindowPos, OPENGL};
|
||||||
use sdl2::event::{poll_event, Event};
|
use sdl2::event::{poll_event, Event};
|
||||||
@@ -140,88 +140,126 @@ fn main() {
|
|||||||
|
|
||||||
player.on_ground = false;
|
player.on_ground = false;
|
||||||
|
|
||||||
if let Some(intersecting) = layer.find_intersecting(&player.to_rect()) {
|
if let Some(intersect) = layer.find_intersecting(&player.to_rect()) {
|
||||||
if player.dx > 0.0 {
|
if player.dx > 0.0 {
|
||||||
let p_x = player.x + player.w as f32;
|
let p = player.x + player.w as f32;
|
||||||
let t_x = intersecting.x + intersecting.w;
|
let mut d = player.dx;
|
||||||
|
|
||||||
let mut d_x = player.dx;
|
for y in range(intersect.y, intersect.y + intersect.h + 1) {
|
||||||
|
let mut x = intersect.x;
|
||||||
|
|
||||||
for y in range_step_inclusive(intersecting.y, intersecting.y + intersecting.h, 1) {
|
loop {
|
||||||
for x in range_step_inclusive(t_x, t_x + 1, 1) {
|
let t = (x * TILE_WIDTH) as f32 - p;
|
||||||
d_x = match *layer.get_tile(x, y) {
|
|
||||||
Tile::Empty => d_x,
|
if t > d {
|
||||||
Tile::Floor(_) => d_x.min((x * TILE_WIDTH) as f32 - p_x)
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo get_tile should return Option<Tile>
|
||||||
|
d = match *layer.get_tile(x, y) {
|
||||||
|
Tile::Empty => d,
|
||||||
|
Tile::Floor(_) => d.min(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
x += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if d_x > 0.0 {
|
if d > 0.0 {
|
||||||
player.x += d_x;
|
player.x += d;
|
||||||
} else {
|
} else {
|
||||||
player.dx = 0.0;
|
player.dx = 0.0;
|
||||||
}
|
}
|
||||||
} else if player.dx < 0.0 {
|
} else if player.dx < 0.0 {
|
||||||
let p_x = player.x;
|
let p = player.x;
|
||||||
let t_x = intersecting.x;
|
let mut d = player.dx;
|
||||||
|
|
||||||
let mut d_x = player.dx;
|
for y in range(intersect.y, intersect.y + intersect.h + 1) {
|
||||||
|
let mut x = intersect.x;
|
||||||
|
|
||||||
for y in range_step_inclusive(intersecting.y, intersecting.y + intersecting.h, 1) {
|
loop {
|
||||||
for x in range_step_inclusive(t_x, t_x - 1, -1) {
|
let t = (x * TILE_WIDTH + TILE_WIDTH) as f32 - p;
|
||||||
d_x = match *layer.get_tile(x, y) {
|
|
||||||
Tile::Empty => d_x,
|
if t < d {
|
||||||
Tile::Floor(_) => d_x.max((x * TILE_WIDTH + TILE_WIDTH) as f32 - p_x)
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo get_tile should return Option<Tile>
|
||||||
|
d = match *layer.get_tile(x, y) {
|
||||||
|
Tile::Empty => d,
|
||||||
|
Tile::Floor(_) => d.max(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
x -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if d_x < 0.0 {
|
if d < 0.0 {
|
||||||
player.x += d_x;
|
player.x += d;
|
||||||
} else {
|
} else {
|
||||||
player.dx = 0.0;
|
player.dx = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if player.dy > 0.0 {
|
if player.dy > 0.0 {
|
||||||
let p_y = player.y + player.h as f32;
|
let p = player.y + player.h as f32;
|
||||||
let t_y = intersecting.y + intersecting.h;
|
let mut d = player.dy;
|
||||||
|
|
||||||
let mut d_y = player.dy;
|
for x in range(intersect.x, intersect.x + intersect.w + 1) {
|
||||||
|
let mut y = intersect.y;
|
||||||
|
|
||||||
for y in range_step_inclusive(t_y, t_y + 1, 1) {
|
loop {
|
||||||
for x in range_step_inclusive(intersecting.x, intersecting.x + intersecting.w, 1) {
|
let t = (y * TILE_HEIGHT) as f32 - p;
|
||||||
d_y = match *layer.get_tile(x, y) {
|
|
||||||
Tile::Empty => d_y,
|
if t > d {
|
||||||
Tile::Floor(_) => d_y.min((y * TILE_HEIGHT) as f32 - p_y)
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo get_tile should return Option<Tile>
|
||||||
|
d = match *layer.get_tile(x, y) {
|
||||||
|
Tile::Empty => d,
|
||||||
|
Tile::Floor(_) => d.min(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
y += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if d_y > 0.0 {
|
if d > 0.0 {
|
||||||
player.y += d_y;
|
player.y += d;
|
||||||
} else {
|
} else {
|
||||||
player.dy = 0.0;
|
player.dy = 0.0;
|
||||||
|
|
||||||
player.on_ground = true;
|
player.on_ground = true;
|
||||||
}
|
}
|
||||||
} else if player.dy < 0.0 {
|
} else if player.dy < 0.0 {
|
||||||
let p_y = player.y;
|
let p = player.y;
|
||||||
let t_y = intersecting.y;
|
let mut d = player.dy;
|
||||||
|
|
||||||
let mut d_y = player.dy;
|
for x in range(intersect.x, intersect.x + intersect.w + 1) {
|
||||||
|
let mut y = intersect.y;
|
||||||
|
|
||||||
for y in range_step_inclusive(t_y, t_y - 1, -1) {
|
loop {
|
||||||
for x in range_step_inclusive(intersecting.x, intersecting.x + intersecting.w, 1) {
|
let t = (y * TILE_HEIGHT + TILE_HEIGHT) as f32 - p;
|
||||||
d_y = match *layer.get_tile(x, y) {
|
|
||||||
Tile::Empty => d_y,
|
println!("x={}, y={}, d={}, t={}", x, y, d, t);
|
||||||
Tile::Floor(_) => d_y.max((y * TILE_HEIGHT + TILE_HEIGHT) as f32 - p_y)
|
|
||||||
|
if t < d {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo get_tile should return Option<Tile>
|
||||||
|
d = match *layer.get_tile(x, y) {
|
||||||
|
Tile::Empty => d,
|
||||||
|
Tile::Floor(_) => d.max(t)
|
||||||
|
};
|
||||||
|
|
||||||
|
y -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if d_y < 0.0 {
|
if d < 0.0 {
|
||||||
player.y += d_y;
|
player.y += d;
|
||||||
} else {
|
} else {
|
||||||
player.dy = 0.0;
|
player.dy = 0.0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ impl<T> Layer<T> where T: Clone {
|
|||||||
let x2 = min((rect.x + rect.w - 1) / self.tile_width, self.width - 1);
|
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 y2 = min((rect.y + rect.h - 1) / self.tile_height, self.height - 1);
|
||||||
|
|
||||||
println!("{}, {}, {}, {}", x1, y1, x2, y2);
|
|
||||||
|
|
||||||
if x1 < 0 || x2 >= self.width {
|
if x1 < 0 || x2 >= self.width {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user