day131:2RenMJ:2RenMJ游戏简介&部署MJ项目到本地
目录
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项目到本地的更多相关文章
- 【Eclipse】eclipse部署web项目至本地的tomcat但在webapps中找不到
clipse部署web项目至本地的tomcat但在webapps中找不到 1.发现问题 在我的 eclipse 中有个Dynamic Web Project(动态web项目),在本地的 tomcat ...
- eclipse部署web项目至本地的tomcat但在webapps中找不到
一.发现问题 在eclipse中新建Dynamic Web Project,配置好本地的tomcat并写好代码后选择Run on Server,但运行后发现在tomcat的安装目录下的webapps并 ...
- eclipse部署web项目至本地的tomcat但在webapps中找不到问题
一.发现问题 在eclipse中新建Dynamic Web Project,配置好本地的tomcat并写好代码后选择Run on Server,但运行后发现在tomcat的安装目录下的webapps并 ...
- jenkins maven svn 部署web项目到本地Tomcat
查了N多网页,折腾了几个小时,终于部署成功,部署的过程比较坎坷,遇到各种问题,记录一下,不管大家是否会遇到的同样的问题,希望有所帮助: 常规操作: 1.下载jenkins,必须要做的一步,http:/ ...
- jenkins部署java项目在本地(三)
(1)新建maven构建的java项目 pom.xml的配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...
- jenkins部署web项目到webogic
注: Docker容器里安装的jenkins,Docker容易里安装的weblogic 在jenkins里面直接将打包好的 war 包通过 Publish over SSH插件 放入 weblogic ...
- nginx 练习(将游戏图片部署到NFS+LNMP架构简介+uwsgi架构简介)
nginx(将游戏图片部署到NFS) 练习 一.首先去NFS这里创建挂载点 1.先在NFS的opt下面创建文件夹存放图片 [root@linux opt]# mkdir /opt/img 2.然后将此 ...
- SpringBoot启动方式讲解和部署war项目到tomcat9
1.SpringBoot启动方式讲解和部署war项目到tomcat9简介:SpringBoot常见启动方式讲解和部署war项目Tomcat 1.ide启动 2.jar包方式启动 maven插件: &l ...
- 【SpringBoot】单元测试进阶实战、自定义异常处理、t部署war项目到tomcat9和启动原理讲解
========================4.Springboot2.0单元测试进阶实战和自定义异常处理 ============================== 1.@SpringBoot ...
随机推荐
- (四)、vim的缓冲区、标签、窗口操作
1.缓冲区的基本操作 a.文件与缓冲区的区别 vim file1 打开一个文件时,其实是从磁盘中读取文件到内存中,文件的内容会被加载到缓冲区中, 这个缓冲区在一个窗口上显示,所以他是一个已激活的缓 ...
- Java数组的三种打印方式
1.数组的输出的三种方式 一维数组: 定义一个数组 int[] array = {1,2,3,4,5}; (1)传统的for循环方式 for(int i=0;i<array.length;i++ ...
- ES标签搜索并解决评分排序问题
一.概述 需求: 最近在做一个新闻项目,有这样一个需求,如下: 用户根据视频内容手动创建标签,标签个数不限 在视频详情页提供根据标签推荐视频功能,即按本视频的标签进行搜索,标签匹配多的排在前面,匹配少 ...
- 异步技巧之CompletableFuture
摘自--https://juejin.im/post/5b4622df5188251ac9766f47 异步技巧之CompletableFuture 1.Future接口 1.1 什么是Future? ...
- swap是干嘛的?
本文截取自:http://hbasefly.com/2017/05/24/hbase-linux/ swap是干嘛的? 在Linux下,SWAP的作用类似Windows系统下的"虚拟内存&q ...
- AjaxControlToolKit CalendarExtender(日历扩展控件)的使用方法
设置CalendarExtender的TargetControlID为需要显示日期的TextBox的ID,textBox控件的readOnly属性设置为 false ,这样就可以点击textbox控件 ...
- Hive 中的四种排序详解,再也不会混淆用法了
Hive 中的四种排序 排序操作是一个比较常见的操作,尤其是在数据分析的时候,我们往往需要对数据进行排序,hive 中和排序相关的有四个关键字,今天我们就看一下,它们都是什么作用. 数据准备 下面我们 ...
- ZooKeeper集群“脑裂”
ZooKeeper 集群节点为什么要部署成奇数ZooKeeper 容错指的是:当宕掉几个ZooKeeper节点服务器之后,剩下的个数必须大于宕掉的个数,也就是剩下的节点服务数必须大于n/2,这样Zoo ...
- Windows server 安装远程桌面及破解120天时间限制授权
一.问题描述 Windows Server系列服务器默认远程桌面连接数是2个用户(本文适用于所有Windows Server系列服务器),如果多余两个用户进行远程桌面连接时,系统就会提示超过连接数,可 ...
- kafka 异步双活方案 mirror maker2 深度解析
mirror maker2背景 通常情况下,我们都是使用一套kafka集群处理业务.但有些情况需要使用另一套kafka集群来进行数据同步和备份.在kafka早先版本的时候,kafka针对这种场景就有推 ...