/FunnyGame

the final assignment of web-front course

Primary LanguageJavaScript

“小心前方”微信小游戏文档

logo

GitHub链接:https://github.com/CyrilKZ/FunnyGame

二维码:code

测试环境:分辨率1920x1080

游戏亮点

  • 双人对战模式的可玩性与社交性
  • 开放式的游戏玩法与策略
  • 3D模型、场景和动画效果

游戏策划与功能

核心玩法

game_design

点击、上滑、左滑、右滑,涵盖了触屏手机的基本操作,也是本游戏的主要交互方式。两位玩家借助网络联机进行实时对战,通过滑动屏幕,操作己方方块运动来躲避前方障碍,通过点击屏幕上的特定位置,在对方方块的赛道上添加障碍。

双人对战、相互干扰的模式,给予了游戏比较高的开放度,也增添了游戏的娱乐性和竞技性,玩家可以利用多种策略来达到战胜对方的目的,这些玩法的组合大大丰富了游戏的可玩性。

滑动和点击两种操作通常要求两只手分工,考验玩家的反应能力和协调能力,需要在躲避己方障碍和向对方添加障碍这两种策略间进行平衡,做出抉择。

借助微信小游戏的社交接口,游戏实现了方便的邀请对战和易用的好友排行榜,在提升可玩性的同时增强了社交属性。

规则设计

  • 积分
  • 魔力值

界面设计

游戏界面由首页、排行榜、帮助页面、组队界面、游戏主界面和结算界面组成。

startbg

首页由游戏Logo和3个按钮组成,点击“开始游戏”按钮进入组队界面后,玩家可通过微信转发接口将邀请组队信息发送给好友,此时位于画面右侧的正是本局游戏将要使用的赛道。

game_design

在双方都选择准备后,游戏的主镜头将切入赛道上方,并缓缓下降到游戏主界面的视角,主要的游戏场景将基于这个界面展开,两个玩家操控两个方块展开竞争,或躲避或跳跃前方的障碍物,其中一个方块一旦碰上障碍物,另一方就获得本局胜利。

game_design

对局结束后,游戏进入结算界面,该界面将显示谁是胜者以及双方的得分(只有胜者的积分会记入排行),轻触屏幕可以进入组队界面,开启下一局。

finish

排行榜界面调用了微信开放数据域接口,展示了微信好友中积分前八名和玩家自己的排名信息,拓展了游戏的社交性。

ranklist

游戏效果与优化

沉浸式3D体验

本游戏的游戏主体处于3D场景中,受手机屏幕本质上只能精确反应2D信息以及其尺寸的限制,本游戏没有实现非常立体的3D交互,但是游戏元素的3D属性仍然非常重要,甚至构成了本游戏的核心玩法之一:障碍物由y轴向玩家逼近,而玩家可沿z轴、x轴方向躲避,且不同方向上的躲避有不同的意义,如向上跳跃躲避可以获得加分与能量值回复。

而本游戏的3D效果也是比较好的,与障碍物同步移动的背景造成了主角在不断前进、两个玩家在进行竞赛的感觉。在游戏设计的初期,我们尝试了很多方案,最后选出了一个较好的视角,即相机的位置、仰角和视野角度正好能满足以下几个特点:一是显示出来的赛道不是很长,压缩游戏的无效时间;二是视角不会太低使得近大远小的透视太过夸张,同时不会太高使得障碍物失去压迫感和威胁感,同时避免物体过分变形。

除了视角的设计以外,场景切换的动作也增加了沉浸感。在游戏房间界面,赛道已经显示在了屏幕右侧,当游戏开始后,会播放进入赛道的动画。赛道先到达视野**,然后镜头大幅度下拉,达到快速下降刀甚至是跌落至赛道的效果。而游戏结束后,视角将上升并回到赛道顶。这样的场景的切换连贯性非常好,带来更加好的沉浸体验。

网络对战

本游戏使用了一些技术实现了一定情况下的掉线重连。这主要是通过HTTP请求和Websocket的良好结合实现的。同时,前端也采用了一系列手段保证两名玩家有较好的显示同步、游戏逻辑同步。

当网络延迟过大或网断开时,玩家会被踢出游戏。当玩家主动切到后台时,双方游戏可以暂停,并在非极端条件下可以继续游戏,且继续保证较好的同步性。

技术实现

前端

游戏引擎

在Three.js的基础上,我进一步开发出了一个较为完整的游戏引擎,包括Sprite、粒子系统、UI场景、图片显示器和按钮等类,提供了相当实用的对外接口。充分利用Three.js的光照、和摄像机实现了立体场景、立体动画的展示。并利用正交摄像机与平面几何体模拟了二维游戏UI的显示。

底层优化

本游戏主要采用了以下几种优化策略来优化性能。

首先是对象的复用,这一点是基于示例小游戏中的对象池实现的:对于会大量出现再大量消失的对象,如本游戏中的砖块等,采用回收的策略,“消失”只是不显示,而“出现”只是改变模型的坐标,这样可以减少大量对象尤其是3D模型的创建,为游戏节省大量性能。

其次是内存的及时回收,对于一些不会复用的3D模型,Three.js自带的回收机制非常弱,当模型从场景移除时不会被回收。对于游戏中一些只会出现一次就会被销毁的对象,我封装了移除出场景、删除模型的接口,并在这些对象不再显示时及时调用,保证内存的稳定。

后端

出于信息安全考虑,微信小游戏仅允许与后端服务器通过安全的https和wss协议进行通信。因此后端服务器的技术实现主要基于https和WebSocket(wss)两部分。

https基于http协议,请求过程也与普通http请求差不多,因此仅限于对实时性和动态性要求不高的请求,例如用户登录,加入房间等。WebSocket协议是建立在TCP协议上的一种网络通信协议,具有数据轻便、双向通信等特点,适合对实时性和可靠性要求都比较高的连接,因此被选择作为游戏场景中后端服务器与前端的主要通讯方式。

后端的入口文件为back/index.js,主要实现在server文件夹中的三个模块中,其中主模块index.js主要封装了Server类,整合了https和wss两种协议,实现了将网络请求发送到函数接口的功能,team.js模块主要封装了User类、Team类和userHandler、teamHandler,主要用于处理有关用户、组队过程中的数据和信息,scene.js模块主要封装了游戏过程中面向WebSocket的一些接口,主要负责辅助前端完成游戏逻辑和信息交互。

注:后端实现的所有接口可参见 https://github.com/CyrilKZ/FunnyGame/tree/master/back/README.md

外部库引用

Three.js

为了实现计划中的3D效果,本游戏前端主要使用了Three.js库。比起Cocos和Layabox等工具,Three.js在Webgl渲染技术上相当成熟,有较高的性能,文档非常完善。

在使用的过程中发现Three.js一些功能无法适配微信提供的adapter,因此修改了底层adapter使得Three.js能够正常加载资源完成渲染。

https + Express + ws

微信小游戏主要通过https和WebSocket与服务器交换数据,所以搭建后端服务器主要采用https + Express + ws的架构。其中https基于http服务器模块,用于支持安全http协议,Express用于处理用户登录、创建及加入房间等API请求,ws则用于搭建WebSocket服务器。

ws是Node.js中用于WebSocket服务器的一个模块,基于ws模块搭建起后端服务器后,一个对局中的两名玩家分别与服务器建立WebSocket连接,交换游戏数据和队伍信息,取得了比较好的效果。

分工情况

  • 骆炳君:负责后端服务器、前端网络模块和开放数据域开发、参与前端UI设计
  • 谭昊天:负责游戏逻辑,游戏显示,部分前端UI设计及3D效果底层设计