Home

Awesome

Trick or Treat

运行

服务端

要求: python 2.7

python server/main.py

客户端

Unity里运行login场景或者打包直接运行即可。

游戏实现功能

服务端

客户端

服务端

服务端架构

游戏服务端的架构在给的服务端架构模板上编写而成。

服务器主要分为以下几个模块:

服务端怪物寻路

游戏的怪物寻路在服务器端完成,通过在二维网格中的A*算法实现,传入的地图数据是从Unity中导出的二维网格坐标。

在进行寻路时首先找到场景中距离其最近的玩家的坐标,随后找到在寻路网格中距离怪物和玩家最近的可循路的整点坐标,通过A*算法计算出怪物到达玩家的路径。取路径中的怪物的下两个路径的坐标点,通过怪物的当前坐标,计算出怪物的移动向量返回给上层。

逻辑层通过设置的怪物的速度和该怪物移动的向量,在entity.tick中改变怪物的位置,并在服务器每次帧同步中将怪物的位置实时同步给各个客户端。

优化

为减少寻路算法带给服务器的压力,因为每次寻路后获取的是每个怪物移动的方向向量,所以不必服务器每帧对场景中的每个怪物都寻路一次。

故在实现时设置了怪物的寻路帧数,服务器设置的是4,即4个服务器帧(0.4秒)寻路一次,每次寻路只改变怪物的移动方向的单位向量。

而怪物的位置则可以通过缓存的怪物移动方向的单位向量和怪物的速度在每个服务器帧实时改变。

客户端

客户端架构

客户端代码都在Assets/Scripts目录下。

客户端协议发送处理

由于服务端不具有物理引擎,碰撞检测的处理,触发器的使用都需要在客户端进行。为了避免各个客户端向服务端重复发送消息。例如:怪物攻击玩家的消息,只需要一个客户端发送即可。所以各个客户端在处理攻击消息时,默认规定:本机的操作本机去处理。

即玩家的攻击和被攻击操作,只在各个客户端本机去检测。

玩家技能(导弹)的爆炸检测只在发送的本机检测,在发生碰撞时则向服务器发送爆炸消息,服务器在广播给各个客户端。

以防止每个客户端向服务端发送重复的游戏操作消息,扰乱服务端的逻辑。

客户端同步entity位置缓冲

由于客户端服务端通信的频率时每秒10帧,所以如果再客户端直接将服务端传到的怪物和其他玩家的位置设置为其当前的位置,则相应的GameObject的显示则会非常卡顿,所以在接受到服务端传输到的位置后,不能直接设置,而是进行相应的处理。

这里采用的方法是,通过服务端传送到的位置和该Entity在每个客户端本地的位置,计算出一个移动的向量,并通过该Update中的deltaTime和服务器客户端同步的帧时间的比值相乘,计算出该Gameobject在客户端每个Update中的位移,在对其位置进行相应的改变,则其他玩家和怪物的移动则会非常顺畅。

陷阱的位置放置检测

在放置陷阱时,需要玩家首先进行位置选择,并在确认后将陷阱放置完毕。

在进行陷阱检测时,会根据玩家选取的位置是否有障碍物对陷阱的shader进行实时的改变,效果是如果玩家选择的陷阱的放置的地方有障碍物,则将改变陷阱的shader变为纯色透明,并将颜色变为红色。如果是可以放置的位置,则变为绿色透明。

位置的检测是通过摄像机的朝向向场景中打一个射线,并得到落点。计算在落点内的相应立方体大小的空间内是否存在collider,如果不存在collider,则认为可以放置,否则认为不能放置。

为了放置陷阱重叠放置,在选择放置陷阱时,首先关掉陷阱中的collider,在放置陷阱时打开即可以实现放置陷阱重叠放置的功能。