diff --git a/game.go b/game.go index d6d43fd..fa5ee4e 100644 --- a/game.go +++ b/game.go @@ -22,6 +22,7 @@ type Boardstate struct { OtherRobots []OtherRobot `json:"robots"` Projectiles []Projectile `json:"projectiles"` Splosions []Splosion `json:"splosions"` + Obstacles []Obstacle `json:"obj"` Reset bool `json:"reset"` Type string `json:"type"` Turn int `json:"turn"` @@ -85,6 +86,7 @@ type game struct { players map[*player]bool projectiles map[*Projectile]bool splosions map[*Splosion]bool + obstacles []Obstacle register chan *player unregister chan *player turn int @@ -102,6 +104,7 @@ func NewGame(id string, width, height float32) *game { unregister: make(chan *player, maxPlayer), projectiles: make(map[*Projectile]bool), splosions: make(map[*Splosion]bool), + obstacles: GenerateObstacles(5, width, height), players: make(map[*player]bool), turn: 0, width: width, @@ -117,6 +120,8 @@ func NewGame(id string, width, height float32) *game { func (g *game) tick(payload *Boardstate) int { robots_remaining := 0 + payload.Obstacles = g.obstacles + // Update Players for p := range g.players { if p.Robot.Health > 0 { @@ -163,6 +168,7 @@ func (g *game) send_update(payload *Boardstate) { player_payload := NewBoardstate() player_payload.Projectiles = payload.Projectiles player_payload.Splosions = payload.Splosions + player_payload.Obstacles = payload.Obstacles player_payload.AllBots = payload.AllBots player_payload.Turn = payload.Turn player_payload.Reset = payload.Reset @@ -242,7 +248,7 @@ func (g *game) run() { log.Printf("Robot %v Wins", p.Robot.Id) log.Printf("game %s: game over", g.id) } - p.reset() + p.reset(g) } payload.Reset = true } else { diff --git a/obstacle.go b/obstacle.go new file mode 100644 index 0000000..529f144 --- /dev/null +++ b/obstacle.go @@ -0,0 +1,29 @@ +package main + +import ( + v "bitbucket.org/hackerbots/vector" + "math/rand" +) + +type Obstacle struct { + Bounds v.Rect2d `json:"bounds"` +} + +func GenerateObstacles(count int, width, height float32) []Obstacle { + out := []Obstacle{} + for i := 0; i < count; i++ { + x := rand.Float32() * width + y := rand.Float32() * height + w := rand.Float32() * width / 10 + h := rand.Float32() * height / 10 + out = append( + out, + Obstacle{ + Bounds: v.Rect2d{ + A: v.Point2d{X: x, Y: y}, + B: v.Point2d{X: 20 + x + w, Y: 20 + y + h}, + }, + }) + } + return out +} diff --git a/player.go b/player.go index d0392df..f66d074 100644 --- a/player.go +++ b/player.go @@ -83,10 +83,20 @@ func (p *player) checkCollisions(g *game, move_vector v.Vector2d) (bool, v.Point } } + // Check Obstacles + for _, obj := range g.obstacles { + collision, _, pos := v.RectIntersection(obj.Bounds, p.Robot.Position, move_vector) + if collision { + log.Printf("Object Collision %v hit %v, rect:%v", p.Robot.Position, move_vector, obj.Bounds) + return collision, pos, nil + } + } + return collision, intersection_point, nil } func (p *player) Tick(g *game) { + p.Robot.Collision = false p.scan(g.players) // Adjust Speed @@ -129,15 +139,16 @@ func (p *player) Tick(g *game) { move_vector := new_heading.Scale(p.Robot.Speed * delta) collision, _, hit_player := p.checkCollisions(g, move_vector) if collision { + p.Robot.Collision = true if hit_player != nil { hit_player.Robot.Health -= int(p.Robot.Speed / 10.0) - hit_player.Robot.Speed = (hit_player.Robot.Speed * 0.5) + hit_player.Robot.Speed = (hit_player.Robot.Speed * 0.1) hit_player.Robot.Heading = p.Robot.Heading } - // p.Robot.Position = intersection_point + //p.Robot.Position = intersection_point p.Robot.Health -= int(p.Robot.Speed / 10.0) p.Robot.MoveTo = &p.Robot.Position - p.Robot.Speed = (p.Robot.Speed * 0.5) + p.Robot.Speed = (p.Robot.Speed * 0.1) p.Robot.Heading = p.Robot.Heading.Scale(-1.0) } else { p.Robot.Position = p.Robot.Position.Add(move_vector) @@ -197,12 +208,26 @@ func (p *player) fire(projectiles map[*Projectile]bool, turn int) *Projectile { } } -func (p *player) reset() { - start_pos := v.Point2d{ - X: rand.Float32() * float32(*width), - Y: rand.Float32() * float32(*height), +func (p *player) reset(g *game) { + for { + start_pos := v.Point2d{ + X: rand.Float32() * float32(*width), + Y: rand.Float32() * float32(*height), + } + p.Robot.MoveTo = &start_pos + p.Robot.Position = start_pos + p.Robot.Health = p.Robot.Stats.Hp + + // Check Obstacles + retry := false + for _, obj := range g.obstacles { + _, inside, _ := v.RectIntersection(obj.Bounds, p.Robot.Position, v.Vector2d{0, 0}) + if inside { + retry = true + } + } + if !retry { + break + } } - p.Robot.MoveTo = &start_pos - p.Robot.Position = start_pos - p.Robot.Health = p.Robot.Stats.Hp } diff --git a/projectile.go b/projectile.go index 67b1e5a..65f1df4 100644 --- a/projectile.go +++ b/projectile.go @@ -35,6 +35,16 @@ func (p *Projectile) Tick(g *game) { travel := newPos.Sub(p.Position) arrived, _, _ := v.RectIntersection(r_dest, p.Position, travel) + + if !arrived { + for _, obj := range g.obstacles { + collision, _, _ := v.RectIntersection(obj.Bounds, p.Position, travel) + if collision { + arrived = true + } + } + } + if arrived || hit_player { delete(g.projectiles, p) diff --git a/protocol.go b/protocol.go index ba2f7ba..c1ba03a 100644 --- a/protocol.go +++ b/protocol.go @@ -173,7 +173,7 @@ func addPlayer(ws *websocket.Conn) { send: make(chan *Boardstate), ws: ws, } - p.reset() + p.reset(game) game.register <- p defer func() { game.unregister <- p diff --git a/robot.go b/robot.go index 6a94f73..47a206f 100644 --- a/robot.go +++ b/robot.go @@ -17,6 +17,7 @@ type Robot struct { FireAt *v.Point2d `json:"-"` Scanners []Scanner `json:"scanners"` LastFired int `json:"-"` + Collision bool `json:"collision"` } // This is the subset of data we send to players about robots