ad208三国

 找回密码
 加入
搜索
热搜: 活动 交友 discuz
查看: 488|回复: 4

BrowserQuest多人在线RPG游戏

[复制链接]
发表于 2022-10-7 13:27:58 | 显示全部楼层 |阅读模式

pc2g,电脑好游戏




Browserquest 图文全攻略
https://www.3dmgame.com/gl/2277280.html


以下文字转载自https://blog.csdn.net/lijian_nhy/article/details/84494775

安装部署过程:

百度获得BrowserQuest的下载地址,把BrowserQuest源码下载到本地。

官方网站: http://browserquest.mozilla.org/ 演示https://browserquest.co/

代码下载地址: https://github.com/mozilla/BrowserQuest

1、安装 node.js ,下载地址为 http://nodejs.org/

并通过npm install [MODULE_NAME] 安装如下组件,如npm install underscore 或npm install -d underscore

使用npm install -d 可以自动配置package.json,并安装所有需要依赖的包

underscore
log
bison
websocket
websocket-server
sanitizer
memcache
2、下载BrowserQuest ,地址: https://github.com/mozilla/BrowserQuest

3、 准备一个Webserver,如tomcat7

4、准备一个支持HTML5的浏览器,如FireFox, Chrome等,建议使用FireFox,加上FireBug以便方便对js代码进行跟踪测试

BrowserQuest的目录结构

解压完成的目录结构为
bin
client
server
shared
tools
目前来说,只和client和server有关系。
其中server需要使用node.js框架启动,client使用tomcat7启动,其实指和用户浏览器相关的部分。

Node启动Server
进入server目录,将 config_local.json-dist 改名为 config_local.json
需要把 node_modules copy到 browserquest里,如下图

进入browserquest目录,使用node server/js/main.js命令,如下图所示

Tomcat7启动Client
进入client/config目录,将 config_build.json-dist 改名为 config_build.json ,并且将config_build.json中的 host修改为127.0.0.1

[html] view plaincopy
{
"host": "127.0.0.1",
"port": 8000
}

修改tomcat的配置,增加一个webcontext,注意docbase是到browserquest目录而不是client目录


[html] view plaincopy
<Context docBase="D:/workspaces/HTML5/BrowserQuest-master/" >

</Context>

启动Tomcat

浏览器访问

访问地址为http://localhost:8080/client

即可进入测试。

测试在node的服务端能看到很多输出

[html] view plaincopy
[Thu Nov 22 2012 12:29:48 GMT+0800 (中国标准时间)] DEBUG Received: 0,ddd,21,60
[Thu Nov 22 2012 12:29:48 GMT+0800 (中国标准时间)] INFO ddd has joined world1
[Thu Nov 22 2012 12:29:48 GMT+0800 (中国标准时间)] DEBUG Received: 20,927,929,10
20,1021,1022,1120,1121,1122,1220,1221,1222,1320,1321,1322,11920,11921,12120,1212
1,810235,815222,818209
[Thu Nov 22 2012 12:29:48 GMT+0800 (中国标准时间)] DEBUG Pushed 21 new spawns to
510
[Thu Nov 22 2012 12:29:50 GMT+0800 (中国标准时间)] DEBUG Received: 4,29,225
[Thu Nov 22 2012 12:29:50 GMT+0800 (中国标准时间)] DEBUG ddd is moving to (29, 2
25).
[Thu Nov 22 2012 12:29:50 GMT+0800 (中国标准时间)] DEBUG Received: 26,4
[Thu Nov 22 2012 12:29:54 GMT+0800 (中国标准时间)] DEBUG Received: 21
[Thu Nov 22 2012 12:29:54 GMT+0800 (中国标准时间)] DEBUG group diff:
[Thu Nov 22 2012 12:29:54 GMT+0800 (中国标准时间)] DEBUG Received: 20,926,928,18
20,1821,12220,867220
[Thu Nov 22 2012 12:29:54 GMT+0800 (中国标准时间)] DEBUG Pushed 6 new spawns to
510


无法连接到服务端

最常见的问题是点Play后,页面停留在connecting上,请检查一下两点配置:

1、node.js 服务端是否启动正常,可通过http://127.0.0.1:800/status 如果返回 类似[0,0,0,0] 。如果无法返回检查是否有相关的模块,或8000端口是否被占用。
2、tomcat的web路径要配置到client的上一级,client必须作为子目录。


安装过程中,可以看到,用到了Node.js和服务器端tomcat(当然你可以选择其它中间件,只是支持html访问即可。)浏览器必须支持HTML5,建议使用火狐和谷歌浏览器。
 楼主| 发表于 2022-10-7 13:36:58 | 显示全部楼层
二次开发 BrowserQuest 中,对于地图修改的部分记录
转载自https://blog.csdn.net/lijian_nhy ... 1001.2014.3001.5502

