Colyseus:轻量级多人游戏免费开源解决方案

news2024/9/24 19:15:32

点击上方“青年码农”关注

回复“源码”可获取各种资料

Colyseus 是一个独特的多人游戏框架,被用于许多 H5 小游戏和手机游戏中,使用容易,且选项众多,可满足开发者多样化的需求。如果你在制作多人联网游戏时遇到过各种扩展性需求和细节问题造成的项目阻碍,那么推荐你使用这个免费的开源解决方案。

这个框架也是最近接触,自己在摸索过程中遇到很多坑,因此记录下。文章基于 Express + TS 演示及说明。

在使用 Colyseus 框架之前,我们要满足 Colyseus 的运行环境。

  1. 下载并安装 Node.js V14.0 或更高版本(使用 nvm 或者 n 来管理 Node 版本)

  2. 下载并安装 Git SCM

  3. 下载并安装 Visual Studio Code (或者您喜欢的其他编辑器)

安装

安装过程和其他 npm 库一样,用 npm、yarn 或者其他都可以,但是要注意,npm 库中有 colyseus 和 colyseus.js,这两个有区别,一个是给服务端用的,一个是给客户端用的。

  • colyseus:Node 环境,也就是服务端

  • colyseus.js:前端环境,也就是客户端

npm i colyseus
# or
yarn add colyseus

配置

在 app.ts 文件中引入 colyseus ,

var express = require("express");
import { Server } from "colyseus";
import { WebSocketTransport } from "@colyseus/ws-transport";
import { createServer } from "http";
const port = 3300;

var app = express();
const server = createServer(app);
const gameServer = new Server({
  transport: new WebSocketTransport({
    server
  })
});

gameServer.listen(port);

启动项目,如果没有报错,colyseus 服务就启动成功了,地址就是 IP+3300,客户端创建 client 就可以链接到这个服务了。

var client = new Colyseus.Client("ws://127.0.0.1:3300");

通过上面我们只是简单的有了服务可以使用,游戏,那应该有房间和状态

房间和状态

先说说我对房间的理解,Colyseus 内置房间有两个,大厅房间和中继房间,大厅房间应该是类似我们进入游戏时的大厅,所有人都在一起,然后再找自己喜欢类型的房间,中继房间,我猜测类似吃鸡游戏中,我们选择开始游戏,在出生岛等待游戏开始的房间,以上是个人理解,如有不对,请指正。

大厅房间和中继房间已经帮我们初始了一些状态,但是这些可能不满足我们游戏的需求,因此,我们就需要定义我们自己的房间,使用 Room 类定义

import http from "http";
import { Room, Client } from "colyseus";

export class MyRoom extends Room {
    // 房间初始化时
    onCreate (options: any) { }

    // 在 WebSocket 握手完成前, 客户端基于其提供的 options 进行验证
    onAuth (client: Client, options: any, request: http.IncomingMessage) { }

    // 当客户端成功加入房间时
    onJoin (client: Client, options: any, auth: any) { }

    // 当客户端离开房间时
    onLeave (client: Client, consented: boolean) { }

    // 析构函数, 当房间里没有客户端时被调用. (参考 `autoDispose`)
    onDispose () { }
}

有了房间,肯定要有一些初始状态,使用 Schema 初始化状态

// MyState.ts
import { Client } from "colyseus";
import { Schema, MapSchema, type } from "@colyseus/schema";

// 一个抽象玩家对象, 表达其在3D世界的位置
export class Player extends Schema {
  @type("number")
  x: number = 0;

  @type("number")
  y: number = 0;

  @type("number")
  z: number = 0;
}

export class MyState extends Schema {
  @type({ map: Player })
  players = new MapSchema<Player>();

  @type("string")
  direction: string = "up";
  /**
   * 添加新用户的方法
   *
   * @param {Client} client
   * @memberof PlayerState
   */
  addPlayer(client: Client) {
    let player = new Player(0, 0, 1);
    this.players.set(client.sessionId, player);
  }

  /**
   * 删除一个用户的方法
   *
   * @param {Client} client
   * @memberof PlayerState
   */
  removePlayer(client: Client) {
    this.players.delete(client.sessionId);
  }

  /**
   * 移动用户的方法
   *
   * @param {Client} client
   * @param {number} [x=0]
   * @param {number} [y=0]
   * @memberof PlayerState
   */
  movePlayer(
    client: Client,
    x: number = 0,
    y: number = 0,
    z: number = 0,
    direction: string = "up"
  ) {
    let player = this.players.get(client.sessionId);
    console.log(player);
    if (player != undefined) {
      if (direction == "down" || direction == "right") {
        (<Player>player).x += x;
        (<Player>player).y += y;
        (<Player>player).z += z;
      } else {
        (<Player>player).x -= x;
        (<Player>player).y -= y;
        (<Player>player).z -= z;
        if ((<Player>player).x <= 0) {
          (<Player>player).x = 0;
        }
        if ((<Player>player).y <= 0) {
          (<Player>player).y = 0;
        }
        if ((<Player>player).z <= 0) {
          (<Player>player).z = 0;
        }
      }
    } else {
      // 当前用户不存在
      console.log("client sessionId not exist!");
    }
  }
}

