package projectile import ( "image/color" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/vector" ) // Projectile configuration type ProjectileConfig struct { Speed float64 Radius float64 Color color.NRGBA } type Projectile struct { X float64 Y float64 VelocityX float64 VelocityY float64 Radius float64 Color color.NRGBA Active bool } func New(x, y, directionX, directionY float64, config ProjectileConfig) *Projectile { return &Projectile{ X: x, Y: y, VelocityX: directionX * config.Speed, VelocityY: directionY * config.Speed, Radius: config.Radius, Color: config.Color, Active: true, } } func (p *Projectile) Update(dt float64, screenWidth, screenHeight float64) { p.X += p.VelocityX * dt p.Y += p.VelocityY * dt if p.X < 0 || p.X > screenWidth || p.Y < 0 || p.Y > screenHeight { p.Active = false } } func (p *Projectile) Draw(screen *ebiten.Image) { if !p.Active { return } vector.DrawFilledCircle( screen, float32(p.X), float32(p.Y), float32(p.Radius), p.Color, false, ) } // Projectile manager type Manager struct { Projectiles []*Projectile } func NewManager() *Manager { return &Manager{ Projectiles: make([]*Projectile, 0), } } func (m *Manager) Shoot(x, y, directionX float64, config ProjectileConfig) { p := New(x, y, directionX, 0, config) m.Projectiles = append(m.Projectiles, p) } func (m *Manager) Update(dt float64, screenWidth, screenHeight float64) { for i := len(m.Projectiles) - 1; i >= 0; i-- { p := m.Projectiles[i] p.Update(dt, screenWidth, screenHeight) if !p.Active { m.Projectiles = append(m.Projectiles[:i], m.Projectiles[i+1:]...) } } } func (m *Manager) Draw(screen *ebiten.Image) { for _, p := range m.Projectiles { p.Draw(screen) } } func (m *Manager) Clear() { m.Projectiles = make([]*Projectile, 0) }