在这里要感谢的是网友:神灯,land007

步骤:
1 通过地图编辑器tiled 修改 BrowserQuest-master\tools\maps\tmx 文件夹下的map.tmx

2 通过 地图编辑器 导出 map.json

3 通过命令nodejs脚本把map.json生成系统能够适别的json数据。
命令工具脚本:map.bat,exportmap.js 和 file.js (注:网友”神灯“提供)

1) map.bat:

@color 3F
@echo.
@echo 操作完成自动退出程序!
@echo.
node exportmap.js map.json direct
@echo.
@echo 操作完成按任意键退出程序!
@echo.
@pause >nul
exit

2) exportmap.js

#!/usr/bin/env node

var util = require('util'),
Log = require('log'),
path = require("path"),
fs = require("fs"),
file = require("../../shared/js/file"),
processMap = require('./processmap'),
log = new Log(Log.DEBUG);

// 此处用了nodejs的process进程处理,读取参数,即 map.bat 中 node exportmap.js map.json direct
// node 为参数0 process.argv[0] exportmap.js 为参数1 map.json 为参数3 依次类推...
var source = process.argv[2],
mode = process.argv[3],
destination = process.argv[4];

// source 代表的是map.json

if(!mode){
mode = "direct";
}

if(!source || (mode!="direct" && mode!="root" && mode!="both" && mode!="client" && mode!="server") || (mode!="root" && mode!="direct" && !destination)) {
util.puts("Usage : ./exportmap.js tiled_json_file [mode] [destination]");
util.puts("Optional parameters : mode & destination. Values:");
util.puts(" - \"direct\" (default) → updates current server and map files (WARNING: SHOULD ONLY BE CALLED FROM BrowserQuest/tools/maps !!!);");
util.puts(" - \"client destination_file\" → will generate destination_file.js and destination_file.json for client side map;");
util.puts(" - \"server destination_file.json\" → will generate destination_file.json for server side map;");
util.puts(" - \"both destination_directory\" → will generate world_client.js, world_client.json and world_server.json in directory.");
process.exit(0);
}

function main() {
getTiledJSONmap(source, callback_function);
}

function callback_function(json) {
switch(mode){
case "client":
processClient(json, destination);
break;

case "server":
processServer(json, destination);
break;

case "direct":
processClient(json, "../../client/maps/world_client");
processServer(json, "../../server/maps/world_server.json");
break;

case "both":
var directory=destination.replace(/\/+$/,'');//strip last path slashes
processClient(json, directory+"/world_client");
processServer(json, directory+"/world_server.json");
break;

case "root":
processClient(json, "client/maps/world_client");
processServer(json, "server/maps/world_server.json");
break;

default:
util.puts("Unrecognized mode, how on earth did you manage that ?");
}
}

function processClient(json, dest){
var jsonMap = JSON.stringify(processMap(json, {mode:"client"})); // Save the processed map object as JSON data
// map in a .json file for ajax loading
fs.writeFile(dest+".json", jsonMap, function(err, file) {
if(err){
log.error(JSON.stringify(err));
}
else{
log.info("Finished processing map file: "+ dest + ".json was saved.");
}
});

// map in a .js file for web worker loading
jsonMap = "var mapData = "+jsonMap;
fs.writeFile(dest+".js", jsonMap, function(err, file) {
if(err){
log.error(JSON.stringify(err));
}
else{
log.info("Finished processing map file: "+ dest + ".js was saved.");
}
});
}

function processServer(json, dest){
var jsonMap = JSON.stringify(processMap(json, {mode:"server"})); // Save the processed map object as JSON data
fs.writeFile(dest, jsonMap, function(err, file) {
if(err){
log.error(JSON.stringify(err));
}
else{
log.info("Finished processing map file: "+ dest + " was saved.");
}
});
}

function getTiledJSONmap(filename, callback) {
var self = this;
// 此处调用的file.js中的exists函数
file.exists(filename, function(exists) {
if(!exists) {
log.error(filename + " doesn't exist.")
return;
}

fs.readFile(filename, function(err, file) {
callback(JSON.parse(file.toString()));
});
});
}

main();


3) file.js

var exists, existsSync;
(function () {
var semver = require('semver');
var module = (semver.satisfies(process.version, '>=0.7.1') ? require('fs') : require('path'));

exists = module.exists;
existsSync = module.existsSync;
})();

if (!(typeof exports === 'undefined')) {
module.exports.exists = exists;
module.exports.existsSync = existsSync;
}

// 其中semver为node的一个模块,可以通过 npm install semver 安装模块 (前提是先弄清楚,安装node)


4 修改processmap.js
在官方提供的源码直接运行脚本,并不能完成功能,因为之前看过官方wiki,知道地图这一块有一个
https://github.com/browserquest/ ... /maps/processmap.js
把这个processmap.js 替换源码 BrowserQuest-master\tools\maps 下的processmap.js即可。

