laneya2

cave exploration game
git clone https://git.ce9e.org/laneya2.git

commit
c0008e4afea67cbc431c575ee9a79bd06cb80f7a
parent
36014cd795e3214bdb5d376333d10599b14f3b7e
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2024-09-27 06:42
move monster and player to separate files

Diffstat

M game.go 126 ++++---------------------------------------------------------
A monster.go 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A player.go 40 ++++++++++++++++++++++++++++++++++++++++

3 files changed, 132 insertions, 119 deletions


diff --git a/game.go b/game.go

@@ -3,45 +3,10 @@ package main
    3     3 import (
    4     4 	"log"
    5     5 	"sync"
    6    -1 	"time"
    7    -1 
    8    -1 	"github.com/gorilla/websocket"
    9     6 )
   10     7 
   11     8 type Message map[string]interface{}
   12     9 
   13    -1 type Player struct {
   14    -1 	Game        *Game
   15    -1 	Send        chan []Message
   16    -1 	conn        *websocket.Conn
   17    -1 	alive       bool
   18    -1 	Id          int
   19    -1 	Pos         Point
   20    -1 	Speed       float32
   21    -1 	Health      int
   22    -1 	HealthTotal int
   23    -1 }
   24    -1 
   25    -1 type Monster struct {
   26    -1 	Game   *Game
   27    -1 	quit   chan bool
   28    -1 	Id     int
   29    -1 	Rune   rune
   30    -1 	Pos    Point
   31    -1 	Speed  float32
   32    -1 	Health int
   33    -1 }
   34    -1 
   35    -1 type PlayerMessage struct {
   36    -1 	Player *Player
   37    -1 	Msg    Message
   38    -1 }
   39    -1 
   40    -1 type MonsterMessage struct {
   41    -1 	Monster *Monster
   42    -1 	Msg     Message
   43    -1 }
   44    -1 
   45    10 type Game struct {
   46    11 	Id         string
   47    12 	Players    map[*Player]bool
@@ -91,41 +56,6 @@ func getGame(id string) *Game {
   91    56 	return game
   92    57 }
   93    58 
   94    -1 func (monster *Monster) run() {
   95    -1 	timeout := time.Duration(float32(time.Second) / monster.Speed)
   96    -1 	ticker := time.NewTicker(timeout)
   97    -1 	defer ticker.Stop()
   98    -1 
   99    -1 	for {
  100    -1 		select {
  101    -1 		case <-monster.quit:
  102    -1 			return
  103    -1 		case <-ticker.C:
  104    -1 			bestDist := 100000
  105    -1 			dir := "left"
  106    -1 			for player := range monster.Game.Players {
  107    -1 				dist := monster.Pos.Dist(player.Pos)
  108    -1 				if dist < bestDist {
  109    -1 					bestDist = dist
  110    -1 					dir = monster.Pos.Dir(player.Pos)
  111    -1 				}
  112    -1 			}
  113    -1 
  114    -1 			if bestDist > 10 || !monster.Game.IsFree(monster.Pos.Move(dir)) {
  115    -1 				dir = RandomDir()
  116    -1 			}
  117    -1 
  118    -1 			monster.Game.MMsg <- MonsterMessage{
  119    -1 				monster,
  120    -1 				Message{
  121    -1 					"action": "move",
  122    -1 					"dir":    dir,
  123    -1 				},
  124    -1 			}
  125    -1 		}
  126    -1 	}
  127    -1 }
  128    -1 
  129    59 func (game *Game) broadcast(msgs []Message) {
  130    60 	for player, _ := range game.Players {
  131    61 		player.Send <- msgs
@@ -159,17 +89,8 @@ func (game *Game) generateMap() {
  159    89 			lines = append(lines, makeRect(p1.X, p1.Y, p2.X, p1.Y))
  160    90 			lines = append(lines, makeRect(p2.X, p1.Y, p2.X, p2.Y))
  161    91 
  162    -1 			monster := Monster{
  163    -1 				Game:   game,
  164    -1 				quit:   make(chan bool),
  165    -1 				Id:     game.createId(),
  166    -1 				Rune:   'm',
  167    -1 				Pos:    rect.RandomPoint(),
  168    -1 				Speed:  2,
  169    -1 				Health: 10,
  170    -1 			}
  171    -1 			game.Monsters[&monster] = true
  172    -1 			go monster.run()
   -1    92 			monster := makeMonster(game, rect.RandomPoint())
   -1    93 			game.Monsters[monster] = true
  173    94 
  174    95 			prev = rect
  175    96 		}
@@ -330,22 +251,7 @@ func (game *Game) run() {
  330   251 				if !ok {
  331   252 					continue
  332   253 				}
  333    -1 				pos := player.Pos.Move(dir)
  334    -1 				monster := game.getMonsterAt(pos)
  335    -1 				if monster != nil {
  336    -1 					// TODO
  337    -1 				} else if game.IsFree(pos) {
  338    -1 					player.Pos = pos
  339    -1 					game.broadcast([]Message{
  340    -1 						Message{
  341    -1 							"action": "setPosition",
  342    -1 							"id":     player.Id,
  343    -1 							"pos":    player.Pos,
  344    -1 						},
  345    -1 					})
  346    -1 
  347    -1 					game.MaybeNextLevel()
  348    -1 				}
   -1   254 				player.Move(dir)
  349   255 			} else if verbose {
  350   256 				log.Println("unknown action", msg)
  351   257 			}
@@ -354,29 +260,11 @@ func (game *Game) run() {
  354   260 			msg := mmsg.Msg
  355   261 
  356   262 			if msg["action"] == "move" {
  357    -1 				pos := monster.Pos
  358    -1 				if msg["dir"] == "up" {
  359    -1 					pos.Y -= 1
  360    -1 				} else if msg["dir"] == "right" {
  361    -1 					pos.X += 1
  362    -1 				} else if msg["dir"] == "down" {
  363    -1 					pos.Y += 1
  364    -1 				} else if msg["dir"] == "left" {
  365    -1 					pos.X -= 1
  366    -1 				}
  367    -1 				player := game.getPlayerAt(pos)
  368    -1 				if player != nil {
  369    -1 					// TODO
  370    -1 				} else if game.getMonsterAt(pos) == nil && game.IsFree(pos) {
  371    -1 					monster.Pos = pos
  372    -1 					game.broadcast([]Message{
  373    -1 						Message{
  374    -1 							"action": "setPosition",
  375    -1 							"id":     monster.Id,
  376    -1 							"pos":    monster.Pos,
  377    -1 						},
  378    -1 					})
   -1   263 				dir, ok := msg["dir"].(string)
   -1   264 				if !ok {
   -1   265 					continue
  379   266 				}
   -1   267 				monster.Move(dir)
  380   268 			}
  381   269 		}
  382   270 	}

diff --git a/monster.go b/monster.go

@@ -0,0 +1,85 @@
   -1     1 package main
   -1     2 
   -1     3 import "time"
   -1     4 
   -1     5 type Monster struct {
   -1     6 	Game   *Game
   -1     7 	quit   chan bool
   -1     8 	Id     int
   -1     9 	Rune   rune
   -1    10 	Pos    Point
   -1    11 	Speed  float32
   -1    12 	Health int
   -1    13 }
   -1    14 
   -1    15 type MonsterMessage struct {
   -1    16 	Monster *Monster
   -1    17 	Msg     Message
   -1    18 }
   -1    19 
   -1    20 func makeMonster(game *Game, pos Point) *Monster {
   -1    21 	monster := &Monster{
   -1    22 		Game:   game,
   -1    23 		quit:   make(chan bool),
   -1    24 		Id:     game.createId(),
   -1    25 		Rune:   'm',
   -1    26 		Pos:    pos,
   -1    27 		Speed:  2,
   -1    28 		Health: 10,
   -1    29 	}
   -1    30 	go monster.run()
   -1    31 	return monster
   -1    32 }
   -1    33 
   -1    34 func (monster *Monster) run() {
   -1    35 	timeout := time.Duration(float32(time.Second) / monster.Speed)
   -1    36 	ticker := time.NewTicker(timeout)
   -1    37 	defer ticker.Stop()
   -1    38 
   -1    39 	for {
   -1    40 		select {
   -1    41 		case <-monster.quit:
   -1    42 			return
   -1    43 		case <-ticker.C:
   -1    44 			bestDist := 100000
   -1    45 			dir := "left"
   -1    46 			for player := range monster.Game.Players {
   -1    47 				dist := monster.Pos.Dist(player.Pos)
   -1    48 				if dist < bestDist {
   -1    49 					bestDist = dist
   -1    50 					dir = monster.Pos.Dir(player.Pos)
   -1    51 				}
   -1    52 			}
   -1    53 
   -1    54 			if bestDist > 10 || !monster.Game.IsFree(monster.Pos.Move(dir)) {
   -1    55 				dir = RandomDir()
   -1    56 			}
   -1    57 
   -1    58 			monster.Game.MMsg <- MonsterMessage{
   -1    59 				monster,
   -1    60 				Message{
   -1    61 					"action": "move",
   -1    62 					"dir":    dir,
   -1    63 				},
   -1    64 			}
   -1    65 		}
   -1    66 	}
   -1    67 }
   -1    68 
   -1    69 func (monster *Monster) Move(dir string) {
   -1    70 	game := monster.Game
   -1    71 	pos := monster.Pos.Move(dir)
   -1    72 	player := game.getPlayerAt(pos)
   -1    73 	if player != nil {
   -1    74 		// TODO
   -1    75 	} else if game.getMonsterAt(pos) == nil && game.IsFree(pos) {
   -1    76 		monster.Pos = pos
   -1    77 		game.broadcast([]Message{
   -1    78 			Message{
   -1    79 				"action": "setPosition",
   -1    80 				"id":     monster.Id,
   -1    81 				"pos":    monster.Pos,
   -1    82 			},
   -1    83 		})
   -1    84 	}
   -1    85 }

diff --git a/player.go b/player.go

@@ -0,0 +1,40 @@
   -1     1 package main
   -1     2 
   -1     3 import "github.com/gorilla/websocket"
   -1     4 
   -1     5 type Player struct {
   -1     6 	Game        *Game
   -1     7 	Send        chan []Message
   -1     8 	conn        *websocket.Conn
   -1     9 	alive       bool
   -1    10 	Id          int
   -1    11 	Pos         Point
   -1    12 	Speed       float32
   -1    13 	Health      int
   -1    14 	HealthTotal int
   -1    15 }
   -1    16 
   -1    17 type PlayerMessage struct {
   -1    18 	Player *Player
   -1    19 	Msg    Message
   -1    20 }
   -1    21 
   -1    22 func (player *Player) Move(dir string) {
   -1    23 	game := player.Game
   -1    24 	pos := player.Pos.Move(dir)
   -1    25 	monster := game.getMonsterAt(pos)
   -1    26 	if monster != nil {
   -1    27 		// TODO
   -1    28 	} else if game.IsFree(pos) {
   -1    29 		player.Pos = pos
   -1    30 		game.broadcast([]Message{
   -1    31 			Message{
   -1    32 				"action": "setPosition",
   -1    33 				"id":     player.Id,
   -1    34 				"pos":    player.Pos,
   -1    35 			},
   -1    36 		})
   -1    37 
   -1    38 		game.MaybeNextLevel()
   -1    39 	}
   -1    40 }