package main import ( v "bitbucket.org/hackerbots/vector" "log" ) type Projectile struct { Id string `json:"id"` Position v.Point2d `json:"position"` MoveTo v.Point2d `json:"-"` Radius int `json:"-"` Speed float32 `json:"-"` Damage int `json:"-"` Owner *Robot `json:"-"` } func (p *Projectile) Tick(g *game) { vec := p.MoveTo.Sub(p.Position) v_norm := vec.Normalize() v_scaled := v_norm.Scale(p.Speed * delta) newPos := p.Position.Add(v_scaled) hit_player := false for player := range g.players { for _, r := range player.Robots { if r == p.Owner { continue } player_rect := v.RectFromPoint(r.Position, 3) collision, _, _ := v.RectIntersection(player_rect, p.Position, v_scaled) if collision { hit_player = true if r.Health > 0 { // Direct hit causes more damage log.Printf("Direct Hit %v, Dmg:%v", r.Id, p.Damage) r.Health -= p.Damage r.Hit = true } } } } // Are we going to intersect the destination zone in this tick? r_dest := v.RectFromPoint(p.MoveTo, 3.0) travel := newPos.Sub(p.Position) arrived, _, pos := v.RectIntersection(r_dest, p.Position, travel) if !arrived { for _, obj := range g.obstacles { collision, _, pos := v.RectIntersection(obj.Bounds, p.Position, travel) if collision { arrived = true p.Position = pos } } } else { p.Position = pos } if arrived || hit_player { delete(g.projectiles, p) // Spawn a splosion splo := &Splosion{ Id: p.Id, Position: p.Position, Radius: p.Radius, Lifespan: 8, } g.splosions[splo] = true for player := range g.players { for _, r := range player.Robots { dist := v.Distance(r.Position, p.Position) if dist < float32(p.Radius) { if r.Health > 0 { r.Health -= p.Damage r.Hit = true } } } } } else { p.Position.X = newPos.X p.Position.Y = newPos.Y } }