package game import ( "client/client" "client/elements" "client/fonts" "client/gamedata" "client/pb" "maps" "sync" "time" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/text/v2" "golang.org/x/exp/rand" ) var ( screenWidth = 640 screenHeight = 480 namelist = []string{"slappy", "mick", "rodney", "george", "ringo", "robin", "temitry "} ) func init() { rand.Seed(uint64(time.Now().UnixNano())) } type ClientData struct { Id int Address string Name string Position gamedata.Coordinates } type Game struct { name string blocky *elements.Block gameId int //players map[client.Identity] clients map[string]ClientData gameclient *client.Client cycle int position gamedata.Coordinates mu sync.Mutex } func NewGame() *Game { g := &Game{ gameclient: client.NewClient(), blocky: elements.NewBlock(), cycle: 0, name: namelist[rand.Intn(len(namelist))], } g.clients = make(map[string]ClientData) g.gameId = g.gameclient.GetIdentity() go g.gameclient.ReadData(g.HandleServerData) return g } func (g *Game) Update() error { x, y := ebiten.CursorPosition() g.position.X = float64(x) g.position.Y = float64(y) g.blocky.SetPosition(g.position) //broadcast our position if g.cycle%2 == 0 { if g.gameclient.IsConnected() { //g.gameclient.SendData(fmt.Sprintf("%s,%.0f,%.0f\n", g.name, g.position.X, g.position.Y)) cd := &pb.ClientCoordinates{ Name: g.name, Coordinates: &pb.Coordinates{ X: g.position.X, Y: g.position.Y, }, } g.gameclient.SendProtoData(cd) /* cd := *client.ClientData{ Name: g.name, Address: g. }*/ } } //cleanup client list every 2 seconds if g.cycle%120 == 0 { go g.CleanupClients() } g.cycle++ return nil } func (g *Game) Draw(screen *ebiten.Image) { screen.Clear() g.blocky.Draw() op := &ebiten.DrawImageOptions{} op.GeoM.Translate(-float64(g.blocky.Sprite.Bounds().Dx())/2, -float64(g.blocky.Sprite.Bounds().Dy())/2) op.GeoM.Translate(g.blocky.GetPosition().X, g.blocky.GetPosition().Y) screen.DrawImage(g.blocky.Sprite, op) f2 := &text.GoTextFace{ Source: fonts.LaunchyFont.New, Size: 12, } top := &text.DrawOptions{} top.GeoM.Translate(g.blocky.GetPosition().X-50, g.blocky.GetPosition().Y+15) text.Draw(screen, "you ("+g.name+")", f2, top) g.mu.Lock() clientcopy := maps.Clone(g.clients) g.mu.Unlock() for _, client := range clientcopy { op := &ebiten.DrawImageOptions{} op.GeoM.Translate(-float64(g.blocky.Sprite.Bounds().Dx())/2, -float64(g.blocky.Sprite.Bounds().Dy())/2) op.GeoM.Translate(client.Position.X, client.Position.Y) screen.DrawImage(g.blocky.Sprite, op) f2 := &text.GoTextFace{ Source: fonts.LaunchyFont.New, Size: 12, } top := &text.DrawOptions{} top.GeoM.Translate(client.Position.X, client.Position.Y) text.Draw(screen, client.Name, f2, top) } } func (g *Game) Layout(outsideWidth, outsideHeight int) (screenwidth, screenheight int) { return screenWidth, screenHeight } func (g *Game) HandleServerData(allclients *pb.AllClients) { for _, client := range allclients.Clients { //fmt.Println(client.Coordinates.X) //localaddr := g.gameclient.GetLocalAddr() if client.Id != int32(g.gameId) { update := ClientData{ Address: client.Address, Name: client.Name, Position: gamedata.Coordinates{ X: client.Coordinates.X, Y: client.Coordinates.Y, }, } g.mu.Lock() g.clients[update.Address] = update g.mu.Unlock() } } //log.Println(data) /* raw := data[1 : len(data)-1] clientinfo := strings.Split(raw, ";") for _, info := range clientinfo { subdata := strings.Split(info, ",") if len(subdata) == 4 { if g.gameclient.GetLocalAddr() != subdata[0] { x, err := strconv.Atoi(subdata[2]) if err != nil { x = 0 } y, err := strconv.Atoi(subdata[3]) if err != nil { y = 0 } update := ClientData{ Address: subdata[0], Name: subdata[1], Position: gamedata.Coordinates{ X: float64(x), Y: float64(y), }, } g.mu.Lock() g.clients[update.Address] = update g.mu.Unlock() } } } */ } func (g *Game) CleanupClients() { g.mu.Lock() for k := range g.clients { delete(g.clients, k) } g.mu.Unlock() }