Hello,
I am experimenting in a SPECS game. And I am faced with a problem.
I go through a list of components (simplifying) speed and velocity. If 2 objects if collides, I have to update the velocity of one with that of the other.
In the example below this is not possible because of the borrow check rules.
Is there a possibility for going beyond this rule with the pointer or others (Rc, Box, RefCell, etc..) . Or should I have found another logic.
Thank you.
use specs::{Component, VecStorage, World, WorldExt};
use specs_derive::Component;
use specs::prelude::*;
use rand::prelude::*;
#[derive(Component, Debug)]
#[storage(VecStorage)]
pub struct Position{
pub x : f64,
pub y : f64,
}
#[derive(Component, Debug)]
#[storage(VecStorage)]
pub struct Velocity{
pub x : f64,
pub y : f64,
}
// in a real case, we add ´Entities<'a>´ so as not to compare the same ´Entities<'a>´
pub struct SysCollides;
impl<'a> System<'a> for SysCollides {
type SystemData = (ReadStorage<'a, Position>,
WriteStorage<'a, Velocity>,
);
fn run(&mut self, data: Self::SystemData) {
let ( positions, mut velocities) = data ;
for (pos_a, vel_a) in (& positions, & velocities ).join() {
for (pos_b, vel_b )in (& positions,& velocities).join() {
// condition to have same position
if pos_a.x == pos_b.x && pos_a.y == pos_b.y {
// if same position, else modify vel_b to be equal vel_a
// vel_b.x = vel_a.x;
// vel_b.y = vel_a.y;
}
}
}
}
}
fn initialize_entity(world: &mut World){
let mut rng = rand::thread_rng();
let pos_x : f64 = rng.gen_range(50.0, 700.0);
let pos_y : f64 = rng.gen_range(50.0, 500.0);
let vel_y : f64 = rng.gen_range(-1.0, 1.0);
let vel_x : f64 = rng.gen_range(-1.0, 1.0);
world.create_entity()
.with(Position{ x : pos_x, y : pos_y})
.with(Velocity{ x : vel_x, y : vel_y })
.build();
}
fn main() {
println!("Hello, world!");
let mut world = World::new();
// -- compoments --
world.register::<Position>();
world.register::<Velocity>();
for _ in 0..1000 {
initialize_entity(&mut world);
}
let mut dispatcher = DispatcherBuilder::new()
.with(SysCollides, "sys_collides", &[])
.build();
dispatcher.setup(&mut world);
let mut tps = 0;
// just for exemple run
'running : loop {
dispatcher.dispatch(&mut world);
world.maintain();
if tps >= 10_000 { break 'running; }
tps += 1;
}
}