目录

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:8889 和 127.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

day131:2RenMJ:2RenMJ游戏简介&部署MJ项目到本地的更多相关文章

  1. 【Eclipse】eclipse部署web项目至本地的tomcat但在webapps中找不到

    clipse部署web项目至本地的tomcat但在webapps中找不到 1.发现问题 在我的 eclipse 中有个Dynamic Web Project(动态web项目),在本地的 tomcat ...

  2. eclipse部署web项目至本地的tomcat但在webapps中找不到

    一.发现问题 在eclipse中新建Dynamic Web Project,配置好本地的tomcat并写好代码后选择Run on Server,但运行后发现在tomcat的安装目录下的webapps并 ...

  3. eclipse部署web项目至本地的tomcat但在webapps中找不到问题

    一.发现问题 在eclipse中新建Dynamic Web Project,配置好本地的tomcat并写好代码后选择Run on Server,但运行后发现在tomcat的安装目录下的webapps并 ...

  4. jenkins maven svn 部署web项目到本地Tomcat

    查了N多网页,折腾了几个小时,终于部署成功,部署的过程比较坎坷,遇到各种问题,记录一下,不管大家是否会遇到的同样的问题,希望有所帮助: 常规操作: 1.下载jenkins,必须要做的一步,http:/ ...

  5. jenkins部署java项目在本地(三)

    (1)新建maven构建的java项目 pom.xml的配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...

  6. jenkins部署web项目到webogic

    注: Docker容器里安装的jenkins,Docker容易里安装的weblogic 在jenkins里面直接将打包好的 war 包通过 Publish over SSH插件 放入 weblogic ...

  7. nginx 练习(将游戏图片部署到NFS+LNMP架构简介+uwsgi架构简介)

    nginx(将游戏图片部署到NFS) 练习 一.首先去NFS这里创建挂载点 1.先在NFS的opt下面创建文件夹存放图片 [root@linux opt]# mkdir /opt/img 2.然后将此 ...

  8. SpringBoot启动方式讲解和部署war项目到tomcat9

    1.SpringBoot启动方式讲解和部署war项目到tomcat9简介:SpringBoot常见启动方式讲解和部署war项目Tomcat 1.ide启动 2.jar包方式启动 maven插件: &l ...

  9. 【SpringBoot】单元测试进阶实战、自定义异常处理、t部署war项目到tomcat9和启动原理讲解

    ========================4.Springboot2.0单元测试进阶实战和自定义异常处理 ============================== 1.@SpringBoot ...

随机推荐

  1. Python进阶——什么是描述符?

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 在 Python 开发中,你可能听说过「描述符」这个概念,由于我们很少直接使用它,所以大部分开发人员 ...

  2. CCNP之OSPF实验报告

    OSPF实验报告 一.实验要求 1.R4为ISP,其上只能配置IP地址:R4与其它所有直连设备间使用公有IP2.R3--R5/6/7为MGRE环境,R3为中心站点3.整个OSPF环境IP地址为172. ...

  3. python3全局函数解析

    python的全局函数: import builtins dir(builtins) [ 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray ...

  4. Mac 上使用 Shell 脚本 + adb shell 实现简单的 Android 模拟点击自动化测试

    需求 在 A 界面,点击跳转到 B 界面(该界面会执行一些业务),再点击返回键出现 Dialog 弹窗,点击确认退出按钮,返回 A 界面.不断循环. 思路 一开始想到的就是按键精灵,下了 mac 版使 ...

  5. Android硬件访问服务中的HAL-查看打印的信息

    JNI  向上提供本地函数,向下加载HAL文件并调用HAL的函数 HAL 负责访问驱动程序执行硬件操作. external\chromium_org\third_party\hwcplus\src\h ...

  6. Qt学习笔记-设计简易的截图工具软件

    现在利用Qt来实现一个截图软件. 首先,设计一个界面出来. 最上面有一个label用来显示图片. 然后使用QPixmap中的静态函数grabWindow来获取图片.这里需要一个winID.可以使用 Q ...

  7. esp-01与esp-01s的区别 ESP8288-01S与ESP8288-01的区别

    ESP8266系列Wi-Fi模块一共有01-14十多款模块, ESP8266-01简称ESP-01, ESP8266-01S简称ESP-01S 至于他们的区别请看下图:左边的是ESP8266-01S, ...

  8. Linux之远程登录和文件传输

    一---导读 在实际开发过程中,程序员和Linux系统是远程的,并且可能有多个程序员一同在同一个linux系统上工作,那么这个时候就需要我们远程登录linux系统 二---软件介绍 xshell 和 ...

  9. TurtleBot3使用课程-第一节b(北京智能佳)

    目录 1.模拟运行TurtleBot 2 1.1 ROS安装和设置2 1.1.1 turtlebot3 在Gazebo中模拟 3 1.1.1.1用于Gazebo的ROS包装 3 1.1.1.2 tur ...

  10. Prometheus集群介绍-1

    Prometheus监控介绍 公司做教育的,要迁移上云,所以需要我这边从零开始调研加后期维护Prometheus:近期看过二本方面的prometheus书籍,一本是深入浅出一般是实战方向的:官方文档主 ...