client/spectator.go

193 lines
4.5 KiB
Go
Raw Normal View History

package client
import (
2015-08-31 21:55:18 -07:00
"fmt"
2014-05-12 22:11:44 -07:00
"math"
2014-05-04 00:33:46 -07:00
"github.com/nsf/termbox-go"
"hackerbots.us/server"
)
2014-05-12 22:25:44 -07:00
var botDown rune = 'v'
var botUp rune = '^'
var botRight rune = '>'
var botLeft rune = '<'
2014-05-04 00:33:46 -07:00
type size struct {
width, height int
}
// Recv is our implementation of receiving a server.Boardstate from the server
2015-08-31 21:48:25 -07:00
func (s *Client) Recv(bs *server.Boardstate) map[string]server.Instruction {
s.StateStream <- bs
return nil
}
2014-05-04 00:33:46 -07:00
2015-08-31 21:48:25 -07:00
func (s *Client) Visualize() {
2014-05-04 00:33:46 -07:00
err := termbox.Init()
if err != nil {
2015-08-31 21:55:18 -07:00
panic(err)
2014-05-04 00:33:46 -07:00
}
s.viewX, s.viewY = termbox.Size()
2015-08-31 21:48:25 -07:00
events := make(chan termbox.Event, 1024)
2014-05-04 00:33:46 -07:00
go func() {
for {
events <- termbox.PollEvent()
}
}()
termbox.HideCursor()
termbox.Clear(termbox.ColorBlack, termbox.ColorBlack)
func() {
for {
select {
case event := <-events:
switch event.Type {
case termbox.EventKey:
switch event.Key {
case termbox.KeyCtrlZ, termbox.KeyCtrlC:
return
}
switch event.Ch {
case 'q':
return
case 'c':
termbox.Clear(termbox.ColorBlack, termbox.ColorBlack)
}
case termbox.EventResize:
s.viewX, s.viewY = event.Width, event.Height
case termbox.EventError:
2015-08-31 21:55:18 -07:00
panic(fmt.Sprintf("Quitting because of termbox error:\n%v\n", event.Err))
2014-05-04 00:33:46 -07:00
}
2015-08-31 21:48:25 -07:00
case u := <-s.StateStream:
2014-05-04 00:33:46 -07:00
termbox.Clear(termbox.ColorBlack, termbox.ColorBlack)
for _, obstacle := range u.Obstacles {
startX := int((obstacle.Bounds.A.X / s.width) * float64(s.viewX))
stopX := int((obstacle.Bounds.B.X / s.width) * float64(s.viewX))
startY := int((obstacle.Bounds.A.Y / s.height) * float64(s.viewY))
stopY := int((obstacle.Bounds.B.Y / s.height) * float64(s.viewY))
for x := startX; x < stopX; x++ {
for y := startY; y < stopY; y++ {
termbox.SetCell(
x,
s.viewY-y,
' ',
termbox.ColorBlack, termbox.ColorBlue,
)
}
}
}
2015-08-31 21:48:25 -07:00
for _, bot := range u.MyRobots {
2014-05-04 00:33:46 -07:00
x := int((bot.Position.X / s.width) * float64(s.viewX))
y := int((bot.Position.Y / s.height) * float64(s.viewY))
2014-05-12 22:25:44 -07:00
var b rune
if math.Abs(bot.Heading.X) > math.Abs(bot.Heading.Y) {
if bot.Heading.X > 0 {
b = botRight
} else {
b = botLeft
}
} else {
if bot.Heading.Y > 0 {
b = botUp
} else {
b = botDown
}
}
2014-05-04 00:33:46 -07:00
c := termbox.ColorWhite
2014-05-13 00:23:14 -07:00
if bot.Health <= 0 {
2014-05-04 00:33:46 -07:00
c = termbox.ColorBlack
}
termbox.SetCell(
x,
s.viewY-y,
b,
c|termbox.AttrBold, termbox.ColorBlack,
)
}
2015-08-31 21:48:25 -07:00
for _, bot := range u.OtherRobots {
x := int((bot.Position.X / s.width) * float64(s.viewX))
y := int((bot.Position.Y / s.height) * float64(s.viewY))
var b rune
if math.Abs(bot.Heading.X) > math.Abs(bot.Heading.Y) {
if bot.Heading.X > 0 {
b = botRight
} else {
b = botLeft
}
} else {
if bot.Heading.Y > 0 {
b = botUp
} else {
b = botDown
}
}
c := termbox.ColorRed
if bot.Health <= 0 {
c = termbox.ColorBlack
}
termbox.SetCell(
x,
s.viewY-y,
b,
c, termbox.ColorBlack,
)
}
2014-05-04 00:33:46 -07:00
for _, p := range u.Projectiles {
x := int((p.Position.X / s.width) * float64(s.viewX))
y := int((p.Position.Y / s.height) * float64(s.viewY))
termbox.SetCell(
x,
s.viewY-y,
'·',
termbox.ColorWhite|termbox.AttrBold, termbox.ColorBlack,
)
}
for _, splosion := range u.Splosions {
2014-05-12 22:11:44 -07:00
startX := int(((splosion.Position.X - float64(splosion.Radius)) / s.width) * float64(s.viewX))
startY := int(((splosion.Position.Y - float64(splosion.Radius)) / s.height) * float64(s.viewY))
stopX := int(((splosion.Position.X+float64(splosion.Radius))/s.width)*float64(s.viewX)) + 1
stopY := int(((splosion.Position.Y+float64(splosion.Radius))/s.height)*float64(s.viewY)) + 1
for x := startX; x < stopX; x++ {
for y := startY; y < stopY; y++ {
realX := float64(x) * s.width / float64(s.viewX)
realY := float64(y) * s.height / float64(s.viewY)
dX := realX - splosion.Position.X
dY := realY - splosion.Position.Y
curRad := math.Sqrt(dX*dX + dY*dY)
if curRad < float64(splosion.Radius) {
termbox.SetCell(
x,
s.viewY-y,
'·',
termbox.ColorYellow|termbox.AttrBold, termbox.ColorRed,
)
}
}
}
2014-05-04 00:33:46 -07:00
}
err := termbox.Flush()
if err != nil {
2015-08-31 21:55:18 -07:00
panic(err)
2014-05-04 00:33:46 -07:00
}
2014-05-13 00:23:14 -07:00
case <-s.Die:
return
2014-05-04 00:33:46 -07:00
}
}
}()
termbox.Close()
}