最后运行map.bat批处理文件,即可在对应目录生成json数据。。
然后你重启node server/js/main.js 重启服务器tomcat或apache,访问,可以看到,此时的地图为你修改后的地图。地图编辑算是成功了。
 楼主| 发表于 2022-10-7 13:38:57 | 显示全部楼层
关于 BrowserQuest人物地图移动的原理分析
以下文字转载自https://blog.csdn.net/lijian_nhy ... 1001.2014.3001.5502

人物在游戏中的截图:




红色部位为切换地图的部位。

下面是tiled地图编辑工具打开的原始图:




红色部位为上图中游戏中的截图区域,当游戏人物走到矩形中时,通过判断人物行走的方位,即可切换到tiled地图中zones地图的下一区域,这样就达到了人物移动地图切换的目的。


游戏中主要代码:client/js/updater.js

/**
* 更新地图,即更新精灵显示区域。
*/
updateZoning: function() {
var g = this.game,
c = g.camera,
z = g.currentZoning, /** 当前站立的区域 **/
s = 3,
ts = 16,
speed = 500;

if(z && z.inProgress === false) {
// 获得当前游戏人物要走的方向
var orientation = this.game.zoningOrientation,
startValue = endValue = offset = 0,
updateFunc = null,
endFunc = null;

if(orientation === Types.Orientations.LEFT || orientation === Types.Orientations.RIGHT) { /** 精灵向左向右 **/
offset = (c.gridW - 2) * ts;
startValue = (orientation === Types.Orientations.LEFT) ? c.x - ts : c.x + ts;
endValue = (orientation === Types.Orientations.LEFT) ? c.x - offset : c.x + offset;
updateFunc = function(x) {
c.setPosition(x, c.y);
g.initAnimatedTiles();
g.renderer.renderStaticCanvases();
}
endFunc = function() {
c.setPosition(z.endValue, c.y);
g.endZoning();
}
} else if(orientation === Types.Orientations.UP || orientation === Types.Orientations.DOWN) { /** 精灵向上向下 **/
offset = (c.gridH - 2) * ts;
startValue = (orientation === Types.Orientations.UP) ? c.y - ts : c.y + ts;
endValue = (orientation === Types.Orientations.UP) ? c.y - offset : c.y + offset;
updateFunc = function(y) {
c.setPosition(c.x, y);
g.initAnimatedTiles();
g.renderer.renderStaticCanvases();
}
endFunc = function() {
c.setPosition(c.x, z.endValue);
g.endZoning();
}
}

z.start(this.game.currentTime, updateFunc, endFunc, startValue, endValue, speed);
}
}
 楼主| 发表于 2022-10-7 13:50:51 | 显示全部楼层
以下文字转载自
https://blog.csdn.net/weixin_39805998/article/details/115822466

单进程模式用户间数据容易共享

browserquest本身就设计成单进程模式,单进程模式用户间数据容易共享,不用频繁的进程间通讯,开发简单。

改成gateway网关模式利弊

如果要改成多进程gateway网关模式,代码改动量会很大,要求开发者对于browserquest运行机制及代码结构非常熟悉。

即使开发出多进程模式,由于进程间要频繁通讯,整体性能不一定比单进程好。

拿browserquest来说

拿browserquest来说,虽然是单进程模式,但是由于游戏内没有阻塞IO,单进程估计也能支持上千人。

browserquest本身地图并不大,如果是上千人在线估计已经是满屏都是人了,支持再高的在线人数意义不大,人数继续增加的话应该去考虑增加一个browserquest服务,采用多房间(多服)的方式平摊压力。每个服单独的实例,互不影响,可以几乎无限的水平扩展。

所以就browserquest来说,单进程模式+多实例分服的方式会比较好。

非要多进程写个browserquest

假设非要突破browserquest单进程限制,可以考虑为每个地图创建一个进程,用户切换地图时,关闭原来socket链接,并重新链接连到对应的地图服务器进程。由于不同地图的人之间不会有太多的消息通讯,所以不需要太多进程间通讯,这样每个地图都可以承载上千人,那么多个地图就可以承载更多人。

这样一组browserquest进程应该比原来单进程承载更多的在线用户,如果用户量继续增加,还是老套路,开新的游戏服务器房间。

再优化

再优化可能就是把游戏拆分成更多的服务,登陆服务、接入服务、地图服务、AI服务等,然后针对每个服务做优化,多进程多服务器支持等。具体如何做与服务类型有关,得具体问题具体分析了。

我本身不是做游戏的,抛砖引玉,欢迎大家讨论

Archiver|手机版|小黑屋|ad208三国

GMT+8, 2024-3-29 02:26

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表