Compare commits

...

1 Commits

Author SHA1 Message Date
SimonFJ20
9ac727f2a1 skillissues 2024-04-11 22:58:27 +02:00
2 changed files with 71 additions and 35 deletions

View File

@ -33,16 +33,16 @@ enum Diagonal {
BottomLeft, BottomLeft,
} }
enum DiagonalCommonResult { enum DiagonalComparison {
None, None,
Direction(Direction), Direction(Direction),
Diagonal(Diagonal), Diagonal(Diagonal),
} }
impl Diagonal { impl Diagonal {
pub fn common(&self, other: &Diagonal) -> DiagonalCommonResult { pub fn common(&self, other: &Diagonal) -> DiagonalComparison {
use Diagonal::*; use Diagonal::*;
use DiagonalCommonResult as R; use DiagonalComparison as R;
use Direction::*; use Direction::*;
match (self, other) { match (self, other) {
(TopLeft, TopRight) => R::Direction(Top), (TopLeft, TopRight) => R::Direction(Top),
@ -57,24 +57,52 @@ impl Diagonal {
_ => R::None, _ => R::None,
} }
} }
pub fn opposing(&self, other: &Diagonal) -> DiagonalComparison {
use Diagonal::*;
use DiagonalComparison as R;
use Direction::*;
match (self, other) {
(TopLeft, TopRight) => R::Direction(Left),
(TopLeft, BottomLeft) => R::Direction(Top),
(TopRight, TopLeft) => R::Direction(Right),
(TopRight, BottomRight) => R::Direction(Top),
(BottomRight, TopRight) => R::Direction(Bottom),
(BottomRight, BottomLeft) => R::Direction(Right),
(BottomLeft, TopLeft) => R::Direction(Bottom),
(BottomLeft, BottomRight) => R::Direction(Left),
(left, right) if left == right => R::Diagonal(left.opposite()),
_ => R::None,
}
}
pub fn contains(&self, dir: Direction) -> bool { pub fn contains(&self, dir: Direction) -> bool {
use Diagonal::*;
use Direction::*;
match (self, dir) { match (self, dir) {
(Diagonal::TopLeft, Direction::Top) (TopLeft, Top)
| (Diagonal::TopLeft, Direction::Left) | (TopLeft, Left)
| (Diagonal::TopRight, Direction::Top) | (TopRight, Top)
| (Diagonal::TopRight, Direction::Left) | (TopRight, Left)
| (Diagonal::TopRight, Direction::Right) | (TopRight, Right)
| (Diagonal::BottomRight, Direction::Bottom) | (BottomRight, Bottom)
| (Diagonal::BottomRight, Direction::Right) | (BottomRight, Right)
| (Diagonal::BottomLeft, Direction::Bottom) | (BottomLeft, Bottom)
| (Diagonal::BottomLeft, Direction::Left) => true, | (BottomLeft, Left) => true,
(Diagonal::TopLeft, Direction::Bottom) (TopLeft, Bottom)
| (Diagonal::TopLeft, Direction::Right) | (TopLeft, Right)
| (Diagonal::TopRight, Direction::Bottom) | (TopRight, Bottom)
| (Diagonal::BottomRight, Direction::Top) | (BottomRight, Top)
| (Diagonal::BottomRight, Direction::Left) | (BottomRight, Left)
| (Diagonal::BottomLeft, Direction::Top) | (BottomLeft, Top)
| (Diagonal::BottomLeft, Direction::Right) => false, | (BottomLeft, Right) => false,
}
}
pub fn opposite(&self) -> Self {
use Diagonal::*;
match self {
TopLeft => BottomRight,
TopRight => BottomLeft,
BottomRight => TopLeft,
BottomLeft => TopRight,
} }
} }
} }
@ -185,34 +213,42 @@ fn rects_closet_points(
lowest.1 lowest.1
} }
fn point_vel_rect_collision(pos: V2, vel: V2, other_pos: V2, rect: V2) -> Option<V2> { fn point_delta_rect_collision(pos: V2, delta: V2, other_pos: V2, rect: V2) -> Option<V2> {
let c1 = point_rect_closest_point(pos, other_pos, rect); let c1 = point_rect_closest_point(pos, other_pos, rect);
let (c0, c2) = rect_adjacent_corners(other_pos, rect, c1); let (c0, c2) = rect_adjacent_corners(other_pos, rect, c1);
let intersection_c1_c0 = line_intersection(pos, vel, c1, (c0.0 - c1.0, c0.1 - c1.0))?; if let Some(intersection_c1_c0) = line_intersection(pos, delta, c1, (c0.0 - c1.0, c0.1 - c1.0))
if point_between_points(intersection_c1_c0, c1, c0) { {
return Some(intersection_c1_c0); println!("x intersect");
if point_between_points(intersection_c1_c0, c1, c0) {
println!(" x between points");
return Some(intersection_c1_c0);
}
} }
let intersection_c1_c2 = line_intersection(pos, vel, c1, (c2.0 - c1.0, c2.1 - c1.0))?; if let Some(intersection_c1_c2) = line_intersection(pos, delta, c1, (c2.0 - c1.0, c2.1 - c1.0))
if point_between_points(intersection_c1_c2, c1, c2) { {
return Some(intersection_c1_c2); println!("y intersect");
if point_between_points(intersection_c1_c2, c1, c2) {
println!(" y between points");
return Some(intersection_c1_c2);
}
} }
None None
} }
fn rect_collision( fn rect_collision(
pos: V2, pos: V2,
vel: V2, delta: V2,
rect: V2, rect: V2,
other_pos: V2, other_pos: V2,
other_rect: V2, other_rect: V2,
) -> Option<(V2, Direction)> { ) -> Option<(V2, Direction)> {
let ((p0, d0), (_, d1)) = rects_closet_points(pos, rect, other_pos, other_rect); let ((p0, d0), (_, d1)) = rects_closet_points(pos, rect, other_pos, other_rect);
let common = match d0.common(&d1) { let dir = match d0.opposing(&d1) {
DiagonalCommonResult::Direction(dir) => dir, DiagonalComparison::Direction(dir) => dir,
_ => return None, _ => return None,
}; };
let new_pos = point_vel_rect_collision(p0, vel, other_pos, other_rect)?; let new_pos = point_delta_rect_collision(p0, delta, other_pos, other_rect)?;
Some((new_pos, common)) Some((new_pos, dir))
} }
#[derive(Component, Clone, Default)] #[derive(Component, Clone, Default)]
@ -247,10 +283,10 @@ impl System for CollisionSystem {
continue; continue;
}; };
let body = ctx.entity_component::<RigidBody>(id); let body = ctx.entity_component::<RigidBody>(id);
body.pos = new_pos; // body.pos = new_pos;
match dir { match dir {
Direction::Top | Direction::Bottom => body.vel.0 = 0.0, Direction::Top | Direction::Bottom => body.vel.1 = 0.0,
Direction::Left | Direction::Right => body.vel.1 = 0.0, Direction::Left | Direction::Right => body.vel.0 = 0.0,
} }
} }
} }

View File

@ -141,7 +141,7 @@ fn main() {
context.add_system(CloudSystem); context.add_system(CloudSystem);
let player = context.load_sprite("textures/player.png").unwrap(); let player = context.load_sprite("textures/player.png").unwrap();
let background = context.load_sprite("textures/literally_dprk.png").unwrap(); let background = context.load_sprite("textures/literally_dprk.png").unwrap();
let nope = context.load_sprite("textures/nuh-uh.png").unwrap(); // let nope = context.load_sprite("textures/nuh-uh.png").unwrap();
spawn!( spawn!(
&mut context, &mut context,