首页 > 其他分享 >Flappybird(基于Unity)修改与完善

Flappybird(基于Unity)修改与完善

时间:2023-03-05 22:56:19浏览次数:42  
标签:游戏 管道 Update 修改 Unity Flappybird 判定 position

项目分析

在引擎中运行原游戏

这是一个经典的游戏Flappy Bird。在游戏中,我们需要点击空格键来使角色向上飞行来避开管道(障碍物),而不让小鸟碰到这些障碍物或飞出屏幕。

image

游戏实现原理分析

在Flappy Bird游戏中,有多种判定需要实现,包括小鸟和障碍物的碰撞判定、小鸟飞出屏幕的判定以及得分的计算判定。

通过阅读源代码,我分析出游戏中各项主要判定的实现方式如下:

  1. 小鸟和障碍物的碰撞判定:该判定需要检测小鸟是否与障碍物发生碰撞。实现方法是使用矩形碰撞检测。具体来说,将小鸟和障碍物分别添加矩形碰撞箱,并检测它们是否有重叠部分。如果有重叠部分,则判定为碰撞发生。
  2. 小鸟飞出屏幕的判定:该判定需要检测小鸟是否已经飞出了屏幕。实现方法是检测小鸟的纵坐标是否超出了屏幕的上下边界。
  3. 得分的计算判定:该判定需要检测小鸟是否成功通过了一组障碍物,并进行得分的计算。在此,游戏在管道中单独添加了无实体的碰撞箱,小鸟的碰撞体积与该碰撞箱接触后,通过Logic Manger使得分计数器加一。

探索可能的问题

问题1:帧率判定问题

问题1概述

首先,在我调试游戏时,我发现游戏并没有设定运行帧数的限制,而在这样简单的游戏中,unity引擎往往会以很高的帧率来运行它。查看game status,发现果然如此。FPS数值在400-1200间波动。

image

在Unity中,所有的Update脚本都是按帧运行的。因此,如果帧率极高而且不稳定,游戏中的变化将非常快,而且没有固定的时间间隔。这使得我们难以与游戏进行交互。

这里有一个简单的验证,加入我们把movespeed调成引擎中常规的数值(比如5这样的个位数),我们可以发现在极短的时间内,游戏中管道就已经移到x轴的-10000左右的位置,完全没有反应时间,游戏就已经失败了。

image

原游戏中为了使游戏运行起来,只能将movespeed设定为一个极低的数据,才使得游戏能正常运行(玩家能看见管道缓慢移动)。

image

这或许是最简单的解决方法,但它是极不合理的。通常Unity中的数据有一个较为统一的范围,使得每个数据都能和其他数据互动、运算、判定。这样极小的数据显然可互动性极差,导致后续设及移动有关的数据都需要做预处理。

这还会导致一个更为严重的问题,也是在其他项目中实际出现过的问题,“帧数跳过”(Frame Skipping)。具体而言,当游戏运行在高帧数(例如120帧每秒)或者帧数不稳定时,游戏伤害判定数值会有多次浮动。这是因为游戏的代码基于帧判定,确并没有运行在一个相对稳定的帧数、也没有对代码进行限制,导致游戏引擎快速跳过了一些帧,使得碰撞被多次判定。

游戏引擎使用的是时间步长(Time Step)机制来控制游戏中的时间流逝。时间步长是指游戏引擎在每一帧中处理游戏逻辑的时间长度,例如,如果时间步长为0.016秒,那么游戏引擎每16毫秒处理一次游戏逻辑。

在游戏中,许多动作都是基于时间步长来计算的,例如角色移动、怪物攻击等。当游戏引擎的帧率很低(例如30帧每秒)时,时间步长会相应地增加,以确保游戏逻辑在一定时间内得到处理。而当游戏引擎的帧率很高(例如120帧每秒)时,时间步长会相应地减少,以确保游戏逻辑能够在更短的时间内得到处理。

问题1的解决

这里,我选择了引入Time.deltaTime 来解决这个问题。通过查阅Unity引擎开发文档中时间和帧速率管理,我找到了这个解决方案。在Unity引擎中,DeltaTime是一个代表自上一帧(Frame)到当前帧所花费的时间的变量。它通常被用于控制游戏对象的移动速度、动画、物理模拟等。如果deltaTime的值在一帧之内非常小,那么游戏对象的移动速度将减慢,从而使游戏变得更加平稳。优化游戏的帧率和交互性是非常重要的,这样玩家才能够享受到游戏的乐趣并获得更好的游戏体验。

image

间而言之,从上一帧到当前帧的间隔Unity 可能每帧多次调用它。而deltaTime函数能使脚本基于具体时间判定而非帧。


原代码如下:

// Update is called once per frame
    void Update()
    {
        transform.position = transform.position + (Vector3.left * moveSpeed);
        
    }

修改后代码如下:

public class PipeMoveScript : MonoBehaviour
{
    public float moveSpeed = 5;
    public float deadZone = -45;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.position = transform.position + (Vector3.left * moveSpeed)*Time.deltaTime;
        
    }
}

相关文章

  • unity3D设置Target位置和怪物类型18
    设置每一组target怪物的编号TargetManager//18.设置target编号publicinttargetPosition;设置每一个怪物的编号MonsterManager//13.设置怪物的编号publ......
  • unity3D存储音乐的开关状态17
    存储背景音乐开关的状态usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;//2.获得UIusingUnityEngine.UI;publicclassUIManager......
  • unity3D游戏存档与读档16
    Unity中使用的存档方式PlayerPrefs:数据持久化方案采用键值对的方式对数据进行存储PlayPrefs.SetInt("Index",1);可以存储IntFloatString类型的数据PlayPrefs.S......
  • unity3D游戏音效开关设置16
    得到背景音乐选框赋值赋值usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;//2.获得UIusingUnityEngine.UI;publicclassUI......
  • fastjson修改json的时间转换,包含递归json子集的时间
    JSONDateMatchersEnum时间格式枚举类packageconvert;publicenumJSONDateMatchersEnum{DEFAULT_MATCHER("yyyy-MM-ddHH:MM:ss","^((((1[6-9]|[2-9]\\d)\\d{2})-(......
  • unity3游戏build14
    file——>buildsetting添加场景......
  • unity3D制作暂停游戏和继续游戏12
    菜单出来时枪不能旋转游戏需要暂停创建空物体控制所有的游戏状态创建脚本usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;public......
  • 选课系统二次修改
      在csdn上发现了一篇高校选课系统的设计,其流程图如上。缺点:教师只能查询信息与录入成绩,没有修改课程信息、辞退学生等的能力。改进后如下:  ......
  • Anaconda 修改默认虚拟环境安装位置
    查看当前有哪些路径#简单查询condainfo#或者用这句能够直接看到key:condaconfig--show添加、删除envs_dirs#dir是路径condaconfig--addenvs_dirsdircondaco......
  • unity3D制作统计得分UI10
    创建UItext画布选择2D方便观察设置字体位置和字体大小字体颜色等为UI建立脚本......