状态有了,稍微修改下房间,在房间初始化时把状态加上

import { MyState } from "./myState";

onCreate(options: any) {
    this.setState(new MyState());
}

房间和状态都定义好了,通过 define 公开房间(修改文件 app.ts)

gameServer.define("game", MyRoom);

再重新启动项目,就可以使用新的房间了

通过@colyseus/monitor 实时监察服务器生成的房间列表

@colyseus/monitor 是一个方便易用的工具,可以实时监察服务器生成的房间列表.

安装模块:

npm install --save @colyseus/monitor

在项目中引入:

import { monitor } from "@colyseus/monitor";

app.use("/colyseus", monitor());

1864586251408741142f187ddd98eff6.png

接收消息和广播

怎么接收客户端发送的消息和怎么发送广播?通过 onMessage 接收消息,通过 broadcast 发送广播,在 onCreate 定义

onCreate(options: any) {
    this.setState(new MyState());
    // 活动消息
    this.onMessage("action", (client, message) => {
      console.log(client.sessionId, "sent 'action' message: ", message);
    });

    // 消息保存
    this.onMessage("save", (client, data) => {
      // 广播
      this.broadcast("action-taken", "an action has been taken!");
    });
  }

客户端通过 send 触发。

this.room.send("action", { direction: "left" });
// 触发广播
this.room.send("save", { direction: "left" });

fc513dc24d070444dbbedf4a3efb26df.png

一个用户加入

8ed17d6bc0d1601f7f305fb53542072e.png

两个用户加入,并且一个用户位置发生了改变

dd0778c79000ede8f0af3f60a3ef8691.png

监测有人进入房间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/130301.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据卷(Data Volumes)

目录 1.Docker宿主机和容器之间文件拷贝 利用MySQL镜像安装MySQL服务 从容器中拷贝文件到宿主机 从宿主机拷贝文件到容器 2.数据卷 3.数据卷容器 1.Docker宿主机和容器之间文件拷贝 利用MySQL镜像安装MySQL服务 docker run -p 3307:3306 --name mysql2 -di -v /home/…

Qt中用thrift验证flume

一.flume简介 flume是Cloudera提供的一个高可用的&#xff0c;高可靠的&#xff0c;分布式的海量日志采集、聚合和传输的系统。 在flume中分为了3个组件&#xff0c;分别为source&#xff0c;channel和sink。 Source是负责接收数据到Flume Agent的组件。Source组件可以处理各种…

在阿里做了7年软件测试原来是........

你了解软件测试岗吗&#xff1f; 很多人做测试3&#xff0c;5年&#xff0c;甚至年限多长。 但并不懂软件测试岗所要求的技术和能力&#xff0c;只是拘于当前的工作环境和培训班的宣传。 在一个微信里中看到如下的对话&#xff1a; 某人说&#xff0c;工作中开始做自动化了。…

8253练习题(8253端口地址怎么求?怎么求初值?怎么看出工作方式)

目录 一&#xff1a;简单&#xff08;题目把计数初值和工作方式都给你了&#xff09; 二&#xff1a;给了你输入时间周期和初值&#xff0c;你会不会求输出&#xff1f; 三&#xff1a;简单 四&#xff1a;初值计数方式都不给&#xff0c;初值还是给的时间和频率混合 五&a…

前端_swapCache方法 发布文章

swapCache方法 swapCache方法用来手工执行本地缓存的更新&#xff0c;它只能在applicationCache对象的updateReady事件被触发时调用&#xff0c;updateReady事件只有服务器上的manifest文件被更新&#xff0c;并且把manifest文件中所要求的资源文件下载到本地后触发。顾名思义…

[极客大挑战 2019]Secret File(BUUCTF)

前言: 这篇文章还是是为了帮助一些 像我这样的菜鸟 找到简单的题解 题目描述 解题工具: fiddler或burpsuite抓包 解题过程: 又是要找秘密&#xff0c; 先检查一下源代码 发现了一个链接与背景颜色融合了 点进去看看 找到了SECRET但肯定没这么简单 点击SECRET页面发生…

15. 我是怎么用一个特殊 Cookie ,限制住别人的爬虫的

爬虫训练场&#xff0c;第15篇博客。 博客详细清单&#xff0c;参考 https://pachong.vip/blog 本次案例&#xff0c;用定值 Cookie 实现反爬 文章目录Cookie 生成Python Flask 框架生成 CookieFlask make_response 加载模板Flask 判断指定 cookie 是否存在补充知识点Cookie 生…

【AcWing每日一题】4818. 奶牛大学

