Working on collisions
This commit is contained in:
parent
cd1befafa5
commit
94f10594df
|
@ -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 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 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 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 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 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
|
||||||
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 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 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
|
||||||
|
|
|
@ -402,21 +402,109 @@ impl Map {
|
||||||
pub fn collides_point(&self, old: Vector2<f32>, new: Vector2<f32>)
|
pub fn collides_point(&self, old: Vector2<f32>, new: Vector2<f32>)
|
||||||
-> Option<(CollisionAxis, Vector2<f32>)> {
|
-> Option<(CollisionAxis, Vector2<f32>)> {
|
||||||
|
|
||||||
let height = new.y - old.y;
|
let vert = self.collides_point_vertical(old, new);
|
||||||
let mut y = (old.y / 16.0).ceil() * 16.0;
|
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 width = new.y - old.y;
|
||||||
let x = old.x + (new.x - old.x) * current_height / height;
|
|
||||||
|
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
|
// Find tile on x, y
|
||||||
if x > 0.0 && y > 0.0 {
|
if x > 0.0 && y > 0.0 {
|
||||||
|
|
||||||
let row = (y / 16.0) as usize;
|
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;
|
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 {
|
if tile.from_top {
|
||||||
return Some((CollisionAxis::Y, Vector2::new(x, y)));
|
return Some((CollisionAxis::Y, Vector2::new(x, y)));
|
||||||
}
|
}
|
||||||
|
@ -424,10 +512,11 @@ impl Map {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
y += 16.0;
|
row += height.signum() as isize;
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue