cowision hawd >~<
This commit is contained in:
parent
7cbde4f614
commit
a9ce9b6978
259
src/collision.rs
Normal file
259
src/collision.rs
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
use crate::{
|
||||||
|
engine::{self, Component, System},
|
||||||
|
query, RigidBody,
|
||||||
|
};
|
||||||
|
|
||||||
|
type V2 = (f64, f64);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum Direction {
|
||||||
|
Top,
|
||||||
|
Bottom,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Direction {
|
||||||
|
pub fn opposite(&self) -> Self {
|
||||||
|
use Direction::*;
|
||||||
|
match self {
|
||||||
|
Top => Bottom,
|
||||||
|
Bottom => Top,
|
||||||
|
Left => Right,
|
||||||
|
Right => Left,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
enum Diagonal {
|
||||||
|
TopLeft,
|
||||||
|
TopRight,
|
||||||
|
BottomRight,
|
||||||
|
BottomLeft,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DiagonalCommonResult {
|
||||||
|
None,
|
||||||
|
Direction(Direction),
|
||||||
|
Diagonal(Diagonal),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Diagonal {
|
||||||
|
pub fn common(&self, other: &Diagonal) -> DiagonalCommonResult {
|
||||||
|
use Diagonal::*;
|
||||||
|
use DiagonalCommonResult as R;
|
||||||
|
use Direction::*;
|
||||||
|
match (self, other) {
|
||||||
|
(TopLeft, TopRight) => R::Direction(Top),
|
||||||
|
(TopLeft, BottomLeft) => R::Direction(Left),
|
||||||
|
(TopRight, TopLeft) => R::Direction(Top),
|
||||||
|
(TopRight, BottomRight) => R::Direction(Right),
|
||||||
|
(BottomRight, TopRight) => R::Direction(Right),
|
||||||
|
(BottomRight, BottomLeft) => R::Direction(Bottom),
|
||||||
|
(BottomLeft, TopLeft) => R::Direction(Left),
|
||||||
|
(BottomLeft, BottomRight) => R::Direction(Bottom),
|
||||||
|
(left, right) if left == right => R::Diagonal(left.clone()),
|
||||||
|
_ => R::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn contains(&self, dir: Direction) -> bool {
|
||||||
|
match (self, dir) {
|
||||||
|
(Diagonal::TopLeft, Direction::Top)
|
||||||
|
| (Diagonal::TopLeft, Direction::Left)
|
||||||
|
| (Diagonal::TopRight, Direction::Top)
|
||||||
|
| (Diagonal::TopRight, Direction::Left)
|
||||||
|
| (Diagonal::TopRight, Direction::Right)
|
||||||
|
| (Diagonal::BottomRight, Direction::Bottom)
|
||||||
|
| (Diagonal::BottomRight, Direction::Right)
|
||||||
|
| (Diagonal::BottomLeft, Direction::Bottom)
|
||||||
|
| (Diagonal::BottomLeft, Direction::Left) => true,
|
||||||
|
(Diagonal::TopLeft, Direction::Bottom)
|
||||||
|
| (Diagonal::TopLeft, Direction::Right)
|
||||||
|
| (Diagonal::TopRight, Direction::Bottom)
|
||||||
|
| (Diagonal::BottomRight, Direction::Top)
|
||||||
|
| (Diagonal::BottomRight, Direction::Left)
|
||||||
|
| (Diagonal::BottomLeft, Direction::Top)
|
||||||
|
| (Diagonal::BottomLeft, Direction::Right) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn point_rect_closest_point(pos: V2, other_pos: V2, rect: V2) -> V2 {
|
||||||
|
[
|
||||||
|
other_pos,
|
||||||
|
(other_pos.0, other_pos.1 + rect.1),
|
||||||
|
(other_pos.0 + rect.0, other_pos.1),
|
||||||
|
(other_pos.0 + rect.0, other_pos.1 + rect.1),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| (p, point_distance(pos, p)))
|
||||||
|
.min_by(|(_, a), (_, b)| a.total_cmp(b))
|
||||||
|
.map(|(p, _)| p)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rect_adjacent_corners(pos: V2, rect: V2, corner: V2) -> (V2, (f64, f64)) {
|
||||||
|
if corner == pos {
|
||||||
|
((pos.0, pos.1 + rect.1), (pos.0 + rect.0, pos.1))
|
||||||
|
} else if corner == (pos.0 + rect.0, pos.1) {
|
||||||
|
(pos, (pos.0 + rect.0, pos.1 + rect.1))
|
||||||
|
} else if corner == (pos.0 + rect.0, pos.1 + rect.1) {
|
||||||
|
((pos.0 + rect.0, pos.1), (pos.0, pos.1 + rect.1))
|
||||||
|
} else if corner == (pos.0, pos.1 + rect.1) {
|
||||||
|
((pos.0 + rect.0, pos.1), pos)
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn line_intersection(p0: V2, r0: V2, p1: V2, r1: V2) -> Option<V2> {
|
||||||
|
if r0.0 == 0.0 && r1.0 == 0.0 {
|
||||||
|
// both vertical
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// y = ax + b
|
||||||
|
// a = y / x
|
||||||
|
let a0 = r0.1 / r0.0;
|
||||||
|
let a1 = r1.1 / r1.0;
|
||||||
|
if a0 == a1 {
|
||||||
|
// parallel
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
// b = y - ax
|
||||||
|
let b0 = p0.1 - a0 * p0.0;
|
||||||
|
let b1 = p1.1 - a1 * p1.0;
|
||||||
|
// y = a0 * x + b0
|
||||||
|
// y = a1 * x + b1
|
||||||
|
// a0 * x + b0 = a1 * x + b1
|
||||||
|
// a0 * x - a1 * x = b1 - b0
|
||||||
|
// x * (a0 - a1) = b1 - b0
|
||||||
|
// x = (b1 - b0) / (a0 - a1)
|
||||||
|
let x = (b1 - b0) / (a0 - a1);
|
||||||
|
let y = a0 * x + b0;
|
||||||
|
Some((x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn point_between_points(p: V2, p0: V2, p1: V2) -> bool {
|
||||||
|
let t = (p.0 - p0.0) / (p1.0 - p0.0);
|
||||||
|
0.0 < t && t < 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn point_distance(a: V2, b: (f64, f64)) -> f64 {
|
||||||
|
((a.0 - b.0).abs().powi(2) + (a.1 - b.1).abs().powi(2)).sqrt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rects_closet_points(
|
||||||
|
pos: V2,
|
||||||
|
rect: V2,
|
||||||
|
other_pos: V2,
|
||||||
|
other_rect: V2,
|
||||||
|
) -> ((V2, Diagonal), (V2, Diagonal)) {
|
||||||
|
use Diagonal::*;
|
||||||
|
let points = [
|
||||||
|
((pos.0, pos.1), TopLeft),
|
||||||
|
((pos.0 + rect.0, pos.1), TopRight),
|
||||||
|
((pos.0 + rect.0, pos.1 + rect.1), BottomRight),
|
||||||
|
((pos.0, pos.1 + rect.1), BottomLeft),
|
||||||
|
];
|
||||||
|
|
||||||
|
let other_points = [
|
||||||
|
((other_pos.0, other_pos.1), TopLeft),
|
||||||
|
((other_pos.0 + other_rect.0, other_pos.1), TopRight),
|
||||||
|
(
|
||||||
|
(other_pos.0 + other_rect.0, other_pos.1 + other_rect.1),
|
||||||
|
BottomRight,
|
||||||
|
),
|
||||||
|
((other_pos.0, other_pos.1 + other_rect.1), BottomLeft),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut lowest = (
|
||||||
|
f64::INFINITY,
|
||||||
|
(((0.0, 0.0), TopLeft), ((0.0, 0.0), TopLeft)),
|
||||||
|
);
|
||||||
|
for (point, dir) in points {
|
||||||
|
for (other_point, other_dir) in other_points.iter() {
|
||||||
|
let distance = point_distance(point, *other_point);
|
||||||
|
if distance < lowest.0 {
|
||||||
|
lowest = (
|
||||||
|
distance,
|
||||||
|
((point, dir.clone()), (*other_point, other_dir.clone())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lowest.1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn point_vel_rect_collision(pos: V2, vel: V2, other_pos: V2, rect: V2) -> Option<V2> {
|
||||||
|
let c1 = point_rect_closest_point(pos, other_pos, rect);
|
||||||
|
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 point_between_points(intersection_c1_c0, c1, c0) {
|
||||||
|
return Some(intersection_c1_c0);
|
||||||
|
}
|
||||||
|
let intersection_c1_c2 = line_intersection(pos, vel, c1, (c2.0 - c1.0, c2.1 - c1.0))?;
|
||||||
|
if point_between_points(intersection_c1_c2, c1, c2) {
|
||||||
|
return Some(intersection_c1_c2);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rect_collision(
|
||||||
|
pos: V2,
|
||||||
|
vel: V2,
|
||||||
|
rect: V2,
|
||||||
|
other_pos: V2,
|
||||||
|
other_rect: V2,
|
||||||
|
) -> Option<(V2, Direction)> {
|
||||||
|
let ((p0, d0), (_, d1)) = rects_closet_points(pos, rect, other_pos, other_rect);
|
||||||
|
let common = match d0.common(&d1) {
|
||||||
|
DiagonalCommonResult::Direction(dir) => dir,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
let new_pos = point_vel_rect_collision(p0, vel, other_pos, other_rect)?;
|
||||||
|
Some((new_pos, common))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Clone, Default)]
|
||||||
|
pub struct Collider {
|
||||||
|
pub resolve: bool,
|
||||||
|
pub on_ground: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CollisionSystem;
|
||||||
|
impl System for CollisionSystem {
|
||||||
|
fn on_update(&self, ctx: &mut engine::Context, delta: f64) -> Result<(), engine::Error> {
|
||||||
|
for id in query!(ctx, RigidBody, Collider) {
|
||||||
|
let collider = ctx.entity_component::<Collider>(id);
|
||||||
|
collider.on_ground = false;
|
||||||
|
let collider = ctx.entity_component::<Collider>(id).clone();
|
||||||
|
if !collider.resolve {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let body = ctx.entity_component::<RigidBody>(id).clone();
|
||||||
|
for other_id in query!(ctx, RigidBody, Collider) {
|
||||||
|
if id == other_id {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let other_body = ctx.entity_component::<RigidBody>(other_id).clone();
|
||||||
|
let Some((new_pos, dir)) = rect_collision(
|
||||||
|
body.pos,
|
||||||
|
(body.vel.0 * delta, body.vel.1 * delta),
|
||||||
|
body.rect,
|
||||||
|
other_body.pos,
|
||||||
|
other_body.rect,
|
||||||
|
) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let body = ctx.entity_component::<RigidBody>(id);
|
||||||
|
body.pos = new_pos;
|
||||||
|
match dir {
|
||||||
|
Direction::Top | Direction::Bottom => body.vel.0 = 0.0,
|
||||||
|
Direction::Left | Direction::Right => body.vel.1 = 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
233
src/main.rs
233
src/main.rs
@ -1,14 +1,11 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
mod cuwusions;
|
mod collision;
|
||||||
mod engine;
|
mod engine;
|
||||||
|
|
||||||
use engine::{Component, System};
|
use engine::{Component, System};
|
||||||
|
|
||||||
#[derive(Component)]
|
use crate::collision::{Collider, CollisionSystem};
|
||||||
struct Sprite {
|
|
||||||
sprite: engine::Sprite,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component, Default, Clone, Debug)]
|
#[derive(Component, Default, Clone, Debug)]
|
||||||
struct RigidBody {
|
struct RigidBody {
|
||||||
@ -23,153 +20,13 @@ impl System for VelocitySystem {
|
|||||||
fn on_update(&self, ctx: &mut engine::Context, delta: f64) -> Result<(), engine::Error> {
|
fn on_update(&self, ctx: &mut engine::Context, delta: f64) -> Result<(), engine::Error> {
|
||||||
for id in query!(ctx, RigidBody) {
|
for id in query!(ctx, RigidBody) {
|
||||||
let body = ctx.entity_component::<RigidBody>(id);
|
let body = ctx.entity_component::<RigidBody>(id);
|
||||||
// body.pos.0 += body.vel.0 * delta;
|
body.pos.0 += body.vel.0 * delta;
|
||||||
// body.pos.1 += body.vel.1 * delta;
|
body.pos.1 += body.vel.1 * delta;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rects_collide(
|
|
||||||
rect: (f64, f64),
|
|
||||||
pos: (f64, f64),
|
|
||||||
other_rect: (f64, f64),
|
|
||||||
other_pos: (f64, f64),
|
|
||||||
) -> bool {
|
|
||||||
pos.0 + rect.0 > other_pos.0
|
|
||||||
&& pos.0 < other_pos.0 + other_rect.0
|
|
||||||
&& pos.1 + rect.1 > other_pos.1
|
|
||||||
&& pos.1 < other_pos.1 + other_rect.1
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rec_point_collides(rect: (f64, f64), pos: (f64, f64), point: (f64, f64)) -> bool {
|
|
||||||
pos.0 + rect.0 < point.0 && pos.0 > point.0 && pos.1 + rect.1 < point.1 && pos.1 > point.1
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component, Clone, Default)]
|
|
||||||
struct Collider {
|
|
||||||
resolve: bool,
|
|
||||||
colliding_surface: Option<Surface>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn horizontal_line_intersect(p0: (f64, f64), vel: (f64, f64), line_y: f64) -> Option<(f64, f64)> {
|
|
||||||
if vel.1 == 0.0 {
|
|
||||||
// exclusively going left or right, ergo there's no collision with a horizontal line
|
|
||||||
return None;
|
|
||||||
} else if vel.0 == 0.0 {
|
|
||||||
// no change in x, ergo the intersect must be at p0_x
|
|
||||||
return Some((p0.0, line_y));
|
|
||||||
}
|
|
||||||
// y = ax + b
|
|
||||||
let a = vel.1 / vel.0;
|
|
||||||
let b = p0.1 - p0.0 * a;
|
|
||||||
|
|
||||||
let x = (line_y - b) / a;
|
|
||||||
Some((x, line_y))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn vertical_line_intersect(p0: (f64, f64), vel: (f64, f64), line_x: f64) -> Option<(f64, f64)> {
|
|
||||||
if vel.0 == 0.0 {
|
|
||||||
// exclusively going up or down, ergo there's no collision with a vertical line
|
|
||||||
return None;
|
|
||||||
} else if vel.1 == 0.0 {
|
|
||||||
// no change in y, ergo the intersect must be at p0_y
|
|
||||||
return Some((line_x, p0.1));
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// y = ax + b
|
|
||||||
let a = vel.1 / vel.0;
|
|
||||||
let b = p0.1 - p0.0 * a;
|
|
||||||
|
|
||||||
let y = a * line_x + b;
|
|
||||||
Some((line_x, y))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
enum Surface {
|
|
||||||
Top,
|
|
||||||
Bottom,
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn point_distance(a: (f64, f64), b: (f64, f64)) -> f64 {
|
|
||||||
((a.0 - b.0).abs().powi(2) + (a.1 - b.1).abs().powi(2)).sqrt()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn point_rect_closest_surface(
|
|
||||||
p0: (f64, f64),
|
|
||||||
vel: (f64, f64),
|
|
||||||
rect_pos: (f64, f64),
|
|
||||||
rect: (f64, f64),
|
|
||||||
) -> Option<(f64, Surface)> {
|
|
||||||
let closest_horizontal_intersect = [
|
|
||||||
(horizontal_line_intersect(p0, vel, rect_pos.1), Surface::Top),
|
|
||||||
(
|
|
||||||
horizontal_line_intersect(p0, vel, rect_pos.1 + rect.1),
|
|
||||||
Surface::Bottom,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|(intersect, surface)| intersect.map(|intersect| (intersect, surface)))
|
|
||||||
.map(|(point, surface)| (point_distance(p0, point), surface))
|
|
||||||
.min_by(|(dist_a, _), (dist_b, _)| dist_a.total_cmp(dist_b));
|
|
||||||
|
|
||||||
let closest_vertical_intersect = [
|
|
||||||
(vertical_line_intersect(p0, vel, rect_pos.0), Surface::Left),
|
|
||||||
(
|
|
||||||
vertical_line_intersect(p0, vel, rect_pos.0 + rect.0),
|
|
||||||
Surface::Right,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|(intersect, surface)| intersect.map(|intersect| (intersect, surface)))
|
|
||||||
.map(|(point, surface)| (point_distance(p0, point), surface))
|
|
||||||
.min_by(|(dist_a, _), (dist_b, _)| dist_a.total_cmp(dist_b));
|
|
||||||
|
|
||||||
match (closest_horizontal_intersect, closest_vertical_intersect) {
|
|
||||||
(Some(left), Some(right)) => {
|
|
||||||
if right.0 < left.0 {
|
|
||||||
Some(right)
|
|
||||||
} else {
|
|
||||||
Some(left)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(None, v) | (v, None) => v,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CollisionSystem;
|
|
||||||
impl System for CollisionSystem {
|
|
||||||
fn on_update(&self, ctx: &mut engine::Context, delta: f64) -> Result<(), engine::Error> {
|
|
||||||
for id in query!(ctx, RigidBody, Collider) {
|
|
||||||
let collider = ctx.entity_component::<Collider>(id);
|
|
||||||
collider.colliding_surface = None;
|
|
||||||
let collider = ctx.entity_component::<Collider>(id).clone();
|
|
||||||
if !collider.resolve {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let body = ctx.entity_component::<RigidBody>(id).clone();
|
|
||||||
for other_id in query!(ctx, RigidBody, Collider) {
|
|
||||||
if id == other_id {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let other_body = ctx.entity_component::<RigidBody>(other_id).clone();
|
|
||||||
let new_pos = cuwusions::rects_collision_resolution_pos(
|
|
||||||
body.pos,
|
|
||||||
(body.vel.0 * delta, body.vel.1 * delta),
|
|
||||||
body.rect,
|
|
||||||
other_body.pos,
|
|
||||||
other_body.rect,
|
|
||||||
);
|
|
||||||
|
|
||||||
let body = ctx.entity_component::<RigidBody>(id);
|
|
||||||
body.pos = new_pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
struct GravitySystem;
|
struct GravitySystem;
|
||||||
impl System for GravitySystem {
|
impl System for GravitySystem {
|
||||||
fn on_update(&self, ctx: &mut engine::Context, delta: f64) -> Result<(), engine::Error> {
|
fn on_update(&self, ctx: &mut engine::Context, delta: f64) -> Result<(), engine::Error> {
|
||||||
@ -188,6 +45,24 @@ impl System for GravitySystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
struct Sprite {
|
||||||
|
sprite: engine::Sprite,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpriteRenderer;
|
||||||
|
impl System for SpriteRenderer {
|
||||||
|
fn on_update(&self, ctx: &mut engine::Context, _delta: f64) -> Result<(), engine::Error> {
|
||||||
|
for id in query!(ctx, Sprite, RigidBody) {
|
||||||
|
let body = ctx.entity_component::<RigidBody>(id).clone();
|
||||||
|
let sprite = ctx.entity_component::<Sprite>(id).sprite;
|
||||||
|
|
||||||
|
ctx.draw_sprite(sprite, body.pos.0 as i32, body.pos.1 as i32)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
struct Cloud;
|
struct Cloud;
|
||||||
|
|
||||||
@ -227,19 +102,6 @@ impl System for CloudSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SpriteRenderer;
|
|
||||||
impl System for SpriteRenderer {
|
|
||||||
fn on_update(&self, ctx: &mut engine::Context, _delta: f64) -> Result<(), engine::Error> {
|
|
||||||
for id in query!(ctx, Sprite, RigidBody) {
|
|
||||||
let body = ctx.entity_component::<RigidBody>(id).clone();
|
|
||||||
let sprite = ctx.entity_component::<Sprite>(id).sprite;
|
|
||||||
|
|
||||||
ctx.draw_sprite(sprite, body.pos.0 as i32, body.pos.1 as i32)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
struct PlayerMovement;
|
struct PlayerMovement;
|
||||||
|
|
||||||
@ -259,7 +121,7 @@ impl System for PlayerMovementSystem {
|
|||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
if let (Some(Surface::Top), true) = (collider.colliding_surface, w_down) {
|
if collider.on_ground && w_down {
|
||||||
body.vel.1 = -1000.0;
|
body.vel.1 = -1000.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,10 +133,10 @@ fn main() {
|
|||||||
let mut game = engine::Game::new().unwrap();
|
let mut game = engine::Game::new().unwrap();
|
||||||
|
|
||||||
let mut context = game.context();
|
let mut context = game.context();
|
||||||
context.add_system(VelocitySystem);
|
|
||||||
context.add_system(CollisionSystem);
|
context.add_system(CollisionSystem);
|
||||||
|
context.add_system(VelocitySystem);
|
||||||
context.add_system(SpriteRenderer);
|
context.add_system(SpriteRenderer);
|
||||||
context.add_system(PlayerMovementSystem);
|
// context.add_system(PlayerMovementSystem);
|
||||||
context.add_system(GravitySystem);
|
context.add_system(GravitySystem);
|
||||||
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();
|
||||||
@ -291,7 +153,8 @@ fn main() {
|
|||||||
&mut context,
|
&mut context,
|
||||||
Sprite { sprite: player },
|
Sprite { sprite: player },
|
||||||
RigidBody {
|
RigidBody {
|
||||||
pos: (400.0, 400.0),
|
pos: (400.0, 200.0),
|
||||||
|
vel: (10.0, 0.0),
|
||||||
rect: (128.0, 128.0),
|
rect: (128.0, 128.0),
|
||||||
gravity: true,
|
gravity: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -313,27 +176,27 @@ fn main() {
|
|||||||
Collider::default(),
|
Collider::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
spawn!(
|
// spawn!(
|
||||||
&mut context,
|
// &mut context,
|
||||||
RigidBody {
|
// RigidBody {
|
||||||
pos: (300.0, 200.0),
|
// pos: (300.0, 200.0),
|
||||||
rect: (32.0, 32.0),
|
// rect: (32.0, 32.0),
|
||||||
..Default::default()
|
// ..Default::default()
|
||||||
},
|
// },
|
||||||
Collider::default(),
|
// Collider::default(),
|
||||||
Sprite { sprite: nope },
|
// Sprite { sprite: nope },
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
spawn!(
|
// spawn!(
|
||||||
&mut context,
|
// &mut context,
|
||||||
RigidBody {
|
// RigidBody {
|
||||||
pos: (900.0, 400.0),
|
// pos: (900.0, 400.0),
|
||||||
rect: (32.0, 32.0),
|
// rect: (32.0, 32.0),
|
||||||
..Default::default()
|
// ..Default::default()
|
||||||
},
|
// },
|
||||||
Collider::default(),
|
// Collider::default(),
|
||||||
Sprite { sprite: nope },
|
// Sprite { sprite: nope },
|
||||||
);
|
// );
|
||||||
|
|
||||||
game.run();
|
game.run();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user