day131:2RenMJ:2RenMJ遊戲簡介&部署MJ專案到本地

Poke發表於2021-01-27

目錄

1.遊戲簡介

  1.如何做出一款麻將遊戲?

  2.麻將執行介面

  3.麻將專案所用技術快速概覽

  4.web開發 / 遊戲開發 / APP開發 比較

  5.firefly遊戲框架介紹

2.部署麻將專案到本地

  1.專案整體目錄結構

  2.客戶端本地安裝部署

  3.遊戲服務端本地安裝部署

  4.web服務端本地安裝部署+執行

  5.遊戲服務端執行

  6.客戶端執行

1.遊戲簡介

1.如何做出一款麻將遊戲?

⾃2000年Python第⼀個穩定的2.7版本釋出以來,Python"簡單、明確、優雅"設計哲學的根本出發點就決定了Python這⻔語⾔的程式設計易⽤性和⼯作⾼效性。特別是近幾年來,在遊戲⾏業中傳統的程式設計語⾔c++開發及維護成本極⾼的劣勢逐漸凸顯,同樣的業務需求實現,可能傳統程式設計語⾔c++程式猿需要1周,⽽⼀個普通的Python程式猿可能三天就能完成,同時後續隱藏的bug還會少很多。於是在休閒、棋牌遊戲領域,Python這⻔⾼效的指令碼語⾔開始逐漸流⾏起來

作為棋牌遊戲中複雜度最⾼的遊戲,麻將遊戲開發遊戲邏輯複雜多變,據不完全統計,全國地⽅麻將的種類已經超過上千種,不同的地⽅麻將差異巨⼤,⽐如有的沒有"萬",有的沒有"餅",有的存在"亮倒"等操作,胡牌的型別更是千變萬化,⼀些胡牌型別甚⾄有些匪夷所思(如綠⼀⾊:即⼿牌全是綠⾊的牌,⼀種東北地⽅麻將的⼤胡胡法)。

2.麻將執行介面

1.大廳介面

 

2.牌局介面

3.系統提示

4.系統郵箱

3.麻將專案所用技術快速概覽

python版本: 2.7

game server( 遊戲服務端 )

目錄:echecs/

依賴:firefly遊戲引擎 / 基於twisted框架研發而來的

web service( web端 )

目錄:echecs_web_services/

依賴:tornado5.1+rpc介面

client(客戶端):

目錄:tpmj_new/

依賴:白鷺引擎 Egret 5.0

4.web開發 / 遊戲開發 / APP開發 比較

在wiki上對Server的分類:

  Typical servers are database servers, fifile servers, mail servers, print servers, web servers, game

servers, and application servers.

其他⼏種Server我們都⽐較清楚了,跟unix差不多同時誕⽣。接下來我們主要針對web servers,game servers, and application servers進⾏簡單介紹。

1.web server

典型例⼦是淘寶。

  特點:所有流程均由客戶端發起,客戶端發個請求,服務端返回個響應。⽽且,根據客戶端訪問的服

務不同,客戶端可以向不同的具體服務端節點發起請求。

2.game server

典型例⼦是王者榮耀。

  特點:有⼀個⾁眼能感覺到的連線握⼿的過程,建⽴連線後,流程有可能是服務端發起(⽐如給你

展示周邊玩家),也有可能是客戶端發起(⽐如你移動了⼀下)。

  同時,如果你⼿邊有抓包⼯具,可以看到,如果你選中了某個玩家,在該玩家的頭像框消失之前,

⼀直是同⼀個場景伺服器在跟你通訊。

3.app server

典型例⼦是QQ。

  特點:介於Web Server和Game Server之間,看著像⼀個web伺服器,但是⼜有遊戲伺服器的特

點。

4.三者的共同點??

都是為客戶端提供多種服務

都需要連線會話的概念

服務端的每臺物理機服務多個客戶端

都具有分散式結構

5.三者的不同點??

a. 會話的存在形式:

這⼀點是web服務端與遊戲服務端最本質的區別。

  web服務端的客戶端與客戶端之間互動⾮常有限,因此,服務端可以將會話儲存在外部儲存服務,⽐如⼀些快取中介軟體、⽂件系統中介軟體,然後等再⽤到的時候再拿出來就可以了。

  ⽽遊戲服務端的客戶端與客戶端之間互動⾮常頻繁,⽐如,同場景的其他玩家會不停做不規律移動,戰⽃時⼀個技能就會對複數個玩家造成影響。

  這時如果將會話狀態儲存在外部,會造成頻繁的狀態存取,嚴重影響伺服器吞吐量。因此對於遊戲服務端來說,會話通常儲存在程式內。

b. 互動頻率與資料流向:

