Skip to content

Commit

Permalink
camera movement
Browse files Browse the repository at this point in the history
  • Loading branch information
mkhan45 committed Apr 11, 2021
1 parent 8d69ecb commit f3bfe06
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 63 deletions.
25 changes: 25 additions & 0 deletions notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,28 @@ Right now, wire inputs are pushed to by a node, and then the outputs pull from t
With Connections, the node can push to the wire input through the connection, and then the node pulls from the wire output through a connection as well.

This makes it easy to iterate through all the connections at once.

# New wires

Add Hitbox component

```rs
enum Hitbox {
Circle(f32), // for nodes/connections
Rect(Rect), // for wires
Compound(Vec<Hitbox>), // for wires
}
```

Make all click stuff go thru hitboxes

Remove Pos component from wires, instead

```rs
pub struct Wire {
...
bend_points: Vec<Vec2>,
}
```

Rework drawing wires
41 changes: 41 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::nodes::Wire;
use crate::resources::UiSignal;
use macroquad::prelude::*;
use resources::CameraRes;
use specs::prelude::*;

mod components;
Expand Down Expand Up @@ -67,6 +68,12 @@ async fn main() {

world.insert(resources::Tick(0));
world.insert(resources::TickFrames(60));
world.insert(resources::CameraRes::default());

let mut prev_mouse_pos = {
let (mx, my) = mouse_position();
Vec2::new(mx, my)
};

let mut last_fps = [60i32; 256];

Expand Down Expand Up @@ -115,6 +122,13 @@ async fn main() {
});
});

{
let camera = world.fetch::<CameraRes>().0;
world.insert(resources::MousePos(
camera.screen_to_world(mouse_position().into()),
));
}

if is_mouse_button_pressed(MouseButton::Left) {
ui::mouse_click::handle_mouse_click(&mut world);
}
Expand All @@ -123,6 +137,33 @@ async fn main() {
ui::mouse_click::handle_mouse_right_click(&mut world);
}

let new_mouse_pos = {
let (mx, my) = mouse_position();
Vec2::new(mx, -my)
};

if is_mouse_button_down(MouseButton::Middle) {
world.fetch_mut::<CameraRes>().0.offset += (new_mouse_pos - prev_mouse_pos) / 1000.0;
}

{
let mp: Vec2 = mouse_position().into();
let old_camera = world.fetch::<CameraRes>().0;
let old_focus = old_camera.screen_to_world(mp);

let mwheel = macroquad::input::mouse_wheel().1;
let zoom_fac = 1.0 + mwheel / 10.0;
world.fetch_mut::<CameraRes>().0.zoom *= zoom_fac;
let new_camera = world.fetch::<CameraRes>().0;
let new_focus = new_camera.screen_to_world(mp);

let delta_focus = new_focus - old_focus;
world.fetch_mut::<CameraRes>().0.offset += delta_focus * new_camera.zoom;
}

macroquad::camera::set_camera(world.fetch::<CameraRes>().0);
prev_mouse_pos = new_mouse_pos;

egui_macroquad::draw();

next_frame().await;
Expand Down
20 changes: 20 additions & 0 deletions src/resources.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use macroquad::prelude::screen_height;
use macroquad::prelude::Vec2;
use macroquad::texture::Texture2D;
use macroquad::{camera::Camera2D, prelude::screen_width};
use specs::Entity;

use crate::components::nodes::NodeTy;
Expand Down Expand Up @@ -72,3 +75,20 @@ impl Default for CurrentModeText {
)
}
}

pub struct CameraRes(pub Camera2D);

impl Default for CameraRes {
fn default() -> Self {
CameraRes(Camera2D {
rotation: 0.0,
zoom: Vec2::new(2.0 / screen_width(), 2.0 / screen_height()),
target: Vec2::new(0.0, 0.0),
offset: Vec2::new(0.0, 0.0),
render_target: None,
})
}
}

#[derive(Default)]
pub struct MousePos(pub Vec2);
96 changes: 59 additions & 37 deletions src/systems/draw_systems.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::Pos;
use crate::Wire;
use crate::components::round_to_snap;
use crate::{components::nodes::NandNode, nodes::NotNode};
use crate::{components::nodes::NorNode, nodes::OnNode};
use crate::{components::nodes::XnorNode, nodes::XorNode};
Expand All @@ -13,7 +12,9 @@ use crate::{
components::{nodes::AndNode, Node},
resources::Textures,
};
use crate::{resources::CameraRes, Wire};
use crate::{resources::GridMode, Connected};
use crate::{resources::MousePos, Pos};
use core::marker::PhantomData;
use macroquad::prelude::*;
use specs::prelude::*;
Expand Down Expand Up @@ -241,11 +242,12 @@ where

pub struct TempWireDrawSys;
impl<'a> System<'a> for TempWireDrawSys {
type SystemData = (Read<'a, UIState>, ReadStorage<'a, Pos>);
type SystemData = (Read<'a, UIState>, ReadStorage<'a, Pos>, Read<'a, MousePos>);

fn run(&mut self, (ui_state, position_storage): Self::SystemData) {
fn run(&mut self, (ui_state, position_storage, mouse_pos): Self::SystemData) {
use crate::components::round_to_snap as snap;
let color = LIGHTGRAY;
let mouse_pos = mouse_pos.0;
match *ui_state {
UIState::AddingWire {
connection_entity: e,
Expand All @@ -258,7 +260,7 @@ impl<'a> System<'a> for TempWireDrawSys {
draw_line(
start_pos.x,
start_pos.y,
snap(mouse_position().0),
snap(mouse_pos.x),
start_pos.y,
5.0,
color,
Expand All @@ -269,8 +271,7 @@ impl<'a> System<'a> for TempWireDrawSys {
y_pos: Some(y_pos),
..
} => {
let (mx, my) = mouse_position();
let pos = Pos::from_vec(Vec2::new(mx, my)).pos;
let pos = Pos::from_vec(mouse_pos).pos;

draw_line(snap(x_pos), snap(y_pos), snap(x_pos), pos.y, 5.0, color);
draw_line(snap(x_pos), pos.y, pos.x, pos.y, 5.0, color);
Expand All @@ -282,13 +283,14 @@ impl<'a> System<'a> for TempWireDrawSys {

pub struct DrawConnectionSys;
impl<'a> System<'a> for DrawConnectionSys {
type SystemData = (ReadStorage<'a, Connection>, ReadStorage<'a, Pos>);
type SystemData = (
ReadStorage<'a, Connection>,
ReadStorage<'a, Pos>,
Read<'a, MousePos>,
);

fn run(&mut self, (connections, positions): Self::SystemData) {
let mouse_pos = {
let (mx, my) = mouse_position();
Vec2::new(mx, my)
};
fn run(&mut self, (connections, positions, mouse_pos): Self::SystemData) {
let mouse_pos = mouse_pos.0;

let color = |pos: Vec2| {
if (pos - mouse_pos).length() > 10.0 {
Expand All @@ -306,39 +308,65 @@ impl<'a> System<'a> for DrawConnectionSys {

pub struct DrawGridSys;
impl<'a> System<'a> for DrawGridSys {
type SystemData = Read<'a, GridMode>;
type SystemData = (Read<'a, GridMode>, Read<'a, CameraRes>);

fn run(&mut self, grid_mode: Self::SystemData) {
// TODO: for some reason this only draws in the first quadrant, should be fixed later
fn run(&mut self, (grid_mode, camera_res): Self::SystemData) {
use crate::components::SNAP;
let s = 4;
let camera = camera_res.0;

let (top, left) = {
let top_left = camera.screen_to_world((0.0, 0.0).into());
(top_left.y, top_left.x)
};
let top = top - top.ceil() % SNAP + SNAP;
let left = left - left.ceil() % SNAP - SNAP;
let sx = s - ((left.floor() / SNAP).abs() as usize % s);

let (bottom, right) = {
let bottom_right = camera.screen_to_world((screen_width(), screen_height()).into());
(bottom_right.y, bottom_right.x)
};
let bottom = bottom - bottom.ceil() % SNAP - SNAP;
let right = right - right.ceil() % SNAP + SNAP;

// idk why they're switched but they are
let (bottom, top) = (top, bottom);
let sy = s - ((top.floor() / SNAP).abs() as usize % s);

let x_positions = (0..((right - left) / SNAP).ceil() as usize + s + 1)
.map(|i| (i, i % s == 0))
.map(|(i, is_big)| (left + i as f32 * SNAP - sx as f32 * SNAP - SNAP, is_big));
let y_positions = (0..((bottom - top) / SNAP).ceil() as usize + s + 1)
.map(|i| (i, i % s == 0))
.map(|(i, is_big)| (top + i as f32 * SNAP - sy as f32 * SNAP, is_big));

match *grid_mode {
GridMode::Lines => {
// lines
let base_width = 0.5;
let wider_width = 1.5;

(0..(screen_width() / SNAP).ceil() as usize)
.map(|i| (i, if i % s == 0 { wider_width } else { base_width }))
.map(|(i, width)| (i as f32 * SNAP, width))
.for_each(|(x, width)| draw_line(x, 0.0, x, screen_height(), width, DARKGRAY));
let thickness = |is_big| {
if is_big {
wider_width
} else {
base_width
}
};

(0..(screen_height() / SNAP).ceil() as usize)
.map(|i| (i, if i % s == 0 { wider_width } else { base_width }))
.map(|(i, width)| (i as f32 * SNAP, width))
.for_each(|(y, width)| draw_line(0.0, y, screen_width(), y, width, DARKGRAY));
x_positions.for_each(|(x, is_big)| {
draw_line(x, top, x, bottom, thickness(is_big), DARKGRAY)
});
y_positions.for_each(|(y, is_big)| {
draw_line(left, y, right, y, thickness(is_big), DARKGRAY)
});
}
GridMode::Dots => {
let base_rad = 1.5;
let wider_rad = 3.0;

let x_positions = (0..(screen_width() / SNAP).ceil() as usize)
.map(|i| (i, i % s == 0))
.map(|(i, is_big)| (i as f32 * SNAP, is_big));
let y_positions = (0..(screen_height() / SNAP).ceil() as usize)
.map(|i| (i, i % s == 0))
.map(|(i, is_big)| (i as f32 * SNAP, is_big));

for (x, b1) in x_positions {
for (y, b2) in y_positions.clone() {
let rad = if b1 && b2 { wider_rad } else { base_rad };
Expand All @@ -352,13 +380,6 @@ impl<'a> System<'a> for DrawGridSys {
let wider_thickness = 1.25;
let wider_length = 15.0;

let x_positions = (0..(screen_width() / SNAP).ceil() as usize)
.map(|i| (i, i % s == 0))
.map(|(i, is_big)| (i as f32 * SNAP, is_big));
let y_positions = (0..(screen_height() / SNAP).ceil() as usize)
.map(|i| (i, i % s == 0))
.map(|(i, is_big)| (i as f32 * SNAP, is_big));

for (x, b1) in x_positions {
for (y, b2) in y_positions.clone() {
let (thickness, len) = if b1 && b2 {
Expand All @@ -368,6 +389,7 @@ impl<'a> System<'a> for DrawGridSys {
};

draw_line(x - len / 2.0, y, x + len / 2.0, y, thickness, DARKGRAY);

draw_line(x, y - len / 2.0, x, y + len / 2.0, thickness, DARKGRAY);
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/systems/place_node_sys.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::components::{Connection, ConnectionTy, Node};
use crate::Connected;
use crate::Pos;
use crate::{resources::MousePos, Connected};
use core::marker::PhantomData;
use macroquad::prelude::*;
use specs::prelude::*;
use std::convert::TryInto;

Expand All @@ -22,15 +21,15 @@ where
WriteStorage<'a, Connected<N, I, O>>,
WriteStorage<'a, Pos>,
WriteStorage<'a, Connection>,
Read<'a, MousePos>,
Entities<'a>,
);

fn run(
&mut self,
(mut node_storage, mut position_storage, mut connections, entities): Self::SystemData,
(mut node_storage, mut position_storage, mut connections, mouse_pos, entities): Self::SystemData,
) {
let mp = mouse_position();
let pos = Pos::from_vec(mp.into());
let pos = Pos::from_vec(mouse_pos.0);
let input_offsets = N::input_offsets();
let output_offsets = N::output_offsets();

Expand Down
9 changes: 4 additions & 5 deletions src/systems/place_wire_sys.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::components::Pos;
use crate::components::{Connection, ConnectionTy};
use crate::resources::UIState;
use crate::Wire;
use macroquad::prelude::*;
use crate::{components::Pos, resources::MousePos};
use specs::prelude::*;

pub struct WirePlaceSys;
Expand All @@ -12,15 +11,15 @@ impl<'a> System<'a> for WirePlaceSys {
WriteStorage<'a, Wire>,
ReadStorage<'a, Pos>,
Write<'a, UIState>,
Read<'a, MousePos>,
Entities<'a>,
);

fn run(
&mut self,
(mut connections, mut wires, positions, mut ui_state, entities): Self::SystemData,
(mut connections, mut wires, positions, mut ui_state, mouse_pos, entities): Self::SystemData,
) {
let (mx, my) = mouse_position();
let mp = Vec2::new(mx, my);
let mp = mouse_pos.0;

match *ui_state {
UIState::AddingWire { wire_entity, .. } => {
Expand Down
12 changes: 4 additions & 8 deletions src/systems/ui_systems.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use crate::nodes::SwitchNode;
use crate::resources::UIState;
use crate::Connected;
use crate::Pos;
use crate::{nodes::SwitchNode, resources::MousePos};
use specs::prelude::*;

use macroquad::prelude::*;

use crate::resources::CurrentModeText;

pub struct CurrentModeSys;
Expand Down Expand Up @@ -46,14 +44,12 @@ pub struct SwitchClickSys;
impl<'a> System<'a> for SwitchClickSys {
type SystemData = (
WriteStorage<'a, Connected<SwitchNode, 0, 1>>,
Read<'a, MousePos>,
ReadStorage<'a, Pos>,
);

fn run(&mut self, (mut switches, positions): Self::SystemData) {
let mouse_pos = {
let (mx, my) = mouse_position();
Vec2::new(mx, my)
};
fn run(&mut self, (mut switches, mouse_pos, positions): Self::SystemData) {
let mouse_pos = mouse_pos.0;

let target_switch = (&mut switches, &positions)
.join()
Expand Down
Loading

0 comments on commit f3bfe06

Please sign in to comment.