server
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
package instance
|
||||
|
||||
import "google.golang.org/protobuf/proto"
|
||||
|
||||
type Msg2Client struct {
|
||||
SID string
|
||||
UID int
|
||||
Msg proto.Message
|
||||
}
|
||||
@@ -3,11 +3,16 @@ package instance
|
||||
import (
|
||||
"common/discover"
|
||||
"common/log"
|
||||
"common/proto/gen/cs"
|
||||
"common/proto/gen/grpc_pb"
|
||||
"common/utils"
|
||||
"context"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"runtime/debug"
|
||||
"scene/grpc_server/stream_client"
|
||||
"scene/npc"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@@ -15,27 +20,27 @@ import (
|
||||
// Instance 场景类
|
||||
type Instance struct {
|
||||
wg sync.WaitGroup
|
||||
players map[int]*PlayerNode // 存储所有玩家节点 [uid]
|
||||
ctx context.Context // 停止指令
|
||||
cancel context.CancelFunc // 停止函数
|
||||
players map[int]*npc.PlayerNode // 存储所有玩家节点 [uid]
|
||||
ctx context.Context // 停止指令
|
||||
cancel context.CancelFunc // 停止函数
|
||||
logger *zap.SugaredLogger // 日志
|
||||
|
||||
SID int64 // 服务ID
|
||||
InstanceID int // 副本ID
|
||||
UniqueNo int64 // 唯一编号
|
||||
EventIn chan proto.Message // 消息入口
|
||||
EventOut chan *Msg2Client // 消息出口
|
||||
}
|
||||
|
||||
// NewScene 初始化场景
|
||||
func NewScene(sid int64, instanceID int) *Instance {
|
||||
s := &Instance{
|
||||
players: make(map[int]*PlayerNode),
|
||||
players: make(map[int]*npc.PlayerNode),
|
||||
SID: sid,
|
||||
InstanceID: instanceID,
|
||||
UniqueNo: utils.SnowflakeInstance().Generate().Int64(),
|
||||
EventIn: make(chan proto.Message),
|
||||
EventOut: make(chan *Msg2Client),
|
||||
}
|
||||
s.logger = log.GetLogger().Named(fmt.Sprintf("%v:%v", s.InstanceID, s.UniqueNo))
|
||||
s.ctx, s.cancel = context.WithCancel(context.Background())
|
||||
return s
|
||||
}
|
||||
@@ -46,20 +51,20 @@ func (i *Instance) Start(ttl int64) {
|
||||
defer i.wg.Done()
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Infof("instance err: %v, uniqueNo: %v", err, i.UniqueNo)
|
||||
i.logger.Infof("instance err: %v", err)
|
||||
debug.PrintStack()
|
||||
}
|
||||
}()
|
||||
Mgr.Add(i.UniqueNo, i)
|
||||
defer func() {
|
||||
log.Infof("instance destroy: %v, %v", i.InstanceID, i.UniqueNo)
|
||||
i.logger.Infof("instance destroy")
|
||||
discover.UnRegisterInstance(i.UniqueNo)
|
||||
close(i.EventIn)
|
||||
Mgr.Delete(i.UniqueNo)
|
||||
}()
|
||||
|
||||
if err := discover.RegisterInstance(i.SID, i.InstanceID, i.UniqueNo, ttl); err != nil {
|
||||
log.Errorf("register discover error")
|
||||
i.logger.Errorf("register discover error")
|
||||
return
|
||||
}
|
||||
// 场景心跳
|
||||
@@ -75,23 +80,46 @@ func (i *Instance) Start(ttl int64) {
|
||||
}
|
||||
}
|
||||
}()
|
||||
log.Infof("new scene start: %v, %v", i.InstanceID, i.UniqueNo)
|
||||
i.logger.Infof("new scene start")
|
||||
}
|
||||
|
||||
// 网络帧
|
||||
func (i *Instance) onEvent(e proto.Message) {
|
||||
switch v := e.(type) {
|
||||
case *grpc_pb.EnterReq:
|
||||
i.players[int(v.UID)] = npc.NewPlayerNode(v.GatewaySID, int(v.UID))
|
||||
case *grpc_pb.ActionReq:
|
||||
if node, ok := i.players[int(v.UID)]; ok {
|
||||
node.addAction(v)
|
||||
node.AddAction(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 逻辑帧
|
||||
func (i *Instance) onLogic() {
|
||||
positionUpdate := make([]*cs.PositionInfo, 0)
|
||||
sid := int64(0)
|
||||
// 优先处理移动指令
|
||||
for _, node := range i.players {
|
||||
node.logicMove()
|
||||
if node.LogicMove() {
|
||||
positionUpdate = append(positionUpdate, &cs.PositionInfo{
|
||||
UID: int32(node.UID),
|
||||
X: node.Position[0],
|
||||
Y: node.Position[1],
|
||||
})
|
||||
sid = node.GatewaySID
|
||||
}
|
||||
}
|
||||
if len(positionUpdate) > 0 {
|
||||
payload, _ := proto.Marshal(&cs.S2C_Position{
|
||||
Info: positionUpdate,
|
||||
})
|
||||
if err := stream_client.SendMessageToGateway(sid, stream_client.FunToClient, &grpc_pb.ToClientReq{
|
||||
UID: -1,
|
||||
MessageID: int32(cs.MessageID_MESSAGE_ID_POSITION),
|
||||
Payload: payload,
|
||||
}); err != nil {
|
||||
i.logger.Errorf("send action err: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package instance
|
||||
|
||||
import (
|
||||
"common/proto/gen/grpc_pb"
|
||||
)
|
||||
|
||||
// PlayerNode 定义玩家节点结构体
|
||||
type PlayerNode struct {
|
||||
ID int
|
||||
Position [2]float64 // 二维坐标 [x, y]
|
||||
MoveCross int8 // 移动十字,1 上 2 下 4 左 8 右
|
||||
Action []*grpc_pb.ActionReq // 其他操作
|
||||
}
|
||||
|
||||
// 将指令存储到玩家身上
|
||||
func (p *PlayerNode) addAction(e *grpc_pb.ActionReq) {
|
||||
if e.Action < 16 {
|
||||
p.MoveCross = int8(e.Action)
|
||||
} else {
|
||||
p.Action = append(p.Action, e)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
DirUp int8 = 1 << iota // 1 (00000001)
|
||||
DirDown // 2 (00000010)
|
||||
DirLeft // 4 (00000100)
|
||||
DirRight // 8 (00001000)
|
||||
)
|
||||
|
||||
// 逻辑帧-移动
|
||||
func (p *PlayerNode) logicMove() {
|
||||
if p.MoveCross&DirUp != 0 && p.MoveCross&DirDown != 0 {
|
||||
p.MoveCross &^= DirUp | DirDown
|
||||
}
|
||||
if p.MoveCross&DirLeft != 0 && p.MoveCross&DirRight != 0 {
|
||||
p.MoveCross &^= DirLeft | DirRight
|
||||
}
|
||||
|
||||
var moveX, moveY float64
|
||||
if p.MoveCross&DirUp != 0 {
|
||||
moveY += 1
|
||||
}
|
||||
if p.MoveCross&DirDown != 0 {
|
||||
moveY -= 1
|
||||
}
|
||||
if p.MoveCross&DirLeft != 0 {
|
||||
moveX -= 1
|
||||
}
|
||||
if p.MoveCross&DirRight != 0 {
|
||||
moveX += 1
|
||||
}
|
||||
|
||||
if moveX != 0 && moveY != 0 {
|
||||
const diagonalFactor = 0.7071
|
||||
moveX *= diagonalFactor
|
||||
moveY *= diagonalFactor
|
||||
}
|
||||
|
||||
speed := 100.0
|
||||
p.Position[0] += moveX * speed
|
||||
p.Position[1] += moveY * speed
|
||||
}
|
||||
Reference in New Issue
Block a user