web服務端的頻率低,⽽且資料的流動是由客戶端驅動的,流向通常是客戶端請求了,服務端才返回。

⽽遊戲服務端的頻率⾼,資料的流動⼀部分由客戶端驅動,⼀部分由服務端驅動。流向除了服務端對客戶端請求的響應,還有服務端的主動推送。

c. 通訊協議基礎:

web通訊的基礎在應⽤層是http/https/websocket協議。

遊戲通常會實現私有的序列化協議,可以簡單理解為應⽤層定義協議包結構平鋪成位元組流或者是串⾏序列化位元組流。如果要⽀持⼀定程度的協議版本相容,會⽤⼆進位制json或者protobuf來實現協議序列化,但是通訊協議本身是沒有「基礎」可⾔的,純私有化協議,不具普適性,也沒有必要定義成⼀種專⻔的協議。

5.firefly遊戲框架介紹

Firefly是免費、開源、穩定、快速擴充套件、能 “熱更新”的分散式遊戲伺服器端框架,採⽤Python編寫,基於Twisted框架開發。

在麻將遊戲中,應⽤firefly框架後的遊戲總體架構圖如下:

1.client: 客戶端,即玩家⽤戶,遊戲中客戶端和服務端之間的連線是⻓連線,客戶端和服務端的proxy節

點進⾏連線;

2.proxy:服務端的代理節點,其主要任務是負責訊息打包和解包,加解密,然後將合法的訊息轉發向後

端節點。proxy節點地址對公⽹開發(客戶端通過域名和端⼝連線);

3.gate: 服務端的訊息分發節點(⻔戶節點)。該節點根據訊息請求id將不同的訊息分發到不同的⼦節點中

進⾏處理,如⻓沙麻將分發到⻓沙麻將的遊戲節點處理,⼴東麻將分發到⼴東麻將節點處理,該型別節

點⼀般不對公⽹開放;

遊戲節點,各型別的遊戲,如csmj(⻓沙麻將),gdmj(⼴東麻將), xzmj(⾎戰)等。此類節點為遊戲主邏輯

節點。

4.master:firefly框架中的管理節點,它負責管理所有的proxy,gate,遊戲節點等,主要管理節點的加⼊

和退出,不負責具體業務邏輯;

5.DB模組:遊戲中所有涉及到資料庫的部分,各節點皆有可能操作。

2.部署麻將專案到本地

1.專案整體目錄結構

專案目錄結構:
Codes/
├── echecs/                # 遊戲引擎服務端
├── echecs_web_services/   # 遊戲web服務端
├── mj_client_new/         # 遊戲web客戶端[壓縮,已打包]
└── tpmj_new/              # 遊戲web客戶端[原生,未打包]

2.客戶端本地安裝部署

1.修改客戶端的main.min.js修改引數

檔案內搜尋:127.0.0.1:8889127.0.0.1:10000 替換成自己伺服器的地址,注意:如果是本地部署,則不需要修改。

2.安裝的輕量級web開發伺服器live-server,需要通過npm進行安裝。如果是部署到線上,則需要更換成nginx即可。

npm install -g live-server

3.執行專案  

切換終端的工作目錄到mj_client_new/,執行命令:live-server

live-server

3.遊戲服務端本地安裝部署

1.基於python2.7建立虛擬環境

mkvirtualenv mahjong -p python2

2.在虛擬環境中安裝麻將專案的第三方依賴模組

pip install -r requirements.txt -i https://pypi.douban.com/simple

注意: 安裝過程中,Mysql-Python模組在暗轉過程中會因為Mysql-Client報錯,解決辦法如下:

sudo apt-get install python-dev
sudo apt-get install libmysqld-dev
sudo apt-get install libmysqlclient-dev
pip install MySQL-python

3.通過PyCharm開啟專案Codes並設定虛擬環境

注意:Codes事實上並非真正的專案根目錄,而是多個專案根目錄的父級目錄。所以我們需要在pycharm的終端下面執行多個專案。

4.web服務端本地安裝部署+執行

1.給redis設定密碼

web服務端中設定了快取伺服器為redis,並且配置項中redis的密碼為必填項。所以我們必須設定redis的密碼。

sudo vim /etc/redis/redis.conf
# 把500行左右的配置項requirepass的註釋開啟,填寫自己的密碼,例如我這裡是happy
# requirepass xxxxxxxx

# 儲存並重啟redis
service redis restart

將註釋開啟-->修改密碼

進入redis-cli確認密碼新增成功

2.在mysql中建立資料庫

web服務端中整合了SQLAlchemy ORM框架,所以我們必須在mysql中先建立資料庫 twoperson_majdb

create database twoperson_majdb charset=utf8;

3.web服務端根目錄: echecs_web_services的配置檔案修改

web專案配置,Codes/echecs_web_services/config.ini,程式碼:

