use crate::game_object::{GameObject, ObjectType};
pub struct World {
pub game_objects: Vec<GameObject>,
pub gravity: f32,
}
impl World {
pub fn new() -> Self {
Self::with_gravity(980.0)
}
pub fn with_gravity(gravity: f32) -> Self {
Self {
game_objects: Vec::new(),
gravity,
}
}
pub fn empty() -> Self {
Self::new()
}
pub fn update(&mut self, dt: f32) {
for object in self.game_objects.iter_mut() {
if !object.active {
continue;
}
object.update_physics(dt, self.gravity);
object.update_animation(dt);
}
self.game_objects.sort_by_key(|obj| obj.z_index);
self.handle_collisions();
}
pub fn add_object(&mut self, object: GameObject) {
self.game_objects.push(object);
}
pub fn cleanup_inactive(&mut self) {
self.game_objects.retain(|obj| obj.active);
}
fn handle_collisions(&mut self) {
let mut collected_coin_indices = Vec::new();
let player_rect = self
.game_objects
.iter()
.find(|obj| obj.object_type == ObjectType::Player && obj.active)
.and_then(|p| p.get_collision_rect());
if let Some(player_rect) = player_rect {
for (i, object) in self.game_objects.iter().enumerate() {
if !object.active || object.object_type != ObjectType::Coin {
continue;
}
if let Some(coin_rect) = object.get_collision_rect() {
if player_rect.intersects(&coin_rect) {
println!("Colisão! Moeda #{} coletada.", i);
collected_coin_indices.push(i);
}
}
}
}
for i in collected_coin_indices.iter().rev() {
self.game_objects.remove(*i);
}
}
}