桌游、房间类的游戏设计与开发实现(四),netty 分布式网络游戏服务器框架,netty 集群网络游戏服务器框架。

前置介绍

系列相关内容

当前系列是基于 netty 分布式网络游戏服务器框架开发。

相关系列:

  1. 桌游、房间类的游戏设计与开发实现(一)
  2. 桌游、房间类的游戏设计与开发实现(二)
  3. 桌游、房间类的游戏设计与开发实现(三)

ioGame 简单介绍

ioGame 网络游戏服务器框架 (yuque.com)

ioGame 是一个轻量级的网络编程框架,适用于网络游戏服务器、物联网、内部系统及各种需要长连接的场景;
ioGame 是基于 java netty 的高性能游戏服务器框架,是一款真.轻量级的网络编程框架。
ioGame 源码完全开放、最新文档阅读完全开放;使用完全自由、免费(遵守开源协议)。

你是否想要开发一个高性能、稳定、易用、自带负载均衡、避免类爆炸设计、可跨进程跨机器通信、集群无中心节点、集群自动化、有状态多进程的分布式的网络编程服务器呢?如果是的话,这里向你推荐一个由 java 语言编写的网络编程框架 ioGame。下面将会从多个方面来对框架做一些简单的介绍。

特点:

  • 无锁异步化、事件驱动的架构设计;轻量级,无需依赖任何第三方中间件或数据库就能支持集群、分布式
  • 通过 ioGame 可以很容易的搭建出一个集群无中心节点、集群自动化、多进程的分布式游戏服务器
  • 包体小、启动快、内存占用少、更加的节约、无需配置文件、提供了优雅的路由访问权限控制
  • 可同时支持多种连接方式:WS、UDP、TCP…等;框架已支持全链路调用日志跟踪特性
  • 让开发者用一套业务代码,能轻松切换和扩展不同的通信协议:Protobuf、JSON
  • 近原生的性能;业务框架在单线程中平均每秒可以执行 1152 万次业务逻辑
  • 代码即联调文档、JSR380验证、断言 + 异常机制 = 更少的维护成本
  • 框架具备智能的同进程亲和性;开发中,业务代码可定位与跳转
  • 架构部署灵活性与多样性:既可相互独立,又可相互融合
  • 可同时与同类型的多个游戏逻辑服通信并得到数据
  • 逻辑服之间可相互跨进程、跨机器进行通信
  • 支持玩家对游戏逻辑服进行动态绑定
  • 能与任何其他框架做融合共存
  • 对 webMVC 开发者友好
  • 无 spring 强依赖
  • 零学习成本

系列描述

本系列将介绍网络游戏开发中,桌游、房间类的游戏设计及实现流程。使用通用的模型来扩展桌游、房间类游戏的实现。

桌游、房间类的游戏通常指的是,如炉石传说、三国杀、斗地主、麻将 …等类似的桌游。或者说只要是房间类的游戏,该模型都适用。比如,CS、泡泡堂、飞行棋、坦克大战 …等。


桌游、房间类的游戏设计描述

light-game-room 房间,是 ioGame 提供的一个轻量小部件 - 可按需选择的模块。

light-game-room + 领域事件 + 内置 Kit = 轻松搞定桌游类游戏

该模块是桌游类、房间类游戏的解决方案。比较适合桌游类、房间类的游戏基础搭建,基于该模型可以做一些如,炉石传说、三国杀、斗地主、麻将 …等类似的桌游。或者说只要是房间类的游戏,该模型都适用。比如,CS、泡泡堂、飞行棋、坦克大战 …等。

如果你计划做一些桌游类的游戏,那么推荐你基于该模块做扩展。该模块遵循面向对象的设计原则,没有强耦合,可扩展性强。且帮助开发者屏蔽了很多重复性的工作,并可为项目中的功能模块结构、开发流程等进行清晰的组织定义,减少了后续的项目维护成本。


达成目标

现在,我们基于该 room 模块做一个实战示例,该示例整体比较简单,多名玩家在同一个房间里猜拳(石头、剪刀、布)得分。

实战示例包括了前后端,前端使用 FXGL 引擎,这样开发者在学习时,只需 JDK 环境就可以了,从而避免安装其他环境。

在这里插入图片描述

基于 room 模块的扩展,只需要数百行代码就完成了下述功能:

  • 登录
  • 玩家进入大厅(地图)
  • 玩家可在大厅移动
  • 玩家移动时相互可见
  • 玩家离开大厅(玩家下线)
  • 查询房间列表
  • 房间信息实时变更通知(房间内有玩家数量变化,等待中、游戏中 …等状态)
  • 玩家创建房间
  • 玩家进入房间
  • 玩家退出房间
  • 解散房间
  • 玩家准备
  • 开始游戏
  • 玩家在房间内的玩法操作
  • 游戏对接文档的生成
  • 及各种验证(断言 + 异常机制 = 清晰简洁的代码

正如开头介绍所说的,room 模块很好的帮助开发者屏蔽这些重复性的工作,并可为项目中的功能模块结构、开发流程等进行清晰的组织定义,减少了后续的项目维护成本。更重要的是有相关文档,将来当你的团队有新进成员时,可以快速的上手。


目标部分截图展示

启动游戏后玩家会将加入大厅(类似地图),多名玩家相互可见,并且玩家可以在大厅内移动。

在这里插入图片描述

图中左边是玩家的可移动区域,右边房间列表信息。

在这里插入图片描述
在这里插入图片描述


正文开始

上篇,我们介绍了房间管理相关的内容了,本篇将介绍【开始游戏流程 - 相关】相关内容。


开始游戏流程 - 相关

GameFlowService 开始游戏流程相关的。通常桌游、房间类的游戏都有一些固定的流程,如创建房间、玩家进入房间、玩家退出房间、解散房间、玩家准备、开始游戏 …等。
在这里插入图片描述

自定义扩展

GameFlowService 接口基本由开发者自己实现,因为游戏类型不同、玩法不同,所以框架只能抽象出一些流程,而具体的实现则由开发者实现。

public class TankGameFlowService implements GameFlowService {
    @Override
    public Room createRoom(RoomCreateContext createContext) {
        // 创建房间
        TankRoom room = new TanRoom();
        // return YourGameRoom
        return room;
    }

    @Override
    public Player createPlayer(GameFlowContext gameFlowContext) {
        // 创建玩家
        TankPlayer player = new TankPlayer();
        // return YourGameRoomPlayer
        return player;
    }

    @Override
    public void enterRoom(GameFlowContext gameFlowContext) {
        // 玩家进入房间 (重连)
    }

    @Override
    public void startGameVerify(GameFlowContext gameFlowContext) {
        // 游戏开始前的逻辑校验
    }

    @Override
    public void startGameVerifyAfter(GameFlowContext gameFlowContext) {
        // 游戏开始,会在 startGameVerify 校验成功后执行
    }
    
    @Override
    public void dissolveRoom(GameFlowContext gameFlowContext) {
        // 解散房间
    }

    @Override
    public void quitRoom(GameFlowContext gameFlowContext) {
        // 玩家退出房间
    }

    @Override
    public void ready(boolean ready, GameFlowContext gameFlowContext) {
        // 玩家准备
    }
}

RoomCreateContext

RoomCreateContext 是创建房间时的上下文,提供了以下 api
在这里插入图片描述

下面是一个创建 RoomCreateContext 的示例,并与 GameFlowService 接口配合使用。因为创建房间的逻辑是由开发者自定义的,如果创建过程中需要更复杂的游戏规则,可以通过动态属性来扩展。

AttrOption<YourRoomRule> ruleAttr = AttrOption.valueOf("rule");

// 创建房间
RoomCreateContext roomCreateContext = RoomCreateContext.of(flowContext)
        // 设置房间空间大小:最大可容纳 3 人,开始游戏时最少需要 2 人
        .setSpaceSize(3, 2)
        // 动态属性扩展 - 自定义房间玩法规则
        .option(ruleAttr, rule);

// 创建房间
GameFlowService gameFlowService = ...
Room room = gameFlowService.createRoom(roomCreateContext);

// 保存房间
RoomService roomService = ...
roomService.addRoom(room);
public class MyGameFlowService implements GameFlowService {
    ... ...
    @Override
    public TankRoom createRoom(RoomCreateContext createContext) {
        long roomId = roomIdCounter.incrementAndGet();

        var room = new TankRoom();
        room.setRoomId(roomId);
        room.setRoomCreateContext(createContext);
        room.setSpaceSize(createContext.getSpaceSize());

        return room;
    }
}

GameFlowContext

GameFlowService 是与开始游戏流程相关的,除了房间创建的方法使用了 RoomCreateContext 作为参数外,其余方法(玩家进入房间、玩家退出房间、解散房间、玩家准备、开始游戏)的参数则都是使用的 GameFlowContext。

GameFlowContext 也具备动态属性的特性。

在这里插入图片描述

以玩家准备来举例,来说明 GameFlowContext 的使用。

// 创建 GameFlowContext
GameFlowContext context = GameFlowContext.of(room, flowContext);

// 玩家准备
GameFlowService gameFlowService = ...
gameFlowService.ready(true, context);
// 准备与取消准备的协议
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
public class PlayerReady {
    /** userId */
    long userId;
    /** true 表示准备 */
    boolean ready;
}

public class MyGameFlowService implements GameFlowService {
    ... ...
    @Override
    public void ready(boolean ready, GameFlowContext gameFlowContext) {
        // 当前操作的玩家
        Player player = gameFlowContext.getPlayer();
        player.setReady(ready);

        // 通知房间内的玩家,有玩家准备或取消准备了
        PlayerReady playerReady = new PlayerReady();
        playerReady.userId = gameFlowContext.getUserId();
        playerReady.ready = ready;

        // 房间内广播
        gameFlowContext.getRoom().ofRangeBroadcast()
                .setResponseMessage(RoomCmd.of(RoomCmd.ready), playerReady)
                .execute();
    }
}

小结

现在,我们已经介绍了 RoomService(房间管理相关的)和 GameFlowService(开始游戏流程相关的)。现在,玩家除了不能在房间里面操作,其他的流程已经通了。

还介绍了 RoomCreateContext 和 GameFlowContext 上下文,两者都是服务于游戏流程的;同时,两者都具备动态属性的特性,如果有特殊业务的,可以通过此扩展来实现。

下篇预告

本期先介绍到这,后续将介绍【玩法操作 - 相关】相关内容。

房间内的玩法操作业务,也就是玩家的房间内具体的玩法操作。如,坦克的射击,炉石的战前选牌、出牌,麻将的吃、碰、杠、过、胡,回合制游戏的普攻、防御、技能 …等。

.
由于玩法操作的不同,所以我们的玩法操作需要是可扩展的,并用于处理具体的玩法操作。通过实现 OperationHandler 接口,开发者可以扩展不同的玩法操作;同时这种扩展方式更符合单一职责,使得我们后续的扩展与维护成本更低。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值