DEBUG=1
REDIS_HOST="127.0.0.1"
REDIS_PORT=6379
REDIS_DB=10
REDIS_PWD="libolun"

# testA mysql   mysql://root:123456@192.168.1.73/twoperson_majdb?charset=utf8
SQLALCHEMY_DATABASE_URI = "mysql://root:123456@127.0.0.1/twoperson_majdb?charset=utf8"


#  增加本地redis 地址 For example: redis://[:password]@localhost:6379/0
# REDIS_URL = 'redis://:123456abc@192.168.1.73:25001/1'

# testA mysql   mysql://er_mj:123456@119.23.66.138/er_mjdb?charset=utf8
# SQLALCHEMY_DATABASE_URI = "mysql://root:123456@39.108.10.161/twoperson_majdb?charset=utf8"
#  增加本地redis 地址 For example: redis://[:password]@localhost:6379/0
# REDIS_URL = 'redis://:happyeveryday@oldboy.iespoir.com:8379/1'
REDIS_URL = 'redis://:libolun@127.0.0.1:6379/1'

4.web服務端和遊戲服務端進行通訊的配置

Codes/echecs_web_services/app/config/game_config.json

{
  "game_server_config":{
    "host": "127.0.0.1",
    "port": "10000"
  },
  "income_support" : 4000,
  "get_income_support_interval": 300
}

5.執行web服務端(web-server)

接下來,在pycharm終端下執行web專案

cd echecs_web_services/
python manage.py
# 注意:因為我們已經把tornado整合了SQLAlchemy了,所以專案執行的時候,讓它直接連線資料庫並建立了資料庫表了。

執行完這步之後,你就會發現資料庫中就多了很多張表了

執行了專案以後,需要新增遊戲相關配置的引數資訊,在資料庫中執行SQL語句,注意:新增資料成功以後要重新啟動web端。否則會重現快取問題。

INSERT INTO `iw_room_cfg` (`created_date`, `modified_date`, `id`, `name`, `special_rule`, `min_enter_gold`, `min_play_gold`, `max_enter_gold`, `base_bet`, `service_charge`, `draw_card_time`, `min_hu_fan`, `max_hu_fan`, `recommend_pay_num`, `room_type`, `desc`) 
VALUES 
(NULL,NULL,1,'初級場','{}',1000,999,0,60,90,12,6,0,6,0,NULL),
(NULL,NULL,2,'中級場','{\"pass_hu_double\":1}',10000,4000,0,150,220,12,10,0,6,1,NULL),
(NULL,NULL,3,'高階場','{\"pass_hu_double\":1}',40000,20000,0,500,750,12,12,0,6,2,NULL);

5.遊戲服務端執行

1.遊戲服務端的相關配置

Codes/echecs/config.json,程式碼:

{
    "master":{
         "rootport":10010,
         "webport":10009,
         "log":"logs/masterlog.log"
    },
    "servers":{
          "proxy_1":{
                "port": 10000,
                "webport": 10001,
                "name": "proxy_1",
                "app": "proxy.start_up",
                "remoteport":[
                  {"rootport": 11001, "rootname": "gate_1", "is_available":1},
                  {"rootport": 11003, "rootname": "gate_2"}
                ]
          },
          "gate_1": {
                "rootport":11001,
                "webport":11002,
                "name":"gate_1",
                "app":"gate.start_up"
          },
          "gate_2": {
                "rootport":11003,
                "webport":11004,
                "name":"gate_2",
                "app":"gate.start_up"
          },
          "room_1":{
                "rootport": 12001,
                "webport":12002,
                "name":"room_1",
                "app":"game.start_up",
                "remoteport":[
                  {"rootport": 11001, "rootname": "gate_1"},
                  {"rootport": 11003, "rootname": "gate_2"}
                ]
          },
          "room_2":{
                "rootport": 12003,
                "webport":12004,
                "name":"room_2",
                "app":"game.start_up",
                "remoteport":[
                  {"rootport": 11001, "rootname": "gate_1"},
                  {"rootport": 11003, "rootname": "gate_2"}
                ]
          }
    }
}

2.啟動遊戲服務端

1.啟動遊戲服務端主程式(master)

cd echecs
python start_mastersingle.py

2.啟動遊戲服務端代理伺服器(proxy)

cd echecs
python start_proxy_1.py

3.啟動遊戲服務端閘道器伺服器(gate)

cd echecs
python start_gate_1.py 

4.啟動遊戲服務端遊戲伺服器(room)

cd echecs
python start_room_1.py

6.客戶端執行

前面我們已經安裝了live-server在系統終端下啟動,現在關閉,換成在pycharm下面啟動即可。

cd mj_client_new/
live-server

 

相關文章