cabel-movement #3
9 changed files with 377 additions and 25 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1,3 @@
|
||||||
/target
|
/target
|
||||||
|
*.nix
|
||||||
|
.vscode/
|
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -478,8 +478,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "comfy"
|
name = "comfy"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/Plonq/comfy/?branch=101-fix-keyboard-events#6293590aec51875e9832ef05a670149d371f849c"
|
||||||
checksum = "5e8ff7c66a696e9a9e5523d0c4a6306711acb7f6d490d9c412b044a8c95f17f4"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"comfy-core",
|
"comfy-core",
|
||||||
"comfy-wgpu",
|
"comfy-wgpu",
|
||||||
|
@ -499,8 +498,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "comfy-core"
|
name = "comfy-core"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/Plonq/comfy/?branch=101-fix-keyboard-events#6293590aec51875e9832ef05a670149d371f849c"
|
||||||
checksum = "398260ce649e9d35adc3ae75565406aab9b360c1e892a48ae3606e3138df150b"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -558,8 +556,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "comfy-wgpu"
|
name = "comfy-wgpu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/Plonq/comfy/?branch=101-fix-keyboard-events#6293590aec51875e9832ef05a670149d371f849c"
|
||||||
checksum = "6118f09fd99577503ba6861dac53840bae6cf202d70f97042f5cdf43c222e39a"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"comfy-core",
|
"comfy-core",
|
||||||
|
|
|
@ -17,3 +17,8 @@ opt-level = 3
|
||||||
[dependencies]
|
[dependencies]
|
||||||
comfy = { version = "0.4.0", features = ["wayland"] }
|
comfy = { version = "0.4.0", features = ["wayland"] }
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
# https://github.com/darthdeus/comfy/issues/101
|
||||||
|
# https://github.com/darthdeus/comfy/pull/102
|
||||||
|
comfy = { git = "https://github.com/Plonq/comfy/", branch = "101-fix-keyboard-events" }
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
use comfy::*;
|
|
||||||
|
|
||||||
pub fn draw(_state: &crate::State, _engine: &comfy::EngineContext) {
|
|
||||||
draw_circle(vec2(0.0, 0.0), 0.5, RED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(_state: &mut crate::State, _engine: &mut comfy::EngineContext) {}
|
|
69
src/activities/house/grid.rs
Normal file
69
src/activities/house/grid.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
use comfy::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Grid {
|
||||||
|
pub nodes: Vec<Vec2>,
|
||||||
|
pub connections: Vec<(usize, usize)>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Grid {
|
||||||
|
fn default() -> Self {
|
||||||
|
Grid::load() //Just for testing purposes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Grid {
|
||||||
|
fn load() -> Self {
|
||||||
|
let mut grid = Self {
|
||||||
|
nodes: vec![
|
||||||
|
vec2(10.0, 0.0),
|
||||||
|
vec2(0.0, 0.0),
|
||||||
|
vec2(0.0, 10.0),
|
||||||
|
vec2(-10.0, 0.0),
|
||||||
|
vec2(10.0, 10.0),
|
||||||
|
],
|
||||||
|
connections: vec![(0, 1), (1, 2), (1, 3), (0, 4), (0, 5), (5, 1), (6, 7)]
|
||||||
|
};
|
||||||
|
|
||||||
|
grid.sanitize();
|
||||||
|
|
||||||
|
grid
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sanitize(&mut self) {
|
||||||
|
let mut len = self.nodes.len();
|
||||||
|
let connections = self
|
||||||
|
.connections
|
||||||
|
.iter()
|
||||||
|
.filter(|(conn_i1, conn_i2)| {
|
||||||
|
if conn_i1 >= &mut len || conn_i2 >= &mut len {
|
||||||
|
error!("Connection in grid not possible {:?}", (conn_i1, conn_i2));
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|(conn_i1, conn_i2)| (*conn_i1, *conn_i2))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.connections = connections;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&self) {
|
||||||
|
//Draw Grid
|
||||||
|
for node in &self.nodes {
|
||||||
|
draw_circle(*node, 0.25, BLUE, 0);
|
||||||
|
}
|
||||||
|
for (conn_i1, conn_i2) in &self.connections {
|
||||||
|
let node_1 = self.nodes.get(*conn_i1);
|
||||||
|
let node_2 = self.nodes.get(*conn_i2);
|
||||||
|
|
||||||
|
if node_1.is_none() || node_2.is_none() {
|
||||||
|
error!("Connection in grid not available {:?}", (conn_i1, conn_i2));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw_line(*node_1.unwrap(), *node_2.unwrap(), 0.1, BLUE, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
src/activities/house/mod.rs
Normal file
23
src/activities/house/mod.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
mod grid;
|
||||||
|
mod player;
|
||||||
|
|
||||||
|
use grid::Grid;
|
||||||
|
use player::Player;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct HouseState {
|
||||||
|
grid: Grid,
|
||||||
|
player: Player
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(state: &crate::State, _engine: &comfy::EngineContext) {
|
||||||
|
//Draw Grid
|
||||||
|
state.house.grid.draw();
|
||||||
|
|
||||||
|
//Draw Player
|
||||||
|
state.house.player.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(state: &mut crate::State, _engine: &mut comfy::EngineContext) {
|
||||||
|
state.house.player.update(&state.house.grid);
|
||||||
|
}
|
268
src/activities/house/player.rs
Normal file
268
src/activities/house/player.rs
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
use comfy::*;
|
||||||
|
|
||||||
|
use super::Grid;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Player {
|
||||||
|
position: Vec2,
|
||||||
|
speed: f32,
|
||||||
|
connection: usize,
|
||||||
|
next_connections: Vec<usize>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Player {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
position: Default::default(),
|
||||||
|
speed: 10.0,
|
||||||
|
connection: 0,
|
||||||
|
next_connections: vec![1, 2, 3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Player {
|
||||||
|
pub fn draw(&self) {
|
||||||
|
draw_circle(self.position, 0.5, RED, 0);
|
||||||
|
}
|
||||||
|
pub fn update(&mut self, grid: &Grid) {
|
||||||
|
let allowed_movement = get_allowed_movement(self, grid);
|
||||||
|
|
||||||
|
move_player(self, allowed_movement);
|
||||||
|
|
||||||
|
if !on_current_connection(self, grid) && !update_connections(self, grid) {
|
||||||
|
snap_to_closest_node(self, grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_player(player: &mut Player, allowed_movement: (bool, bool, bool, bool)) {
|
||||||
|
let (
|
||||||
|
allow_up_movement,
|
||||||
|
allow_down_movement,
|
||||||
|
allow_left_movement,
|
||||||
|
allow_right_movement
|
||||||
|
) = allowed_movement;
|
||||||
|
|
||||||
|
if allow_up_movement && is_key_down(KeyCode::Up) {
|
||||||
|
player.position += vec2(0.0, player.speed) * delta();
|
||||||
|
}
|
||||||
|
|
||||||
|
if allow_down_movement && is_key_down(KeyCode::Down) {
|
||||||
|
player.position += vec2(0.0, -player.speed) * delta();
|
||||||
|
}
|
||||||
|
|
||||||
|
if allow_right_movement && is_key_down(KeyCode::Right) {
|
||||||
|
player.position += vec2(player.speed, 0.0) * delta();
|
||||||
|
}
|
||||||
|
|
||||||
|
if allow_left_movement && is_key_down(KeyCode::Left) {
|
||||||
|
player.position += vec2(-player.speed, 0.0) * delta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(UP, DOWN, LEFT, RIGHT)
|
||||||
|
fn get_allowed_movement(player: &Player, grid: &Grid) -> (bool, bool, bool, bool) {
|
||||||
|
let (conn_i1, conn_i2) = grid.connections.get(player.connection).unwrap();
|
||||||
|
let node_1 = grid.nodes.get(*conn_i1).unwrap();
|
||||||
|
let node_2 = grid.nodes.get(*conn_i2).unwrap();
|
||||||
|
|
||||||
|
let range = 0.25;
|
||||||
|
|
||||||
|
if in_node_range(&player.position, node_1, range)
|
||||||
|
|| in_node_range(&player.position, node_2, range)
|
||||||
|
{
|
||||||
|
(true, true, true, true)
|
||||||
|
} else {
|
||||||
|
let (
|
||||||
|
mut allow_up_movement,
|
||||||
|
mut allow_down_movement,
|
||||||
|
mut allow_left_movement,
|
||||||
|
mut allow_right_movement
|
||||||
|
) = get_allowed_connection_movement(&player.position, node_1, node_2);
|
||||||
|
|
||||||
|
for conn in &player.next_connections {
|
||||||
|
let (next_conn_i1, next_conn_i2) = grid.connections.get(*conn).unwrap();
|
||||||
|
let next_node_1 = grid.nodes.get(*next_conn_i1).unwrap();
|
||||||
|
let next_node_2 = grid.nodes.get(*next_conn_i2).unwrap();
|
||||||
|
|
||||||
|
let (
|
||||||
|
next_allow_up_movement,
|
||||||
|
next_allow_down_movement,
|
||||||
|
next_allow_left_movement,
|
||||||
|
next_allow_right_movement
|
||||||
|
) = get_allowed_connection_movement(&player.position, next_node_1, next_node_2);
|
||||||
|
|
||||||
|
(
|
||||||
|
allow_up_movement,
|
||||||
|
allow_down_movement,
|
||||||
|
allow_left_movement,
|
||||||
|
allow_right_movement
|
||||||
|
) = (
|
||||||
|
allow_up_movement || next_allow_up_movement,
|
||||||
|
allow_down_movement || next_allow_down_movement,
|
||||||
|
allow_left_movement || next_allow_left_movement,
|
||||||
|
allow_right_movement || next_allow_right_movement
|
||||||
|
);
|
||||||
|
}
|
||||||
|
(
|
||||||
|
allow_up_movement,
|
||||||
|
allow_down_movement,
|
||||||
|
allow_left_movement,
|
||||||
|
allow_right_movement
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//(UP, DOWN, LEFT, RIGHT)
|
||||||
|
fn get_allowed_connection_movement(
|
||||||
|
player_position: &Vec2,
|
||||||
|
node_1: &Vec2,
|
||||||
|
node_2: &Vec2
|
||||||
|
) -> (bool, bool, bool, bool) {
|
||||||
|
let allow_left_movement = {
|
||||||
|
if node_1.x <= node_2.x {
|
||||||
|
node_1.x < player_position.x
|
||||||
|
&& player_position.x <= node_2.x
|
||||||
|
&& player_position.y == node_1.y
|
||||||
|
} else {
|
||||||
|
node_2.x < player_position.x
|
||||||
|
&& player_position.x <= node_1.x
|
||||||
|
&& player_position.y == node_1.y
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let allow_right_movement = {
|
||||||
|
if node_1.x <= node_2.x {
|
||||||
|
node_1.x <= player_position.x
|
||||||
|
&& player_position.x < node_2.x
|
||||||
|
&& player_position.y == node_1.y
|
||||||
|
} else {
|
||||||
|
node_2.x <= player_position.x
|
||||||
|
&& player_position.x < node_1.x
|
||||||
|
&& player_position.y == node_1.y
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let allow_up_movement = {
|
||||||
|
if node_1.y <= node_2.y {
|
||||||
|
node_1.y <= player_position.y
|
||||||
|
&& player_position.y < node_2.y
|
||||||
|
&& player_position.x == node_1.x
|
||||||
|
} else {
|
||||||
|
node_2.y <= player_position.y
|
||||||
|
&& player_position.y < node_1.y
|
||||||
|
&& player_position.x == node_1.x
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let allow_down_movement = {
|
||||||
|
if node_1.y <= node_2.y {
|
||||||
|
node_1.y < player_position.y
|
||||||
|
&& player_position.y <= node_2.y
|
||||||
|
&& player_position.x == node_1.x
|
||||||
|
} else {
|
||||||
|
node_2.y < player_position.y
|
||||||
|
&& player_position.y <= node_1.y
|
||||||
|
&& player_position.x == node_1.x
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
allow_up_movement,
|
||||||
|
allow_down_movement,
|
||||||
|
allow_left_movement,
|
||||||
|
allow_right_movement
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_current_connection(player: &Player, grid: &Grid) -> bool {
|
||||||
|
let (conn_i1, conn_i2) = grid.connections.get(player.connection).unwrap();
|
||||||
|
let node_1 = grid.nodes.get(*conn_i1).unwrap();
|
||||||
|
let node_2 = grid.nodes.get(*conn_i2).unwrap();
|
||||||
|
|
||||||
|
on_connection(&player.position, node_1, node_2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_connection(player_position: &Vec2, node_1: &Vec2, node_2: &Vec2) -> bool {
|
||||||
|
let on_x = if node_1.x <= node_2.x {
|
||||||
|
node_1.x <= player_position.x && player_position.x <= node_2.x
|
||||||
|
} else {
|
||||||
|
node_2.x <= player_position.x && player_position.x <= node_1.x
|
||||||
|
};
|
||||||
|
|
||||||
|
let on_y = if node_1.y <= node_2.y {
|
||||||
|
node_1.y <= player_position.y && player_position.y <= node_2.y
|
||||||
|
} else {
|
||||||
|
node_2.y <= player_position.y && player_position.y <= node_1.y
|
||||||
|
};
|
||||||
|
|
||||||
|
on_x && on_y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_connections(player: &mut Player, grid: &Grid) -> bool {
|
||||||
|
for conn in &player.next_connections {
|
||||||
|
let (next_conn_i1, next_conn_i2) = grid.connections.get(*conn).unwrap();
|
||||||
|
let next_node_1 = grid.nodes.get(*next_conn_i1).unwrap();
|
||||||
|
let next_node_2 = grid.nodes.get(*next_conn_i2).unwrap();
|
||||||
|
|
||||||
|
if on_connection(&player.position, next_node_1, next_node_2) {
|
||||||
|
player.connection = *conn;
|
||||||
|
//Update next connections
|
||||||
|
let mut next_connections = Vec::new();
|
||||||
|
for (i, (poss_conn_i1, poss_conn_i2)) in grid.connections.iter().enumerate() {
|
||||||
|
if (next_conn_i1, next_conn_i2) != (poss_conn_i1, poss_conn_i2)
|
||||||
|
&& next_conn_i1 == poss_conn_i1
|
||||||
|
|| next_conn_i1 == poss_conn_i2
|
||||||
|
|| next_conn_i2 == poss_conn_i1
|
||||||
|
|| next_conn_i2 == poss_conn_i2
|
||||||
|
{
|
||||||
|
next_connections.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.next_connections = next_connections;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn in_node_range(player_position: &Vec2, node: &Vec2, range: f32) -> bool {
|
||||||
|
node.x - range <= player_position.x
|
||||||
|
&& player_position.x <= node.x + range
|
||||||
|
&& node.y - range <= player_position.y
|
||||||
|
&& player_position.y <= node.y + range
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_squared_node_range(player_position: &Vec2, node: &Vec2) -> f32 {
|
||||||
|
(player_position.x - node.x).abs() + (player_position.y - node.y).abs()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn snap_to_closest_node(player: &mut Player, grid: &Grid) {
|
||||||
|
let (current_connection_index_1, current_connection_index_2) =
|
||||||
|
grid.connections.get(player.connection).unwrap();
|
||||||
|
|
||||||
|
let mut nodes = HashSet::new();
|
||||||
|
nodes.insert(current_connection_index_1);
|
||||||
|
nodes.insert(current_connection_index_2);
|
||||||
|
for conn in &player.next_connections {
|
||||||
|
let (next_connection_index_1, next_connection_index_2) =
|
||||||
|
grid.connections.get(*conn).unwrap();
|
||||||
|
|
||||||
|
nodes.insert(next_connection_index_1);
|
||||||
|
nodes.insert(next_connection_index_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut closest_sqared_range = f32::MAX;
|
||||||
|
let mut closest_node = &vec2(0.0, 0.0);
|
||||||
|
for node_index in nodes {
|
||||||
|
let current_node = grid.nodes.get(*node_index).unwrap();
|
||||||
|
let current_squard_range = get_squared_node_range(&player.position, current_node);
|
||||||
|
if closest_sqared_range > current_squard_range {
|
||||||
|
closest_sqared_range = current_squard_range;
|
||||||
|
closest_node = current_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.position = *closest_node;
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
pub mod house;
|
pub mod house;
|
||||||
pub mod overworld;
|
pub mod overworld;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
pub enum Activity {
|
pub enum Activity {
|
||||||
|
#[default]
|
||||||
House,
|
House,
|
||||||
|
#[allow(dead_code)]
|
||||||
Overworld
|
Overworld
|
||||||
}
|
}
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -1,22 +1,15 @@
|
||||||
mod activities;
|
mod activities;
|
||||||
mod game;
|
mod game;
|
||||||
|
|
||||||
use activities::Activity;
|
use activities::{house::HouseState, Activity};
|
||||||
use comfy::*;
|
use comfy::*;
|
||||||
|
|
||||||
const GAME_NAME: &str = "Powercreep";
|
const GAME_NAME: &str = "Powercreep";
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Default)]
|
||||||
struct State {
|
struct State {
|
||||||
activity: Activity
|
activity: Activity,
|
||||||
}
|
house: HouseState
|
||||||
|
|
||||||
impl Default for State {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
activity: Activity::House
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameLoop for State {
|
impl GameLoop for State {
|
||||||
|
|
Loading…
Reference in a new issue