initial go implementation
This commit is contained in:
parent
3c0128b9b9
commit
d777a978ab
39
game.go
Normal file
39
game.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type game struct {
|
||||||
|
players map[*player]bool
|
||||||
|
broadcast chan *player
|
||||||
|
register chan *player
|
||||||
|
unregister chan *player
|
||||||
|
}
|
||||||
|
|
||||||
|
var g = game{
|
||||||
|
broadcast: make(chan *player),
|
||||||
|
register: make(chan *player),
|
||||||
|
unregister: make(chan *player),
|
||||||
|
players: make(map[*player]bool),
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *game) run() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case c := <-g.register:
|
||||||
|
g.players[c] = true
|
||||||
|
case c := <-g.unregister:
|
||||||
|
delete(g.players, c)
|
||||||
|
close(c.send)
|
||||||
|
case p := <-g.broadcast:
|
||||||
|
for c := range g.players {
|
||||||
|
if p != c {
|
||||||
|
select {
|
||||||
|
case c.send <- p:
|
||||||
|
default:
|
||||||
|
delete(g.players, c)
|
||||||
|
close(c.send)
|
||||||
|
go c.ws.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
main.go
Normal file
30
main.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.google.com/p/go.net/websocket"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var addr = flag.String("addr", ":8666", "http service address")
|
||||||
|
var static_files = flag.String("static", "./static", "location of static files")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
http.Handle("/", http.FileServer(http.Dir(
|
||||||
|
fmt.Sprintf("%s/html", *static_files))))
|
||||||
|
http.Handle("/static/", http.StripPrefix("/static/",
|
||||||
|
http.FileServer(http.Dir(*static_files))))
|
||||||
|
|
||||||
|
http.Handle("/ws/game/", websocket.Handler(addPlayer))
|
||||||
|
|
||||||
|
go g.run()
|
||||||
|
|
||||||
|
err := http.ListenAndServe(*addr, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("unable to start server")
|
||||||
|
}
|
||||||
|
}
|
83
player.go
Normal file
83
player.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.google.com/p/go.net/websocket"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Position struct {
|
||||||
|
X, Y int
|
||||||
|
}
|
||||||
|
|
||||||
|
type player struct {
|
||||||
|
Position Position `json:"position"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ws *websocket.Conn
|
||||||
|
send chan *player
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *player) validMove(next Position) (r bool) {
|
||||||
|
r = true
|
||||||
|
if math.Abs(float64(p.Position.X - next.X)) > 1 {
|
||||||
|
r = false
|
||||||
|
}
|
||||||
|
if math.Abs(float64(p.Position.Y - next.Y)) > 1 {
|
||||||
|
r = false
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *player) sender() {
|
||||||
|
for pinfo := range p.send {
|
||||||
|
err := websocket.JSON.Send(p.ws, pinfo)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.ws.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *player) recv() {
|
||||||
|
for {
|
||||||
|
var msg string
|
||||||
|
err := websocket.Message.Receive(p.ws, &msg)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// XXX: the danger!
|
||||||
|
var pos Position
|
||||||
|
err = json.Unmarshal([]byte(msg), &pos)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !p.validMove(pos) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p.Position = pos
|
||||||
|
g.broadcast <- p
|
||||||
|
}
|
||||||
|
p.ws.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func addPlayer(ws *websocket.Conn) {
|
||||||
|
var name string
|
||||||
|
err := websocket.Message.Receive(ws, &name)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("trouble parsing username")
|
||||||
|
}
|
||||||
|
p := &player{
|
||||||
|
Name: name,
|
||||||
|
send: make(chan *player, 256),
|
||||||
|
ws: ws,
|
||||||
|
}
|
||||||
|
g.register <- p
|
||||||
|
defer func() {
|
||||||
|
g.unregister <- p
|
||||||
|
}()
|
||||||
|
go p.sender()
|
||||||
|
p.recv()
|
||||||
|
fmt.Printf("%v has been disconnect from this game\n", p)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user