Farmer John 计划为奶牛们新开办一所大学&#xff01; 有 N 头奶牛可能会入学。 每头奶牛最多愿意支付 ci 的学费。 Farmer John 可以设定所有奶牛入学需要支付的学费。 如果这笔学费大于一头奶牛愿意支付的最高金额&#xff0c;那么这头奶牛就不会入学。 Farmer John 想赚…

C++ New和Delete

目录 前言 New Delete 前言 new是c中用于动态申请空间的运算符&#xff0c;malloc也是用于动态申请空间的&#xff0c;但malloc是函数。 New new是用来开辟一段新空间的&#xff0c;和一般申明不同的是&#xff0c;new开辟的新空间是在堆上&#xff0c;而申明的变量是在栈上…

【自学Java】Java注释

Java注释 Java注释教程 用于注解说明解释程序的文字就是注释&#xff0c;注释可以提高代码的阅读性。同时&#xff0c;注释也是一个程序员必须要具有的良好的编程习惯。我们首先应该将自己的思想通过注释先整理出来&#xff0c;再用代码实现。 在 Java 语言 中&#xff0c;一…

(二)Qt多线程实现海康工业相机图像实时采集

系列文章目录 提示&#xff1a;这里是该系列文章的所有文章的目录 第一章&#xff1a; &#xff08;一&#xff09;QtOpenCV调用海康工业相机SDK示例开发 第二章&#xff1a; &#xff08;二&#xff09;Qt多线程实现海康工业相机图像实时采集 文章目录系列文章目录前言一、项目…

C语言中指针常见问题集

1. 我想声明一个指针并为它分配一些空间,但却不行。这些代码有什么问题&#xff1f; char *p; *p malloc(10);答&#xff1a;你所声明的指针是p, 而不是*p, 当你操作指针本身时你只需要使用指针的名字即可:cp malloc(10);当你操作指针指向的内存时,你才需要使用*作为间接操…

坚果的2022年终总结

人生天地之间&#xff0c;若白驹过隙&#xff0c;转眼间&#xff0c;这一年又快要过去了&#xff0c;按照惯例还是写一篇年终总结&#xff0c;同时也看一下自己是否又成长&#xff0c;是否有哪些事情没做好&#xff0c;给自己做一个复盘。一、缘起OpenHarmony我是从去年开始参加…

Webpack 钩子介绍、手写 Webpack Plugin

目录 1. Plugin 用作和工作原理 1.1 Plugin 的作用 1.2 Plugin 的工作原理 2. Webpack 底层逻辑和钩子介绍 2.1 Webpack 内部执行流程 2.2 Webpack 内部钩子 2.2.1 钩子是什么 2.2.2 Tapable —— 为 Webpack 提供 Plugin 钩子 数据类型接口 定义 2.2.3 Compiler Hook…

C#,图像二值化(08)——灰度图像二值化,全局算法,全局阈值优化算法及其源代码

1、全局阈值算法 基于灰度直方图的优化迭代算法之一。 Iterative Scheduler and Modified Iterative Water-Filling In the downlink, the inter-cell interference is only function of the power levels and is independent of the user scheduling decisions. This suggest…

俺的2022年

年末将至&#xff0c;还是要写点总结性的内容&#xff0c;以回顾过去一年做的各种事情。工作之外从客观数据上看&#xff0c;今年的收入水平略差于去年&#xff0c;主要是工作外的收入有所减少&#xff0c;其核心原因是没有录制新的课程内容进行变现&#xff0c;原本的计划是&a…

【自学Python】Python介绍

Python教程 什么是编程语言 编程语言&#xff08;programming language&#xff09;&#xff0c;是用来定义计算机程序的形式语言。它是一种被标准化的交流技巧&#xff0c;用来向计算机发出指令。 也可以说&#xff0c;计算机语言让程序员能够准确地定义计算机所需要使用的…

拓展交流空间,分享开发精彩 | 开发者说·DTalk 鉴赏

日月其迈&#xff0c;岁律更新&#xff0c;时间的洗礼让开发者们更加坚韧&#xff0c;持续探索&#xff0c;不断追求&#xff0c;同样也激励着我们为开发者提供更多的帮助与支持。不断迭代的技术产品是开发者们的趁手工具&#xff0c;定期更新的政策助力打造安全可靠的生态&…

基础数学(4)——线性回归复习

文章目录课程回顾基础知识回归模型的建模过程一元线性回归模型线性回顾进行极大似然估计&#xff08;例题&#xff08;必考&#xff09;&#xff09;极大似然估计极大似然估计的性质线性性无偏性最优性&#xff08;记住即可&#xff0c;没有推导&#xff09;方差计算一元线性回…

智能制造 | AIRIOT智慧工厂管理解决方案

工厂生产运转中&#xff0c;设备数量多&#xff0c;环境复杂、企业往往需要承担很高的维修、保养、备件和人力成本。传统的工厂改革遇到了诸多前所未有的挑战&#xff1a; 1、管理系统较多&#xff0c;数据隔离&#xff0c;系统集成困难重重&#xff1b; 2、大量老旧设备无法联…