package demonchime import "core:math" import "core:math/linalg" import "core:log" import hm "core:container/handle_map" import "fw" import "phys" Bullet :: struct { handle: 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] = {.Hard}, ) -> (Handle, ^Bullet) { sprite: Sprite init_sprite(&sprite, image_id) set_sprite_offset_percentage(&sprite, {0, 0.5}) sprite.rotation = math.atan2(vel.y, vel.x) 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) handle := hm.add(&state.bullet_list, Bullet{ body = body, sprite = sprite, vel = vel, lifetime = lifetime, lifetime_max = lifetime, }) return handle, hm.get(&state.bullet_list, handle) } delete_bullet :: proc(h: Handle) { b := hm.get(&state.bullet_list, h) phys.remove_body(b.body) hm.remove(&state.bullet_list, h) } update_bullets :: proc(dt: f32) { iter := hm.iterator_make(&state.bullet_list) for b, _ in hm.iterate(&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 := hm.iterator_make(&state.bullet_list) for b, _ in hm.iterate(&iter) { draw_sprite(b.sprite) } } clear_bullets :: proc() { iter := hm.iterator_make(&state.bullet_list) for b, _ in hm.iterate(&iter) { delete_bullet(b.handle) } } on_room_open_bullets :: proc(room_id: Room_Id) { clear_bullets() }