diff options
| author | LLLL Colonq <llll@colonq> | 2026-08-04 04:35:44 -0400 |
|---|---|---|
| committer | LLLL Colonq <llll@colonq> | 2026-08-04 04:35:44 -0400 |
| commit | 3c7796f066647090ed8436778bdfe25f11844c05 (patch) | |
| tree | 0644a101004d91af4fcdc2f51fcc2e03f7f255ce /2026/games/rpc2dot0/src/collision.rs | |
| parent | a75221ab93f59d688f90cd83f0284ff98951fcfa (diff) | |
Prepare for upload
Diffstat (limited to '2026/games/rpc2dot0/src/collision.rs')
| -rw-r--r-- | 2026/games/rpc2dot0/src/collision.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/2026/games/rpc2dot0/src/collision.rs b/2026/games/rpc2dot0/src/collision.rs new file mode 100644 index 0000000..aaae9a7 --- /dev/null +++ b/2026/games/rpc2dot0/src/collision.rs @@ -0,0 +1,99 @@ +use crate::color::EntityColor;
+use crate::constants::{MAX_SPEED, MIN_SPEED, SPEED_COLLIDE_MULT};
+use crate::entity::Entity;
+use crate::math::BoundingCircle;
+use crate::random::RandomState;
+
+pub fn detect_collisions(entities: &[Entity], buffer: &mut Vec<(usize, usize)>) {
+ buffer.clear();
+ let len = entities.len();
+
+ for i in 0..len {
+ if !entities[i].alive {
+ continue;
+ }
+ for j in (i + 1)..len {
+ if !entities[j].alive {
+ continue;
+ }
+ if entities[i].overlaps_with(&entities[j]) {
+ buffer.push((i, j));
+ }
+ }
+ }
+}
+
+pub fn process_collisions(
+ entities: &mut Vec<Entity>,
+ rng: &mut RandomState,
+ _next_entity_id: &mut u32,
+ collision_buffer: &mut Vec<(usize, usize)>,
+ elapsed_ms: f32,
+ _events: &mut Vec<String>,
+) {
+ detect_collisions(entities, collision_buffer);
+
+ let new_entities = Vec::new();
+
+ for &(i, j) in collision_buffer.iter() {
+ if i >= entities.len() || j >= entities.len() {
+ continue;
+ }
+ if !entities[i].alive || !entities[j].alive {
+ continue;
+ }
+
+ let color_a = entities[i].color;
+ let color_b = entities[j].color;
+
+ match (color_a, color_b) {
+ (EntityColor::Green, EntityColor::Green) => {
+ if (rng.next_u32() & 1) == 0 {
+ entities[i].color = EntityColor::Yellow;
+ entities[j].color = EntityColor::Red;
+ entities[j].spawn_time_ms = Some(elapsed_ms);
+ } else {
+ entities[i].color = EntityColor::Red;
+ entities[i].spawn_time_ms = Some(elapsed_ms);
+ entities[j].color = EntityColor::Yellow;
+ }
+ }
+ (EntityColor::Red, EntityColor::Red) => {
+ let a = &entities[i];
+ let b = &entities[j];
+ let collision_point = (a.pos + b.pos) * 0.5;
+
+ entities[i].alive = false;
+ entities[j].alive = false;
+
+ let best_green_idx = entities
+ .iter()
+ .enumerate()
+ .filter(|(_, e)| e.alive && e.color == EntityColor::Green)
+ .min_by(|(_, e1), (_, e2)| {
+ e1.pos
+ .distance_squared(collision_point)
+ .partial_cmp(&e2.pos.distance_squared(collision_point))
+ .unwrap_or(std::cmp::Ordering::Equal)
+ })
+ .map(|(idx, _)| idx);
+
+ if let Some(idx) = best_green_idx {
+ entities[idx].alive = false;
+ }
+ }
+ _ => {
+ let a_speed = (entities[i].speed * SPEED_COLLIDE_MULT).clamp(MIN_SPEED, MAX_SPEED);
+ let b_speed = (entities[j].speed * SPEED_COLLIDE_MULT).clamp(MIN_SPEED, MAX_SPEED);
+ entities[i].speed = a_speed;
+ entities[j].speed = b_speed;
+ entities[i].normalize_velocity();
+ entities[j].normalize_velocity();
+ }
+ }
+ }
+
+ if !new_entities.is_empty() {
+ entities.extend(new_entities);
+ }
+}
|
