revert: 移除 terrain 和 world,设计不合理

This commit is contained in:
kercylan98 2023-07-27 16:23:16 +08:00
parent 41ea022261
commit 361e269f12
6 changed files with 0 additions and 390 deletions

View File

@ -1,273 +0,0 @@
package builtin
import (
"github.com/kercylan98/minotaur/game"
"github.com/kercylan98/minotaur/utils/concurrent"
"github.com/kercylan98/minotaur/utils/log"
"sync/atomic"
)
// NewWorld 创建一个内置的游戏世界
func NewWorld[PlayerID comparable, Player game.Player[PlayerID]](guid int64, options ...WorldOption[PlayerID, Player]) *World[PlayerID, Player] {
world := &World[PlayerID, Player]{
guid: guid,
players: concurrent.NewBalanceMap[PlayerID, Player](),
playerActors: concurrent.NewBalanceMap[PlayerID, *concurrent.BalanceMap[int64, game.Actor]](),
owners: concurrent.NewBalanceMap[int64, PlayerID](),
actors: concurrent.NewBalanceMap[int64, game.Actor](),
}
for _, option := range options {
option(world)
}
return world
}
// World 游戏世界的内置实现,实现了基本的游戏世界接口
type World[PlayerID comparable, Player game.Player[PlayerID]] struct {
guid int64
actorGuid atomic.Int64
playerLimit int
players *concurrent.BalanceMap[PlayerID, Player]
playerActors *concurrent.BalanceMap[PlayerID, *concurrent.BalanceMap[int64, game.Actor]]
owners *concurrent.BalanceMap[int64, PlayerID]
actors *concurrent.BalanceMap[int64, game.Actor]
playerJoinWorldEventHandles []game.PlayerJoinWorldEventHandle[PlayerID, Player]
playerLeaveWorldEventHandles []game.PlayerLeaveWorldEventHandle[PlayerID, Player]
actorGeneratedEventHandles []game.ActorGeneratedEventHandle[PlayerID, Player]
actorAnnihilationEventHandles []game.ActorAnnihilationEventHandle[PlayerID, Player]
actorOwnerChangeEventHandles []game.ActorOwnerChangeEventHandle[PlayerID, Player]
worldResetEventHandles []game.WorldResetEventHandle[PlayerID, Player]
worldReleasedEventHandles []game.WorldReleaseEventHandle[PlayerID, Player]
released atomic.Bool
}
func (slf *World[PlayerID, Player]) GetGuid() int64 {
return slf.guid
}
func (slf *World[PlayerID, Player]) GetPlayerLimit() int {
return slf.playerLimit
}
func (slf *World[PlayerID, Player]) GetPlayer(id PlayerID) Player {
return slf.players.Get(id)
}
func (slf *World[PlayerID, Player]) GetPlayers() map[PlayerID]Player {
return slf.players.Map()
}
func (slf *World[PlayerID, Player]) GetActor(guid int64) game.Actor {
return slf.actors.Get(guid)
}
func (slf *World[PlayerID, Player]) GetActors() map[int64]game.Actor {
return slf.actors.Map()
}
func (slf *World[PlayerID, Player]) GetPlayerActor(id PlayerID, guid int64) game.Actor {
if actors := slf.playerActors.Get(id); actors != nil {
return actors.Get(guid)
}
return nil
}
func (slf *World[PlayerID, Player]) GetPlayerActors(id PlayerID) map[int64]game.Actor {
return slf.playerActors.Get(id).Map()
}
func (slf *World[PlayerID, Player]) IsExistPlayer(id PlayerID) bool {
return slf.players.Exist(id)
}
func (slf *World[PlayerID, Player]) IsExistActor(guid int64) bool {
return slf.actors.Exist(guid)
}
func (slf *World[PlayerID, Player]) IsOwner(id PlayerID, guid int64) bool {
actors := slf.playerActors.Get(id)
if actors != nil {
return actors.Exist(guid)
}
return false
}
func (slf *World[PlayerID, Player]) Join(player Player) error {
if slf.released.Load() {
return ErrWorldReleased
}
if slf.players.Size() >= slf.playerLimit && slf.playerLimit > 0 {
return ErrWorldPlayerLimit
}
log.Debug("World.Join", log.Int64("guid", slf.GetGuid()), log.Any("player", player.GetID()))
slf.players.Set(player.GetID(), player)
if actors := slf.playerActors.Get(player.GetID()); actors == nil {
actors = concurrent.NewBalanceMap[int64, game.Actor]()
slf.playerActors.Set(player.GetID(), actors)
}
slf.OnPlayerJoinWorldEvent(player)
return nil
}
func (slf *World[PlayerID, Player]) Leave(id PlayerID) {
player, exist := slf.players.GetExist(id)
if !exist {
return
}
log.Debug("World.Leave", log.Int64("guid", slf.GetGuid()), log.Any("player", player.GetID()))
slf.OnPlayerLeaveWorldEvent(player)
slf.playerActors.Get(player.GetID()).Range(func(guid int64, actor game.Actor) bool {
slf.OnActorAnnihilationEvent(actor)
slf.owners.Delete(guid)
return false
})
slf.playerActors.Delete(player.GetID())
slf.players.Delete(player.GetID())
}
func (slf *World[PlayerID, Player]) AddActor(actor game.Actor) {
guid := slf.actorGuid.Add(1)
actor.SetGuid(guid)
slf.actors.Set(actor.GetGuid(), actor)
slf.OnActorGeneratedEvent(actor)
}
func (slf *World[PlayerID, Player]) RemoveActor(guid int64) {
if actor, exist := slf.actors.GetExist(guid); exist {
slf.OnActorAnnihilationEvent(actor)
if id, exist := slf.owners.DeleteGetExist(guid); exist {
slf.playerActors.Get(id).Delete(guid)
}
slf.actors.Delete(guid)
}
}
func (slf *World[PlayerID, Player]) SetActorOwner(guid int64, id PlayerID) {
oldId, exist := slf.owners.GetExist(guid)
if exist && oldId == id {
return
}
actor := slf.GetActor(guid)
if actor == nil {
return
}
slf.owners.Set(guid, id)
slf.playerActors.Get(id).Set(guid, actor)
slf.OnActorOwnerChangeEvent(actor, oldId, id, false)
}
func (slf *World[PlayerID, Player]) RemoveActorOwner(guid int64) {
id, exist := slf.owners.GetExist(guid)
if !exist {
return
}
slf.owners.Delete(guid)
slf.playerActors.Get(id).Delete(guid)
slf.OnActorOwnerChangeEvent(slf.GetActor(guid), id, id, true)
}
func (slf *World[PlayerID, Player]) Reset() {
log.Debug("World", log.Int64("Reset", slf.guid))
slf.players.Clear()
slf.playerActors.Range(func(id PlayerID, actors *concurrent.BalanceMap[int64, game.Actor]) bool {
actors.Clear()
return false
})
slf.playerActors.Clear()
slf.owners.Clear()
slf.actors.Clear()
slf.actorGuid.Store(0)
slf.OnWorldResetEvent()
}
func (slf *World[PlayerID, Player]) Release() {
if !slf.released.Swap(true) {
log.Debug("World", log.Int64("Release", slf.guid))
slf.OnWorldReleaseEvent()
slf.Reset()
slf.players = nil
slf.playerActors = nil
slf.owners = nil
slf.actors = nil
slf.playerJoinWorldEventHandles = nil
slf.playerLeaveWorldEventHandles = nil
slf.actorGeneratedEventHandles = nil
slf.actorAnnihilationEventHandles = nil
slf.actorOwnerChangeEventHandles = nil
slf.worldResetEventHandles = nil
slf.worldReleasedEventHandles = nil
}
}
func (slf *World[PlayerID, Player]) RegWorldResetEvent(handle game.WorldResetEventHandle[PlayerID, Player]) {
slf.worldResetEventHandles = append(slf.worldResetEventHandles, handle)
}
func (slf *World[PlayerID, Player]) OnWorldResetEvent() {
for _, handle := range slf.worldResetEventHandles {
handle(slf)
}
}
func (slf *World[PlayerID, Player]) RegWorldReleaseEvent(handle game.WorldReleaseEventHandle[PlayerID, Player]) {
slf.worldReleasedEventHandles = append(slf.worldReleasedEventHandles, handle)
}
func (slf *World[PlayerID, Player]) OnWorldReleaseEvent() {
for _, handle := range slf.worldReleasedEventHandles {
handle(slf)
}
}
func (slf *World[PlayerID, Player]) RegPlayerJoinWorldEvent(handle game.PlayerJoinWorldEventHandle[PlayerID, Player]) {
slf.playerJoinWorldEventHandles = append(slf.playerJoinWorldEventHandles, handle)
}
func (slf *World[PlayerID, Player]) OnPlayerJoinWorldEvent(player Player) {
for _, handle := range slf.playerJoinWorldEventHandles {
handle(slf, player)
}
}
func (slf *World[PlayerID, Player]) RegPlayerLeaveWorldEvent(handle game.PlayerLeaveWorldEventHandle[PlayerID, Player]) {
slf.playerLeaveWorldEventHandles = append(slf.playerLeaveWorldEventHandles, handle)
}
func (slf *World[PlayerID, Player]) OnPlayerLeaveWorldEvent(player Player) {
for _, handle := range slf.playerLeaveWorldEventHandles {
handle(slf, player)
}
}
func (slf *World[PlayerID, Player]) RegActorGeneratedEvent(handle game.ActorGeneratedEventHandle[PlayerID, Player]) {
slf.actorGeneratedEventHandles = append(slf.actorGeneratedEventHandles, handle)
}
func (slf *World[PlayerID, Player]) OnActorGeneratedEvent(actor game.Actor) {
for _, handle := range slf.actorGeneratedEventHandles {
handle(slf, actor)
}
}
func (slf *World[PlayerID, Player]) RegActorAnnihilationEvent(handle game.ActorAnnihilationEventHandle[PlayerID, Player]) {
slf.actorAnnihilationEventHandles = append(slf.actorAnnihilationEventHandles, handle)
}
func (slf *World[PlayerID, Player]) OnActorAnnihilationEvent(actor game.Actor) {
for _, handle := range slf.actorAnnihilationEventHandles {
handle(slf, actor)
}
}
func (slf *World[PlayerID, Player]) RegActorOwnerChangeEvent(handle game.ActorOwnerChangeEventHandle[PlayerID, Player]) {
slf.actorOwnerChangeEventHandles = append(slf.actorOwnerChangeEventHandles, handle)
}
func (slf *World[PlayerID, Player]) OnActorOwnerChangeEvent(actor game.Actor, old, new PlayerID, isolated bool) {
for _, handle := range slf.actorOwnerChangeEventHandles {
handle(slf, actor, old, new, isolated)
}
}

View File

@ -1,8 +0,0 @@
package builtin
import "errors"
var (
ErrWorldPlayerLimit = errors.New("the number of players in the world has reached the upper limit") // 玩家数量达到上限
ErrWorldReleased = errors.New("the world has been released") // 世界已被释放
)

View File

@ -1,13 +0,0 @@
package builtin
import "github.com/kercylan98/minotaur/game"
// WorldOption 世界构建可选项
type WorldOption[PlayerID comparable, Player game.Player[PlayerID]] func(world *World[PlayerID, Player])
// WithWorldPlayerLimit 限制世界的玩家数量上限
func WithWorldPlayerLimit[PlayerID comparable, Player game.Player[PlayerID]](playerLimit int) WorldOption[PlayerID, Player] {
return func(world *World[PlayerID, Player]) {
world.playerLimit = playerLimit
}
}

View File

@ -1,9 +0,0 @@
package game
// Terrain2D 地形
type Terrain2D interface {
GetBlock(x, y int) Terrain2DBlock
GetBlocks() [][]Terrain2DBlock
GetWidth() int
GetHeight() int
}

View File

@ -1,9 +0,0 @@
package game
// Terrain2DBlock 地形块
type Terrain2DBlock interface {
// GetTerrain 获取归属的地形
GetTerrain() Terrain2D
// GetCost 获取移动消耗
GetCost() float64
}

