LollipopGo框架-鬥獸棋遊戲開發基本核心模組
原文地址:
http://www.golang.ltd/forum.php?mod=viewthread&tid=7180&extra=
gitbub地址:
https://github.com/Golangltd/LollipopGo |
package main
import (
"LollipopGo/LollipopGo/log"
"Proto"
"Proto/Proto2"
"flag"
"fmt"
_ "fmt"
"net/rpc"
"net/rpc/jsonrpc"
"strings"
"LollipopGo/LollipopGo/util"
_ "LollipopGo/ReadCSV"
_ "LollipopGo/LollipopGo/player"
"code.google.com/p/go.net/websocket"
)
var addrDSQ = flag.String("addrDSQ", "127.0.0.1:8888", "http service address") // 連結gateway
var ConnDSQ *websocket.Conn // 儲存使用者的連結資訊,資料會在主動匹配成功後進行連結
var ConnDSQRPC rpc.Client // 連結DB server
var DSQAllMap map[string]RoomPlayerDSQ // 遊戲邏輯儲存
var DSQ_qi = []int{ // 1-8 A ;9-16 B
Proto2.Elephant, Proto2.Lion, Proto2.Tiger, Proto2.Leopard, Proto2.Wolf, Proto2.Dog, Proto2.Cat, Proto2.Mouse,
Proto2.Mouse + Proto2.Elephant, Proto2.Mouse + Proto2.Lion, Proto2.Mouse + Proto2.Tiger, Proto2.Mouse + Proto2.Leopard,
Proto2.Mouse + Proto2.Wolf, Proto2.Mouse + Proto2.Dog, Proto2.Mouse + Proto2.Cat, 2 * Proto2.Mouse}
// 鬥獸棋遊戲結構
// 每個房間都存在一個
type RoomPlayerDSQ struct {
OpenIDA string
OpenIDB string
InitData [4][4]int // 鬥獸棋的棋盤的資料
WhoChuPai string // 當前誰出牌
GoAround int // 回合,如果每人出10次都沒有吃子,系統推送平局;第七個回合提示資料 第10局平局
}
/*
-----------------------------------------
| |
| [0,0]01 [1,0]02 [2,0]03 [3,0]04 |
| |
| |
| [0,1]05 [1,1]06 [2,1]07 [3,1]08 |
| |
| |
| [0,2]09 [1,2]10 [2,2]11 [3,2]12 |
| |
| |
| [0,3]13 [1,3]14 [2,3]15 [3,3]16 |
| |
-----------------------------------------
*/
// 初始化操作
func init() {
// if !initDSQGateWayNet() {
// fmt.Println("連結 gateway server 失敗!")
// return
// }
// fmt.Println("連結 gateway server 成功!")
// // 初始化資料
// initDSQNetRPC()
return
}
// 初始化RPC
func initDSQNetRPC() {
client, err := jsonrpc.Dial("tcp", service)
if err != nil {
log.Debug("dial error:", err)
}
ConnDSQRPC = client
}
// 初始化閘道器
func initDSQGateWayNet() bool {
fmt.Println("使用者客戶端客戶端模擬!")
log.Debug("使用者客戶端客戶端模擬!")
url := "ws://" + *addrDSQ + "/GolangLtd"
conn, err := websocket.Dial(url, "", "test://golang/")
if err != nil {
fmt.Println("err:", err.Error())
return false
}
ConnDSQ = conn
// 協程支援 --接受執行緒操作 全球協議操作
go GameServerReceiveDSQ(Conn)
// 傳送連結的協議 ---》
initConnDSQ(Conn)
return true
}
// 連結到閘道器
func initConnDSQ(conn *websocket.Conn) {
// 協議修改
data := &Proto2.G2GW_ConnServer{
Protocol: Proto.G_GameGlobal_Proto, // 遊戲主要協議
Protocol2: Proto2.G2GW_ConnServerProto2,
ServerID: util.MD5_LollipopGO("8895" + "DSQ server"),
}
fmt.Println(data)
// 2 傳送資料到伺服器
PlayerSendToServer(conn, data)
return
}
// 處理資料
func GameServerReceiveDSQ(ws *websocket.Conn) {
for {
var content string
err := websocket.Message.Receive(ws, &content)
if err != nil {
fmt.Println(err.Error())
continue
}
// decode
fmt.Println(strings.Trim("", """))
fmt.Println(content)
content = strings.Replace(content, """, "", -1)
contentstr, errr := base64Decode([]byte(content))
if errr != nil {
fmt.Println(errr)
continue
}
// 解析資料 --
fmt.Println("返回資料:", string(contentstr))
go SyncMeassgeFunDSQ(string(contentstr))
}
}
// 連結分發 處理
func SyncMeassgeFunDSQ(content string) {
var r Requestbody
r.req = content
if ProtocolData, err := r.Json2map(); err == nil {
// 處理我們的函式
HandleCltProtocolDSQ(ProtocolData["Protocol"], ProtocolData["Protocol2"], ProtocolData)
} else {
log.Debug("解析失敗:", err.Error())
}
}
// 主協議處理
func HandleCltProtocolDSQ(protocol interface{}, protocol2 interface{}, ProtocolData map[string]interface{}) {
defer func() { // 必須要先宣告defer,否則不能捕獲到panic異常
if err := recover(); err != nil {
strerr := fmt.Sprintf("%s", err)
//發訊息給客戶端
ErrorST := Proto2.G_Error_All{
Protocol: Proto.G_Error_Proto, // 主協議
Protocol2: Proto2.G_Error_All_Proto, // 子協議
ErrCode: "80006",
ErrMsg: "親,您發的資料的格式不對!" + strerr,
}
// 傳送給玩家資料
fmt.Println("Global server的主協議!!!", ErrorST)
}
}()
// 協議處理
switch protocol {
case float64(Proto.G_GameGlobal_Proto):
{ // Global Server 主要協議處理
fmt.Println("Global server 主協議!!!")
HandleCltProtocol2DSQ(protocol2, ProtocolData)
}
default:
panic("主協議:不存在!!!")
}
return
}
// 子協議的處理
func HandleCltProtocol2DSQ(protocol2 interface{}, ProtocolData map[string]interface{}) {
switch protocol2 {
case float64(Proto2.GW2G_ConnServerProto2):
{ // 閘道器返回資料
fmt.Println("gateway server 返回給global server 資料資訊!!!")
}
case float64(Proto2.G2GW_PlayerEntryHallProto2):
{ // 閘道器請求獲取大廳資料
fmt.Println("玩家請求獲取大廳數:預設獲獎列表、跑馬燈等")
// G2GW_PlayerEntryHallProto2Fucn(Conn, ProtocolData)
}
default:
panic("子協議:不存在!!!")
}
return
}
//------------------------------------------------------------------------------
// 初始化牌型
func InitDSQ(data1 []int) [4][4]int {
data, erdata, j, k := data1, [4][4]int{}, 0, 0
for i := 0; i < Proto2.Mouse*2; i++ {
icount := util.RandInterval_LollipopGo(0, int32(len(data))-1)
fmt.Println("隨機數:", icount)
if len(data) == 1 {
erdata[3][3] = data[0]
} else {
//------------------------------------------------------------------
if int(icount) < len(data) {
erdata[j][k] = data[icount]
k++
if k%4 == 0 {
j++
k = 0
}
data = append(data[:icount], data[icount+1:]...)
} else {
erdata[j][k] = data[icount]
k++
if k%4 == 0 {
j++
k = 0
}
data = data[:icount-1]
}
//------------------------------------------------------------------
}
fmt.Println("生成的資料", erdata)
}
return erdata
}
// 判斷棋子大小
// 玩家操作移動,操作協議
func CheckIsEat(fangx int, qizi int, qipan [4][4]int) (bool, int, [4][4]int) {
if qizi > 16 || qizi < 1 {
log.Debug("玩家傳送棋子資料不對!")
return false, Proto2.DATANOEXIT, qipan
}
// 1 尋找 玩家的棋子在棋牌的位置/或者這個棋子是否存在
bret, Posx, posy := CheckChessIsExit(qizi, qipan)
if bret {
bret, iret, data := CheckArea(fangx, Posx, posy, qipan)
return bret, iret, data
} else {
log.Debug("玩家傳送棋子不存在!疑似外掛。")
return false, Proto2.DATAERROR, qipan
}
return true, 0, qipan
}
// 檢查棋盤中是不是存在
func CheckChessIsExit(qizi int, qipan [4][4]int) (bool, int, int) {
for i := 0; i < 4; i++ {
for j := 0; j < 4; j++ {
if qipan[i][j] == qizi {
return true, i, j
}
}
}
return false, 0, 0
}
// 邊界判斷
func CheckArea(fangx, iposx, iposy int, qipan [4][4]int) (bool, int, [4][4]int) {
if fangx == Proto2.UP {
if iposy == 0 {
return false, Proto2.MOVEFAIL, qipan // 無法移動
}
data_yidong := qipan[iposx][iposy-1]
data := qipan[iposx][iposy]
// 判斷是空地不
if data_yidong == 0 {
data_ret := UpdateChessData(Proto2.MOVE, iposx, iposy-1, iposx, iposy, qipan)
return true, Proto2.MOVESUCC, data_ret // 移動成功
}
// 對比棋子大小
if data < 9 {
if data_yidong < 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy-1, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
} else {
if data_yidong > 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy-1, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy-1, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
}
} else if fangx == Proto2.DOWN {
if iposy == 3 {
return false, Proto2.MOVEFAIL, qipan // 無法移動
}
data_yidong := qipan[iposx][iposy+1]
data := qipan[iposx][iposy]
// 判斷是空地不
if data_yidong == 0 {
data_ret := UpdateChessData(Proto2.MOVE, iposx, iposy+1, iposx, iposy, qipan)
return true, Proto2.MOVESUCC, data_ret // 移動成功
}
// 對比棋子大小
if data < 9 {
if data_yidong < 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy+1, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
} else {
if data_yidong > 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx, iposy+1, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx, iposy+1, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
}
} else if fangx == Proto2.LEFT {
if iposx == 0 {
return false, Proto2.MOVEFAIL, qipan // 無法移動
}
data_yidong := qipan[iposx-1][iposy]
data := qipan[iposx][iposy]
// 判斷是空地不
if data_yidong == 0 {
data_ret := UpdateChessData(Proto2.MOVE, iposx-1, iposy, iposx, iposy, qipan)
return true, Proto2.MOVESUCC, data_ret // 移動成功
}
// 對比棋子大小
if data < 9 {
if data_yidong < 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx-1, iposy, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
} else {
if data_yidong > 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx-1, iposy, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx-1, iposy, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
}
} else if fangx == Proto2.RIGHT {
if iposx == 3 {
return false, Proto2.MOVEFAIL, qipan // 無法移動
}
data_yidong := qipan[iposx+1][iposy]
data := qipan[iposx][iposy]
// 判斷是空地不
if data_yidong == 0 {
data_ret := UpdateChessData(Proto2.MOVE, iposx+1, iposy, iposx, iposy, qipan)
return true, Proto2.MOVESUCC, data_ret // 移動成功
}
// 對比棋子大小
if data < 9 {
if data_yidong < 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx+1, iposy, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
} else {
if data_yidong > 9 {
return false, Proto2.TEAMMATE, qipan // 自己人
} else {
if data_yidong > data {
data_ret := UpdateChessData(Proto2.DISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
return true, Proto2.DISAPPEAR, data_ret // 自殘
} else if data_yidong == data {
data_ret := UpdateChessData(Proto2.ALLDISAPPEAR, iposx+1, iposy, iposx, iposy, qipan)
return true, Proto2.ALLDISAPPEAR, data_ret // 同歸於盡
} else if data_yidong < data {
data_ret := UpdateChessData(Proto2.BEAT, iposx+1, iposy, iposx, iposy, qipan)
return true, Proto2.BEAT, data_ret // 吃掉對方
}
}
}
}
return false, Proto2.ITYPEINIY, qipan // 不存在的操作
}
// 更新棋盤資料
// 注:移動成功後,原來位置如何變化
// 目標的位置如何變化
// fangxPos fangyPos表示變化的位置
// iPosx iPosy 原來棋子的位置
func UpdateChessData(iType, fangxPos, fangyPos, iPosx, iPosy int, qipan [4][4]int) [4][4]int {
// 儲存副本資料
data := qipan
// 原來棋子的資料
yd_data := data[iPosx][iPosy]
// 更新棋盤 資料
if iType == Proto2.MOVE { // 更新空地 ,1 更新原來棋盤的位置為0, 目標的位置為現在資料
data[iPosx][iPosy] = 0
data[fangxPos][fangyPos] = yd_data
} else if iType == Proto2.DISAPPEAR { // 自殘 ,1 更新原來棋盤的位置為0,目標的位置資料不變
data[iPosx][iPosy] = 0
} else if iType == Proto2.ALLDISAPPEAR { // 同歸於盡 ,1 更新原來棋盤的位置為0,目標的位置資料為0
data[iPosx][iPosy] = 0
data[fangxPos][fangyPos] = 0
} else if iType == Proto2.BEAT { // 吃掉對方 ,1 更新原來位置為0,目標位置為現在資料
data[iPosx][iPosy] = 0
data[fangxPos][fangyPos] = yd_data
}
return data
}
LollipopGo遊戲伺服器地址:
https://github.com/Golangltd/LollipopGo
社群視訊課程課件GIT地址:
https://github.com/Golangltd/codeclass
Golang語言社群論壇 :
www.Golang.Ltd
相關文章
- 微信小遊戲開發(8)-模組化遊戲開發
- Android遊戲開發示例——彈幕+戰棋Android遊戲開發
- 【Unity3D開發小遊戲】《戰棋小遊戲》Unity開發教程Unity3D遊戲
- 安卓開發 五子棋遊戲安卓遊戲
- Android模組開發框架 LiveData+ViewModelAndroid框架LiveDataView
- 使用 Python 和 Pygame 模組構建一個遊戲框架PythonGAM遊戲框架
- 飛行巨獸空鬥遊戲《世紀:灰燼紀元》創作思路和開發歷程分享遊戲
- 鬥羅世界NFT遊戲系統技術開發丨鬥羅世界鏈遊開發模式詳情遊戲模式
- 基於 Blazor 開發五子棋⚫⚪小遊戲Blazor遊戲
- 跨平臺渲染引擎之路:框架與核心模組框架
- 格鬥遊戲修羅場:鬼人和他的遊戲開發哲學遊戲開發
- LollipopGo遊戲伺服器架構--NetGateWay.go說明Go遊戲伺服器架構Gateway
- Linux核心模組Linux
- DKHadoop大資料開發框架的構成模組Hadoop大資料框架
- 格鬥遊戲能否翻紅獲手遊玩家芳心?還得從普及基本概念開始遊戲
- 遊戲開發者的思考:什麼是遊戲設計的核心?遊戲開發遊戲設計
- EBCMS核心後臺開發框架框架
- python–模組之基本Python
- node核心模組-vm
- toa 核心模組分析
- spring-boot 整合mybatis-plus 組成後臺開發基本框架SpringbootMyBatis框架
- 文字格鬥遊戲遊戲
- 使用typescript開發angular模組(編寫模組)TypeScriptAngular
- 遊戲是如何有序執行的? 聊聊遊戲規則的基本框架遊戲框架
- 遊戲情感化設計【社交模組】遊戲
- 模組化開發(二)
- 前端模組化開發前端
- Linux核心模組編譯Linux編譯
- 【核心模組】node.jsNode.js
- 核心模組建立檔案
- Linux核心模組學習Linux
- 核心補丁熱更新ceph核心模組
- 《英雄聯盟》開發商 Riot Games 證實正在開發一款格鬥遊戲GAM遊戲
- 《鬼鬥》Steam: “純粹”的格鬥遊戲遊戲
- 《遊戲王:決鬥連結》今日公測!開啟真正的決鬥!遊戲
- 開發者談合格遊戲文件的基本構成要素遊戲
- 五子棋遊戲(Java)遊戲Java
- [Lua遊戲AI開發指南] 筆記零 - 框架搭建遊戲AI筆記框架