Working on collisions

This commit is contained in:
Thomas Forgione 2018-10-06 14:13:31 +02:00
parent cd1befafa5
commit 94f10594df
2 changed files with 103 additions and 14 deletions

View File

@ -3,13 +3,13 @@
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1
1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1
1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

View File

@ -402,21 +402,109 @@ impl Map {
pub fn collides_point(&self, old: Vector2<f32>, new: Vector2<f32>)
-> Option<(CollisionAxis, Vector2<f32>)> {
let height = new.y - old.y;
let mut y = (old.y / 16.0).ceil() * 16.0;
let vert = self.collides_point_vertical(old, new);
let horiz = self.collides_point_horizontal(old, new);
match (vert, horiz) {
(Some(a), Some(b)) => {
if (old.x - a.1.x).abs() < (old.x - b.1.x).abs() {
Some(a)
} else {
Some(b)
}
},
(Some(a), None) => Some(a),
(None, Some(b)) => Some(b),
(None, None) => None,
}
}
while y < new.y {
/// Checks whether the vector (old, new) collides horizontally with an element of the map.
///
/// Returns the height of the collision if any.
pub fn collides_point_horizontal(&self, old: Vector2<f32>, new: Vector2<f32>)
-> Option<(CollisionAxis, Vector2<f32>)> {
let current_height = y - old.y;
let x = old.x + (new.x - old.x) * current_height / height;
let width = new.y - old.y;
if width == 0.0 {
return None;
}
let x = if width > 0.0 {
(old.x / 16.0).ceil() * 16.0
} else {
(old.x / 16.0).floor() * 16.0
};
let mut col = (x / 16.0) as isize;
while (col as f32 * 16.0 - new.x) * width.signum() < 0.0 {
let current_width = col as f32 * 16.0 - old.x;
let y = old.y + (new.y - old.y) * current_width / width;
// Find tile on x, y
if x > 0.0 && y > 0.0 {
let row = (y / 16.0) as usize;
let col = if width > 0.0 {
col
} else {
col - 1
};
if let Some((tile, _)) = self.tiles.get((row, col as usize)) {
if tile.from_top {
return Some((CollisionAxis::X, Vector2::new(x, y)));
}
}
}
col += width.signum() as isize;
}
None
}
/// Checks whether the vector (old, new) collides vertically with an element of the map.
///
/// Returns the height of the collision if any.
pub fn collides_point_vertical(&self, old: Vector2<f32>, new: Vector2<f32>)
-> Option<(CollisionAxis, Vector2<f32>)> {
let height = new.y - old.y;
if height == 0.0 {
return None;
}
let y = if height > 0.0 {
(old.y / 16.0).ceil() * 16.0
} else {
(old.y / 16.0).floor() * 16.0
};
let mut row = (y / 16.0) as isize;
while (row as f32 * 16.0 - new.y) * height.signum() < 0.0 {
let current_height = row as f32 * 16.0 - old.y;
let x = old.x + (new.x - old.x) * current_height / height;
// Find tile on x, y
if x > 0.0 && y > 0.0 {
let col = (x / 16.0) as usize;
if let Some((tile, _)) = self.tiles.get((row, col)) {
let row = if height > 0.0 {
row
} else {
row - 1
};
if let Some((tile, _)) = self.tiles.get((row as usize, col)) {
if tile.from_top {
return Some((CollisionAxis::Y, Vector2::new(x, y)));
}
@ -424,10 +512,11 @@ impl Map {
}
y += 16.0;
row += height.signum() as isize;
}
None
}
}