package demonchime import "core:math" import "core:math/linalg" import "core:log" import "phys" Bullet :: struct { handle: Entity_Handle, body: phys.Body_Handle, sprite: Sprite, vel: Vec2, lifetime: f32, lifetime_max: f32, } make_bullet :: proc( pos: Vec2, vel: Vec2, lifetime: f32 = 5, image_id := Image_Id.Bullet, layers: bit_set[phys.Layer;u16] = {.Player_Projectile}, mask: bit_set[phys.Layer;u16] = {.Default}, ) -> (Entity_Handle, ^Bullet) { sprite: Sprite init_sprite(&sprite, image_id) sprite.offset = { 0, // math.round(f32(sprite.width) * 0.5), math.round(f32(sprite.height) * 0.5), } sprite.rotation = math.atan2(vel.y, vel.x) * math.DEG_PER_RAD sprite.pos = pos body_rect := phys.Rect{ start = {-3, -3}, size = {6, 6}, } body := phys.make_body(body_rect, layers, mask) phys.set_velocity(body, vel) phys.set_position(body, pos) return make_entity(&state.bullet_list, Bullet{ body = body, sprite = sprite, vel = vel, lifetime = lifetime, lifetime_max = lifetime, }) } delete_bullet :: proc(h: Entity_Handle) { b := get_entity(state.bullet_list, h) phys.remove_body(b.body) delete_entity(&state.bullet_list, h) } update_bullets :: proc(dt: f32) { iter := iter_entity_list(state.bullet_list) for b in entity_list_iter(&iter) { b.lifetime -= dt phys.update_body(b.body) if phys.get_collisions(b.body) != nil || b.lifetime < 0 { delete_bullet(b.handle) continue } phys.set_velocity( b.body, linalg.lerp(b.vel, Vec2{0, 0}, 1 - b.lifetime / b.lifetime_max), ) b.sprite.pos = phys.get_position(b.body) b.sprite.scale.x = math.max(b.lifetime / b.lifetime_max, 0.1) } } draw_bullets :: proc() { iter := iter_entity_list(state.bullet_list) for b in entity_list_iter(&iter) { draw_sprite(b.sprite) } } clear_bullets :: proc() { iter := iter_entity_list(state.bullet_list) for b in entity_list_iter(&iter) { delete_bullet(b.handle) } } on_room_open_bullets :: proc(room_id: Room_Id) { clear_bullets() }