View File

@ -1,78 +0,0 @@
package game
// World 游戏世界接口定义
type World[PlayerID comparable, P Player[PlayerID]] interface {
// GetGuid 获取世界的唯一标识符
GetGuid() int64
// GetPlayerLimit 获取玩家人数上限
GetPlayerLimit() int
// GetPlayer 根据玩家id获取玩家
GetPlayer(id PlayerID) P
// GetPlayers 获取世界中的所有玩家
GetPlayers() map[PlayerID]P
// GetActor 根据唯一标识符获取世界中的游戏对象
GetActor(guid int64) Actor
// GetActors 获取世界中的所有游戏对象
GetActors() map[int64]Actor
// GetPlayerActor 获取游戏世界中归属特定玩家的特定游戏对象
GetPlayerActor(id PlayerID, guid int64) Actor
// GetPlayerActors 获取游戏世界中归属特定玩家的所有游戏对象
GetPlayerActors(id PlayerID) map[int64]Actor
// IsExistPlayer 检查游戏世界中是否存在特定玩家
IsExistPlayer(id PlayerID) bool
// IsExistActor 检查游戏世界中是否存在特定游戏对象
IsExistActor(guid int64) bool
// IsOwner 检查游戏世界中的特定游戏对象是否归属特定玩家
IsOwner(id PlayerID, guid int64) bool
// Join 使特定玩家加入游戏世界
Join(player P) error
// Leave 使特定玩家离开游戏世界
Leave(id PlayerID)
// AddActor 添加游戏对象
AddActor(actor Actor)
// RemoveActor 移除游戏对象
RemoveActor(guid int64)
// SetActorOwner 设置游戏对象归属玩家
SetActorOwner(guid int64, id PlayerID)
// RemoveActorOwner 移除游戏对象归属,置为无主的
RemoveActorOwner(guid int64)
// Reset 重置世界资源
Reset()
// Release 释放世界资源,释放后世界将不可用
Release()
// RegWorldResetEvent 世界被重置后将立即执行被注册的事件处理函数
RegWorldResetEvent(handle WorldResetEventHandle[PlayerID, P])
OnWorldResetEvent()
// RegWorldReleaseEvent 世界被释放前将立即执行被注册的事件处理函数,此刻世界仍然可用
RegWorldReleaseEvent(handle WorldReleaseEventHandle[PlayerID, P])
OnWorldReleaseEvent()
// RegPlayerJoinWorldEvent 玩家进入世界时将立即执行被注册的事件处理函数
RegPlayerJoinWorldEvent(handle PlayerJoinWorldEventHandle[PlayerID, P])
OnPlayerJoinWorldEvent(player P)
// RegPlayerLeaveWorldEvent 玩家离开世界时将立即执行被注册的事件处理函数
RegPlayerLeaveWorldEvent(handle PlayerLeaveWorldEventHandle[PlayerID, P])
OnPlayerLeaveWorldEvent(player P)
// RegActorGeneratedEvent 游戏世界中的游戏对象生成完成时将立即执行被注册的事件处理函数
RegActorGeneratedEvent(handle ActorGeneratedEventHandle[PlayerID, P])
OnActorGeneratedEvent(actor Actor)
// RegActorAnnihilationEvent 游戏世界中的游戏对象被移除前执行被注册的事件处理函数
RegActorAnnihilationEvent(handle ActorAnnihilationEventHandle[PlayerID, P])
OnActorAnnihilationEvent(actor Actor)
// RegActorOwnerChangeEvent 游戏对象的归属被改变时立刻执行被注册的事件处理函数
RegActorOwnerChangeEvent(handle ActorOwnerChangeEventHandle[PlayerID, P])
OnActorOwnerChangeEvent(actor Actor, old, new PlayerID, isolated bool)
}
type (
WorldResetEventHandle[ID comparable, P Player[ID]] func(world World[ID, P])
WorldReleaseEventHandle[ID comparable, P Player[ID]] func(world World[ID, P])
PlayerJoinWorldEventHandle[ID comparable, P Player[ID]] func(world World[ID, P], player P)
PlayerLeaveWorldEventHandle[ID comparable, P Player[ID]] func(world World[ID, P], player P)
ActorGeneratedEventHandle[ID comparable, P Player[ID]] func(world World[ID, P], actor Actor)
ActorAnnihilationEventHandle[ID comparable, P Player[ID]] func(world World[ID, P], actor Actor)
ActorOwnerChangeEventHandle[ID comparable, P Player[ID]] func(world World[ID, P], actor Actor, old, new ID, isolated bool)
)