cabel-movement #3

Merged
Glaeder merged 6 commits from cabel-movement into main 2024-07-06 17:59:56 +00:00
Showing only changes of commit 13018c034e - Show all commits

View file

@ -3,7 +3,7 @@ use comfy::*;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct HouseState { pub struct HouseState {
grid: Grid, grid: Grid,
player: Player player: Player,
} }
#[derive(Debug)] #[derive(Debug)]
@ -12,9 +12,12 @@ struct Grid {
connections: Vec<(usize, usize)>, connections: Vec<(usize, usize)>,
} }
#[derive(Debug, Default)] #[derive(Debug)]
struct Player { struct Player {
position: Vec2 position: Vec2,
speed: f32,
connection: usize,
next_connections: Vec<usize>,
} }
impl Default for Grid { impl Default for Grid {
@ -43,34 +46,50 @@ impl Grid {
fn sanitize(&mut self) { fn sanitize(&mut self) {
let mut len = self.nodes.len(); let mut len = self.nodes.len();
let connections = self.connections.iter().filter(|(conn_i1, conn_i2)| { let connections = self
if conn_i1 >= &mut len || conn_i2 >= &mut len{ .connections
error!("Connection in grid not possible {:?}", (conn_i1, conn_i2)); .iter()
false .filter(|(conn_i1, conn_i2)| {
} else { if conn_i1 >= &mut len || conn_i2 >= &mut len {
true error!("Connection in grid not possible {:?}", (conn_i1, conn_i2));
} false
}).map(|(conn_i1, conn_i2)| (*conn_i1, *conn_i2)).collect(); } else {
true
}
})
.map(|(conn_i1, conn_i2)| (*conn_i1, *conn_i2))
.collect();
self.connections = connections; self.connections = connections;
} }
} }
impl Default for Player {
fn default() -> Self {
Self {
position: Default::default(),
speed: 10.0,
connection: 0,
next_connections: vec![1, 2, 3],
}
}
}
pub fn draw(state: &crate::State, _engine: &comfy::EngineContext) { pub fn draw(state: &crate::State, _engine: &comfy::EngineContext) {
//Draw Grid //Draw Grid
for pos in &state.house.grid.nodes { for node in &state.house.grid.nodes {
draw_circle(*pos, 0.25, BLUE, 0); draw_circle(*node, 0.25, BLUE, 0);
} }
for (conn_i1, conn_i2) in &state.house.grid.connections { for (conn_i1, conn_i2) in &state.house.grid.connections {
let p1 = state.house.grid.nodes.get(*conn_i1); let node_1 = state.house.grid.nodes.get(*conn_i1);
let p2 = state.house.grid.nodes.get(*conn_i2); let node_2 = state.house.grid.nodes.get(*conn_i2);
if p1.is_none() || p2.is_none() { if node_1.is_none() || node_2.is_none() {
error!("Connection in grid not available {:?}", (conn_i1, conn_i2)); error!("Connection in grid not available {:?}", (conn_i1, conn_i2));
continue; continue;
} }
draw_line(*p1.unwrap(), *p2.unwrap(), 0.1, BLUE, 0); draw_line(*node_1.unwrap(), *node_2.unwrap(), 0.1, BLUE, 0);
} }
//Draw Player //Draw Player
@ -78,20 +97,225 @@ pub fn draw(state: &crate::State, _engine: &comfy::EngineContext) {
} }
pub fn update(state: &mut crate::State, _engine: &mut comfy::EngineContext) { pub fn update(state: &mut crate::State, _engine: &mut comfy::EngineContext) {
if is_key_down(KeyCode::Up) { let player = &mut state.house.player;
error!("KEY UPPPPPPPPP"); let grid = &state.house.grid;
state.house.player.position += vec2(0.0, 1.0) * delta();
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;
let (
allow_up_movement,
allow_down_movement,
allow_left_movement,
allow_right_movement,
) = 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_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_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,
)
};
if allow_up_movement && is_key_down(KeyCode::Up) {
player.position += vec2(0.0, player.speed) * delta();
} }
if is_key_down(KeyCode::Down) { if allow_down_movement && is_key_down(KeyCode::Down) {
state.house.player.position += vec2(0.0, -1.0) * delta(); player.position += vec2(0.0, -player.speed) * delta();
} }
if is_key_down(KeyCode::Right) { if allow_right_movement && is_key_down(KeyCode::Right) {
state.house.player.position += vec2(1.0, 0.0) * delta(); player.position += vec2(player.speed, 0.0) * delta();
} }
if is_key_down(KeyCode::Left) { if allow_left_movement && is_key_down(KeyCode::Left) {
state.house.player.position += vec2(-1.0, 0.0) * delta(); player.position += vec2(-player.speed, 0.0) * delta();
}
if !on_connection(&player.position, node_1, node_2) {
let mut changed = false;
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) {
changed = true;
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) {
if 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;
break;
}
}
if !changed {
//Get closest node to snap to
let mut nodes = HashSet::new();
nodes.insert(conn_i1);
nodes.insert(conn_i2);
for conn in &player.next_connections {
let (next_conn_i1, next_conn_i2) = grid.connections.get(*conn).unwrap();
nodes.insert(next_conn_i1);
nodes.insert(next_conn_i2);
}
let mut closest_sqared_range = f32::MAX;
let mut closest_node = node_1;
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;
}
} }
} }
//(UP, DOWN, LEFT, RIGHT)
fn get_allowed_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_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 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()
}