enum WeaponState { idle, firing } abstract class Weapon { final String name; final int idleSprite; final List fireFrames; final int damage; final int msPerFrame; WeaponState state = WeaponState.idle; int frameIndex = 0; int lastFrameTime = 0; Weapon({ required this.name, required this.idleSprite, required this.fireFrames, required this.damage, this.msPerFrame = 100, }); int get currentSprite => state == WeaponState.idle ? idleSprite : fireFrames[frameIndex]; /// Core firing logic. Returns true if a bullet was spent. bool fire(int currentTime, {required int currentAmmo}) { if (state == WeaponState.idle && currentAmmo > 0) { state = WeaponState.firing; frameIndex = 0; lastFrameTime = currentTime; return true; } return false; } void update(int currentTime) { if (state == WeaponState.firing) { if (currentTime - lastFrameTime > msPerFrame) { frameIndex++; lastFrameTime = currentTime; if (frameIndex >= fireFrames.length) { state = WeaponState.idle; frameIndex = 0; } } } } }