day131:2RenMJ:2RenMJ遊戲簡介&部署MJ項目到本地

目錄

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:[email protected]/twoperson_majdb?charset=utf8
SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]/twoperson_majdb?charset=utf8"


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

# testA mysql   mysql://er_mj:[email protected]/er_mjdb?charset=utf8
# SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]/twoperson_majdb?charset=utf8"
#  增加本地redis 地址 For example: redis://[:password]@localhost:6379/0
# REDIS_URL = 'redis://:[email protected]:8379/1'
REDIS_URL = 'redis://:[email protected]: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