aceld
6 years ago
7 changed files with 434 additions and 0 deletions
-
7zinx_app_demo/mmo_game/conf/zinx.json
-
103zinx_app_demo/mmo_game/core/player.go
-
BINzinx_app_demo/mmo_game/game_client/client.exe
-
2zinx_app_demo/mmo_game/pb/build.sh
-
263zinx_app_demo/mmo_game/pb/msg.pb.go
-
27zinx_app_demo/mmo_game/pb/msg.proto
-
32zinx_app_demo/mmo_game/server.go
@ -0,0 +1,7 @@ |
|||
{ |
|||
"Name":"Zinx Game", |
|||
"Host":"0.0.0.0", |
|||
"TcpPort":8999, |
|||
"MaxConn":3000, |
|||
"WorkerPoolSize":10 |
|||
} |
@ -0,0 +1,103 @@ |
|||
package core |
|||
|
|||
import ( |
|||
"fmt" |
|||
"github.com/golang/protobuf/proto" |
|||
"math/rand" |
|||
"zinx/ziface" |
|||
"zinx/zinx_app_demo/mmo_game/pb" |
|||
) |
|||
|
|||
//玩家对象
|
|||
type Player struct { |
|||
Pid int32 //玩家ID
|
|||
Conn ziface.IConnection //当前玩家的连接
|
|||
X float32 //平面x坐标
|
|||
Y float32 //高度
|
|||
Z float32 //平面y坐标 (注意不是Y)
|
|||
V float32 //旋转0-360度
|
|||
} |
|||
|
|||
//创建一个玩家对象
|
|||
func NewPlayer(conn ziface.IConnection, pid int32) *Player { |
|||
p := &Player{ |
|||
Pid : pid, |
|||
Conn:conn, |
|||
X:float32(160 + rand.Intn(10)),//随机在160坐标点 基于X轴偏移若干坐标
|
|||
Y:0, //高度为0
|
|||
Z:float32(134 + rand.Intn(17)), //随机在134坐标点 基于Y轴偏移若干坐标
|
|||
V:0, //角度为0,尚未实现
|
|||
} |
|||
|
|||
return p |
|||
} |
|||
|
|||
//告知客户端pid,同步已经生成的玩家ID给客户端
|
|||
func (p *Player) SyncPid() { |
|||
//组建MsgId0 proto数据
|
|||
data := &pb.SyncPid{ |
|||
Pid:p.Pid, |
|||
} |
|||
|
|||
//发送数据给客户端
|
|||
p.SendMsg(1, data) |
|||
} |
|||
|
|||
//广播玩家自己的出生地点
|
|||
func (p *Player) BroadCastStartPosition() { |
|||
|
|||
msg := &pb.BroadCast{ |
|||
Pid:p.Pid, |
|||
Tp:2,//TP2 代表广播坐标
|
|||
Data: &pb.BroadCast_P{ |
|||
&pb.Position{ |
|||
X:p.X, |
|||
Y:p.Y, |
|||
Z:p.Z, |
|||
V:p.V, |
|||
}, |
|||
}, |
|||
} |
|||
|
|||
p.SendMsg(200, msg) |
|||
} |
|||
|
|||
//广播玩家的自身地理位置信息
|
|||
func (p *Player) SyncSurrounding() { |
|||
//TODO 根据自己的位子,获取周围九宫格内的玩家PID
|
|||
|
|||
//TODO 根据获取的PID集合, 获取所有的玩家信息
|
|||
|
|||
//TODO 构建自己的上线地点坐标
|
|||
|
|||
//TODO
|
|||
} |
|||
|
|||
|
|||
/* |
|||
发送消息给客户端, |
|||
主要是将pb的protobuf数据序列化之后发送 |
|||
*/ |
|||
func (p *Player) SendMsg(msgId uint32, data proto.Message) { |
|||
fmt.Printf("before Marshal data = %+v\n", data) |
|||
//将proto Message结构体序列化
|
|||
msg, err := proto.Marshal(data) |
|||
if err != nil { |
|||
fmt.Println("marshal msg err: ", err) |
|||
return |
|||
} |
|||
fmt.Printf("after Marshal data = %+v\n", msg) |
|||
|
|||
if p.Conn == nil { |
|||
fmt.Println("connection in player is nil") |
|||
return |
|||
} |
|||
|
|||
//调用Zinx框架的SendMsg发包
|
|||
if err := p.Conn.SendMsg(msgId, msg); err != nil { |
|||
fmt.Println("Player SendMsg error !") |
|||
return |
|||
} |
|||
|
|||
return |
|||
} |
@ -0,0 +1,2 @@ |
|||
#!/bin/bash |
|||
protoc --go_out=. *.proto |
@ -0,0 +1,263 @@ |
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
|||
// source: msg.proto
|
|||
|
|||
package pb |
|||
|
|||
import ( |
|||
fmt "fmt" |
|||
proto "github.com/golang/protobuf/proto" |
|||
math "math" |
|||
) |
|||
|
|||
// Reference imports to suppress errors if they are not otherwise used.
|
|||
var _ = proto.Marshal |
|||
var _ = fmt.Errorf |
|||
var _ = math.Inf |
|||
|
|||
// This is a compile-time assertion to ensure that this generated file
|
|||
// is compatible with the proto package it is being compiled against.
|
|||
// A compilation error at this line likely means your copy of the
|
|||
// proto package needs to be updated.
|
|||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
|||
|
|||
//同步客户端玩家ID
|
|||
type SyncPid struct { |
|||
Pid int32 `protobuf:"varint,1,opt,name=Pid,proto3" json:"Pid,omitempty"` |
|||
XXX_NoUnkeyedLiteral struct{} `json:"-"` |
|||
XXX_unrecognized []byte `json:"-"` |
|||
XXX_sizecache int32 `json:"-"` |
|||
} |
|||
|
|||
func (m *SyncPid) Reset() { *m = SyncPid{} } |
|||
func (m *SyncPid) String() string { return proto.CompactTextString(m) } |
|||
func (*SyncPid) ProtoMessage() {} |
|||
func (*SyncPid) Descriptor() ([]byte, []int) { |
|||
return fileDescriptor_c06e4cca6c2cc899, []int{0} |
|||
} |
|||
|
|||
func (m *SyncPid) XXX_Unmarshal(b []byte) error { |
|||
return xxx_messageInfo_SyncPid.Unmarshal(m, b) |
|||
} |
|||
func (m *SyncPid) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { |
|||
return xxx_messageInfo_SyncPid.Marshal(b, m, deterministic) |
|||
} |
|||
func (m *SyncPid) XXX_Merge(src proto.Message) { |
|||
xxx_messageInfo_SyncPid.Merge(m, src) |
|||
} |
|||
func (m *SyncPid) XXX_Size() int { |
|||
return xxx_messageInfo_SyncPid.Size(m) |
|||
} |
|||
func (m *SyncPid) XXX_DiscardUnknown() { |
|||
xxx_messageInfo_SyncPid.DiscardUnknown(m) |
|||
} |
|||
|
|||
var xxx_messageInfo_SyncPid proto.InternalMessageInfo |
|||
|
|||
func (m *SyncPid) GetPid() int32 { |
|||
if m != nil { |
|||
return m.Pid |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
//玩家位置
|
|||
type Position struct { |
|||
X float32 `protobuf:"fixed32,1,opt,name=X,proto3" json:"X,omitempty"` |
|||
Y float32 `protobuf:"fixed32,2,opt,name=Y,proto3" json:"Y,omitempty"` |
|||
Z float32 `protobuf:"fixed32,3,opt,name=Z,proto3" json:"Z,omitempty"` |
|||
V float32 `protobuf:"fixed32,4,opt,name=V,proto3" json:"V,omitempty"` |
|||
XXX_NoUnkeyedLiteral struct{} `json:"-"` |
|||
XXX_unrecognized []byte `json:"-"` |
|||
XXX_sizecache int32 `json:"-"` |
|||
} |
|||
|
|||
func (m *Position) Reset() { *m = Position{} } |
|||
func (m *Position) String() string { return proto.CompactTextString(m) } |
|||
func (*Position) ProtoMessage() {} |
|||
func (*Position) Descriptor() ([]byte, []int) { |
|||
return fileDescriptor_c06e4cca6c2cc899, []int{1} |
|||
} |
|||
|
|||
func (m *Position) XXX_Unmarshal(b []byte) error { |
|||
return xxx_messageInfo_Position.Unmarshal(m, b) |
|||
} |
|||
func (m *Position) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { |
|||
return xxx_messageInfo_Position.Marshal(b, m, deterministic) |
|||
} |
|||
func (m *Position) XXX_Merge(src proto.Message) { |
|||
xxx_messageInfo_Position.Merge(m, src) |
|||
} |
|||
func (m *Position) XXX_Size() int { |
|||
return xxx_messageInfo_Position.Size(m) |
|||
} |
|||
func (m *Position) XXX_DiscardUnknown() { |
|||
xxx_messageInfo_Position.DiscardUnknown(m) |
|||
} |
|||
|
|||
var xxx_messageInfo_Position proto.InternalMessageInfo |
|||
|
|||
func (m *Position) GetX() float32 { |
|||
if m != nil { |
|||
return m.X |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
func (m *Position) GetY() float32 { |
|||
if m != nil { |
|||
return m.Y |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
func (m *Position) GetZ() float32 { |
|||
if m != nil { |
|||
return m.Z |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
func (m *Position) GetV() float32 { |
|||
if m != nil { |
|||
return m.V |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
//玩家广播数据
|
|||
type BroadCast struct { |
|||
Pid int32 `protobuf:"varint,1,opt,name=Pid,proto3" json:"Pid,omitempty"` |
|||
Tp int32 `protobuf:"varint,2,opt,name=Tp,proto3" json:"Tp,omitempty"` |
|||
// Types that are valid to be assigned to Data:
|
|||
// *BroadCast_Content
|
|||
// *BroadCast_P
|
|||
// *BroadCast_ActionData
|
|||
Data isBroadCast_Data `protobuf_oneof:"Data"` |
|||
XXX_NoUnkeyedLiteral struct{} `json:"-"` |
|||
XXX_unrecognized []byte `json:"-"` |
|||
XXX_sizecache int32 `json:"-"` |
|||
} |
|||
|
|||
func (m *BroadCast) Reset() { *m = BroadCast{} } |
|||
func (m *BroadCast) String() string { return proto.CompactTextString(m) } |
|||
func (*BroadCast) ProtoMessage() {} |
|||
func (*BroadCast) Descriptor() ([]byte, []int) { |
|||
return fileDescriptor_c06e4cca6c2cc899, []int{2} |
|||
} |
|||
|
|||
func (m *BroadCast) XXX_Unmarshal(b []byte) error { |
|||
return xxx_messageInfo_BroadCast.Unmarshal(m, b) |
|||
} |
|||
func (m *BroadCast) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { |
|||
return xxx_messageInfo_BroadCast.Marshal(b, m, deterministic) |
|||
} |
|||
func (m *BroadCast) XXX_Merge(src proto.Message) { |
|||
xxx_messageInfo_BroadCast.Merge(m, src) |
|||
} |
|||
func (m *BroadCast) XXX_Size() int { |
|||
return xxx_messageInfo_BroadCast.Size(m) |
|||
} |
|||
func (m *BroadCast) XXX_DiscardUnknown() { |
|||
xxx_messageInfo_BroadCast.DiscardUnknown(m) |
|||
} |
|||
|
|||
var xxx_messageInfo_BroadCast proto.InternalMessageInfo |
|||
|
|||
func (m *BroadCast) GetPid() int32 { |
|||
if m != nil { |
|||
return m.Pid |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
func (m *BroadCast) GetTp() int32 { |
|||
if m != nil { |
|||
return m.Tp |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
type isBroadCast_Data interface { |
|||
isBroadCast_Data() |
|||
} |
|||
|
|||
type BroadCast_Content struct { |
|||
Content string `protobuf:"bytes,3,opt,name=Content,proto3,oneof"` |
|||
} |
|||
|
|||
type BroadCast_P struct { |
|||
P *Position `protobuf:"bytes,4,opt,name=P,proto3,oneof"` |
|||
} |
|||
|
|||
type BroadCast_ActionData struct { |
|||
ActionData int32 `protobuf:"varint,5,opt,name=ActionData,proto3,oneof"` |
|||
} |
|||
|
|||
func (*BroadCast_Content) isBroadCast_Data() {} |
|||
|
|||
func (*BroadCast_P) isBroadCast_Data() {} |
|||
|
|||
func (*BroadCast_ActionData) isBroadCast_Data() {} |
|||
|
|||
func (m *BroadCast) GetData() isBroadCast_Data { |
|||
if m != nil { |
|||
return m.Data |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func (m *BroadCast) GetContent() string { |
|||
if x, ok := m.GetData().(*BroadCast_Content); ok { |
|||
return x.Content |
|||
} |
|||
return "" |
|||
} |
|||
|
|||
func (m *BroadCast) GetP() *Position { |
|||
if x, ok := m.GetData().(*BroadCast_P); ok { |
|||
return x.P |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
func (m *BroadCast) GetActionData() int32 { |
|||
if x, ok := m.GetData().(*BroadCast_ActionData); ok { |
|||
return x.ActionData |
|||
} |
|||
return 0 |
|||
} |
|||
|
|||
// XXX_OneofWrappers is for the internal use of the proto package.
|
|||
func (*BroadCast) XXX_OneofWrappers() []interface{} { |
|||
return []interface{}{ |
|||
(*BroadCast_Content)(nil), |
|||
(*BroadCast_P)(nil), |
|||
(*BroadCast_ActionData)(nil), |
|||
} |
|||
} |
|||
|
|||
func init() { |
|||
proto.RegisterType((*SyncPid)(nil), "pb.SyncPid") |
|||
proto.RegisterType((*Position)(nil), "pb.Position") |
|||
proto.RegisterType((*BroadCast)(nil), "pb.BroadCast") |
|||
} |
|||
|
|||
func init() { proto.RegisterFile("msg.proto", fileDescriptor_c06e4cca6c2cc899) } |
|||
|
|||
var fileDescriptor_c06e4cca6c2cc899 = []byte{ |
|||
// 218 bytes of a gzipped FileDescriptorProto
|
|||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xb1, 0x4e, 0x86, 0x30, |
|||
0x10, 0xc7, 0x69, 0xbf, 0xaf, 0x1f, 0x72, 0x12, 0x63, 0x3a, 0x35, 0xea, 0x40, 0x98, 0x9c, 0x18, |
|||
0xf4, 0x09, 0x04, 0x07, 0xc6, 0xa6, 0x12, 0x02, 0x6c, 0x2d, 0x18, 0xd3, 0xc1, 0xb6, 0x81, 0x2e, |
|||
0x3e, 0x86, 0xaf, 0xe1, 0x53, 0x9a, 0x96, 0x90, 0x98, 0x38, 0xdd, 0xfd, 0xfe, 0x97, 0xfc, 0xee, |
|||
0x72, 0x90, 0x7d, 0x6e, 0x1f, 0x95, 0x5b, 0xad, 0xb7, 0x14, 0x3b, 0x55, 0xde, 0x43, 0xfa, 0xf6, |
|||
0x65, 0x66, 0xae, 0x17, 0x7a, 0x0b, 0x27, 0xae, 0x17, 0x86, 0x0a, 0xf4, 0x48, 0x44, 0x68, 0xcb, |
|||
0x1a, 0xae, 0xb8, 0xdd, 0xb4, 0xd7, 0xd6, 0xd0, 0x1c, 0xd0, 0x10, 0x67, 0x58, 0xa0, 0x21, 0xd0, |
|||
0xc8, 0xf0, 0x4e, 0x63, 0xa0, 0x89, 0x9d, 0x76, 0x9a, 0x02, 0xf5, 0xec, 0xbc, 0x53, 0x5f, 0x7e, |
|||
0x23, 0xc8, 0xea, 0xd5, 0xca, 0xa5, 0x91, 0x9b, 0xff, 0xbf, 0x83, 0xde, 0x00, 0xee, 0x5c, 0x54, |
|||
0x11, 0x81, 0x3b, 0x47, 0xef, 0x20, 0x6d, 0xac, 0xf1, 0xef, 0xc6, 0x47, 0x63, 0xd6, 0x26, 0xe2, |
|||
0x08, 0xe8, 0x03, 0x20, 0x1e, 0xcd, 0xd7, 0x4f, 0x79, 0xe5, 0x54, 0x75, 0x1c, 0xd7, 0x26, 0x02, |
|||
0x71, 0x5a, 0x00, 0xbc, 0xcc, 0x01, 0x5f, 0xa5, 0x97, 0x8c, 0x04, 0x63, 0x9b, 0x88, 0x3f, 0x59, |
|||
0x7d, 0x81, 0x73, 0xac, 0xe4, 0x07, 0x63, 0xae, 0xd4, 0x25, 0xbe, 0xe1, 0xf9, 0x37, 0x00, 0x00, |
|||
0xff, 0xff, 0x3b, 0x27, 0xe7, 0x05, 0x13, 0x01, 0x00, 0x00, |
|||
} |
@ -0,0 +1,27 @@ |
|||
syntax="proto3"; //Proto协议 |
|||
package pb; //当前包名 |
|||
option csharp_namespace="Pb"; //给C#提供的选项 |
|||
|
|||
//同步客户端玩家ID |
|||
message SyncPid{ |
|||
int32 Pid=1; |
|||
} |
|||
|
|||
//玩家位置 |
|||
message Position{ |
|||
float X=1; |
|||
float Y=2; |
|||
float Z=3; |
|||
float V=4; |
|||
} |
|||
|
|||
//玩家广播数据 |
|||
message BroadCast{ |
|||
int32 Pid=1; |
|||
int32 Tp=2; |
|||
oneof Data { |
|||
string Content=3; |
|||
Position P=4; |
|||
int32 ActionData=5; |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"fmt" |
|||
"zinx/ziface" |
|||
"zinx/zinx_app_demo/mmo_game/core" |
|||
"zinx/znet" |
|||
) |
|||
|
|||
//当客户端建立连接的时候的hook函数
|
|||
func OnConnecionAdd(conn ziface.IConnection) { |
|||
temp_pid := 1 |
|||
//创建一个玩家
|
|||
player := core.NewPlayer(conn, int32(temp_pid)) |
|||
//同步当前的PlayerID给客户端, 走MsgID:1 消息
|
|||
player.SyncPid() |
|||
//同步当前玩家的初始化坐标信息给客户端,走MsgID:200消息
|
|||
player.BroadCastStartPosition() |
|||
|
|||
fmt.Println("=====> Player pidId = ", temp_pid, " arrived ====") |
|||
} |
|||
|
|||
func main() { |
|||
//创建服务器句柄
|
|||
s := znet.NewServer() |
|||
|
|||
//注册客户端连接建立和丢失函数
|
|||
s.SetOnConnStart(OnConnecionAdd) |
|||
|
|||
//启动服务
|
|||
s.Serve() |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue