博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
東方 project 联机版开发日记(1)
阅读量:7212 次
发布时间:2019-06-29

本文共 2021 字,大约阅读时间需要 6 分钟。

hot3.png

touhou-project online

Intro

东方project是一个典型的2d射击游戏(STG),这里我要实现的是一个简单的双人联机版 东方project 游戏,内容涵盖客户端的开发和服务端的开发,主要目的是实践网络游戏的同步。

源代码仓库托管于

贴图资源是来自网上下载的《东方地灵殿》图集,然后自己用PS切了切,这里给张地灵殿的游戏截图。

截图

服务器架构

登录和房间

不需要严格意义上的账户系统,所以这方面的通信操作仅仅是客户端发出申请,服务器提供数据而已。

服务器操作 客户端操作
登记客户端连接,返回玩家id 连接服务器,申请玩家id
检查房间状态,返回成功与否 退出/进入/创建/随机 房间
是否所有玩家都已经申请开始游戏,如果是则开始游戏 申请开始游戏

游戏操作和网络同步

采用帧锁定同步机制,初步决定是使用严格帧锁定,这里是严格帧锁定相关的

对于这个流程,在开始实现服务端的时候会再做分析

基本思路是这样的,玩家操作先发送给服务器,等到收到服务器返回的关键帧后,再执行操作。

关键在于,如果不收到服务器提供的关键帧,则游戏要暂停,等待服务器关键帧抵达后才继续进行。

序号 服务器操作 客户端操作
1 关键帧计时器开始执行 控制帧计时器开始执行
2 进入关键帧如果已经收到所有客户端的控制帧,则继续下一步,否则回到上一步 -
3 整合控制帧,向所有客户端广播关键帧,重启关键帧计时 收到关键帧
4 - 播放游戏,使用关键帧提供的控制帧作为玩家输入
5 - 进入客户端控制帧
6 - 整合控制帧间的玩家输入,键盘状态,作为控制帧发送给服务器
7 收到控制帧 如果没有收到关键帧,发送完控制帧后继续等待

游戏的操作很简单,这里可以给出所有的操作类型

操作 键位定义
上下左右八方向移动 方向键
射击键 z
减速 x
符卡 c

客户端需要传递的主要就是键盘的状态,按下还是松开,这样子。

服务器接口

有了流程,那么可以定义出服务器的接口了

接口 描述 参数 结果
login 申请玩家id,也可以视作登录 {token: string}
curr-room 当前所处的房间 {room_id: number}
join-room 加入房间,需要提供要加入的房间id room_id {result: boolean}
new-room 创建房间 {room_id: number}
rand-room 随机加入房间,如果没有房间,则返回空 {room_id: number or null}
quit-room 退出房间,理论上应该不会出现错误 {result:boolean}
start 申请开始游戏,所有人都发出申请开始游戏后,则游戏开始 {result: true}
cancel-start 取消申请开始游戏 {result: true}

控制帧结构

// typescript 编写的示例// 也可以用其他方式编写,比如 protobuf 啊// 然后拿 C++ 或者 rust 写服务端也没问题// 不过为了开发速度,所以先拿 typescript 和 websocket 写个原型interface ICtrlFrame {    // 这是个 tuple    // 第一个number表示在x轴上的移动,负数表示向左,正数表示向右    // 第二个表示在y轴上的移动,负数表示向下,正数表示向上    motion:[number,number];     // 射击键的按压状态    fire: boolean;    // 低速键的按压状态    slow: boolean;    // 符卡键的按压状态    spell: boolean;}

关键帧结构

interface IKeyFrame {    // 关键帧的序号    frameIndex: number;    // 控制帧    // {[index:number]: ICtrlFrame} 这个写法是 ts 特有的    // 用起来相当于其他语言的 HashTable 之类的,举个例子来说    // 差不多像是 C++ 的 std::map
// Python 的 dict 这样 // 顺便一提 Python3 的 type annotation 可以指定 Dict[int,ICtrlFrame] 这样的类型 // import typing // ctrl: Dict[int,ICtrlFrame] = {} # 像这样 // 但是没有强类型检查 ctrl: {[index:number]: ICtrlFrame};}

转载于:https://my.oschina.net/u/3888259/blog/1831687

你可能感兴趣的文章
第 138 章 Spark
查看>>
flask 使用 SQLAlchemy 的两种方式
查看>>
Nginx入门笔记之————配置文件结构
查看>>
SQL Server-聚焦深入理解死锁以及避免死锁建议(三十三)
查看>>
Android(Linux)实时监控串口数据
查看>>
Open Sans字体兼容问题解决办法[font-face]
查看>>
现在的我为什么不泡技术论坛了
查看>>
AES加密
查看>>
MPLS LDP随堂笔记1
查看>>
HTTPS 也不安全?被发现新漏洞会暴露你的数据
查看>>
MySQL · 最佳实践 · 什么时候该升级内存规格
查看>>
花卉世界大观园和杂技之游
查看>>
安全问题会对网络购物季产生负面影响吗
查看>>
2016年日本信息安全市场规模分析
查看>>
微软:超过96%的企业用户正在测试Win10
查看>>
Google VC投资SDN初创公司Plexxi
查看>>
英特尔在移动市场另辟蹊径
查看>>
英特尔收购Movidius背后:为什么我们需要一款专门的CV处理芯片?
查看>>
三大新闻机构起诉FBI,FBI与苹果大战续集开幕?
查看>>
未来数据中心的选择:宽带多模光纤
查看>>