IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 物理引擎学习07-小游戏飞机大战 -> 正文阅读

[游戏开发]物理引擎学习07-小游戏飞机大战

到目前为止,碰撞检测的基本内容(狭义的碰撞检测)已经讲完了。广义的碰撞检测,我们到下一阶段再继续。本小节,在上节“碰撞反馈”的基础之上,扩展支持多物体间的碰撞检测。使用最简单的方法来检测哪些物体间会发生碰撞。算法每次遍历所有的物体,两两之间进行碰撞检测测试。所以时间复杂度是 O ( N 2 ) O(N^2) O(N2)

算法伪代码:

for i = 1 to n - 1 do
    for k = i + 1 to n do
        检测物体 i 和物体 k 是否发生了碰撞
    end
end

GJK碰撞检测算法比较耗时,因此在GJK碰撞检测之前,可以先用物体的包围盒快速测试是否相交。后面将会讲到广义的碰撞检测,可以近一步减少测试次数。

在这里插入图片描述

1. 小游戏概述

本小节,我们来制作一个简单的打飞机小游戏。通过制作小游戏,来学习如何应用物理引擎。小游戏的基本元素有: 敌人, 玩家, 子弹。玩家操作自己的飞机,尽可能的躲避敌人的子弹,同时发射子弹去消灭敌机。这里面就涉及到了非常多的碰撞检测。

敌机的逻辑比较简单。从屏幕上方开始。给敌机刚体一个初始的向下速度,边移动边发射子弹。当移动超出屏幕底部的时候,自动销毁掉。

子弹的逻辑也比较简单。有一个初始的位置和初始速度,一直向前移动,直到撞击到障碍物或者撞击到目标的时候销毁。同时对目标计算伤害。子弹这里用到了触发器的概念,只进行碰撞检测,不执行碰撞反馈。既可以避免子弹把敌机撞击到屏幕之外的问题,也能避免大量子弹执行碰撞反馈所引起的开销。

玩家则通过键盘控制自己的飞机移动,手动发射子弹。有一个细节需要注意,如果通过力的方式去控制玩家飞机的刚体移动,会有操作上的延迟,体验很不好。所以我倾向于直接修改飞机的坐标,但是这种方式会出现穿墙的情况。所以在飞机与墙发生碰撞的时候,按照穿透向量的反方向重新修正一下飞机的位置,避免它钻到墙里面去。

public void OnCollisionStay(CollisionInfo info)
{
    // 矫正坐标,不要穿到墙里
    rigidbody.position -= info.normal * info.penetration;
    // 将碰撞深度归零,不要让物理引擎产生作用力
    info.penetration = 0;
}

2. 碰撞掩码

在屏幕的四周创建四个box来包围住屏幕,避免玩家的飞机以及玩家的子弹移动出屏幕。但是敌机和敌机的子弹是从屏幕外边飞到屏幕内的,所以不希望障碍物挡住敌机和敌机的子弹。

这里需要引入“碰撞掩码”的概念,给每个物体添加不同的标记,以及他所期望碰撞到哪些物体。将标记信息用二进制位来表示,碰撞检测的时候可以用二进制“与”运算快速执行判断,决定拿些物体之间可以发生碰撞。

if ((a->collisionMask & b->selfMask != 0) ||
    (b->collisionMask & a->selfMask != 0))
{
    // 执行碰撞检测
}
  • selfMask 表示物体的标记;
  • collisonMask 表示物体需要和哪些其他标记的物体发生碰撞。

我们来梳理一下飞机和子弹的碰撞掩码的关系,避免出现重复的伤害计算。总共有五类物体: 障碍物, 敌机, 敌机的子弹, 玩家的飞机, 玩家的子弹。

碰撞关系障碍物敌机敌机子弹玩家飞机玩家子弹
障碍物
敌机
敌机子弹1
玩家飞机11
玩家子弹11
  • 障碍物属于静态物体,不需要主动撞击任何其他物体。
  • 敌机也不需要主动撞击任何其他物体。敌机与玩家飞机的碰撞伤害计算,由玩家飞机来进行处理。
  • 敌机子弹会主动的撞击玩家飞机,由子弹来处理伤害计算。
  • 玩家飞机碰撞到障碍物之后,会进行位置矫正。碰撞到敌机之后会进行伤害计算。
  • 玩家子弹碰撞到障碍物后会销毁,碰撞到敌机之后进行伤害计算。

3. 子弹发射器

我们在这里实现一个稍微复杂一点的子弹发射器。每次发射能够发射若干组,每组发射中又包含若干个子弹。通过控制每次发射的位置偏移,角度偏移,时间偏移。能够得到非常多样性的发射效果。

3.1 双孔发射器

每次发射三组子弹。每组包含两颗子弹。子弹之间增加位置偏移。
在这里插入图片描述

3.2 太阳辐射发射器

每次发射三组子弹。每组包含36颗子弹。子弹之间有10度的角度偏移。
在这里插入图片描述

3.3 甩鞭发射器

每次发射一组子弹。通过控制子弹的角度偏移和时间偏移,在最小和最大角度之间进行摆动。
在这里插入图片描述

3.4 螺旋发射器

每次发射一组子弹。通过控制子弹的角度偏移和时间偏移。
在这里插入图片描述

3.5 更复杂的发射器

以前我在《雷霆战机》项目组的时候,做过一版非常灵活的弹幕编辑器。每个发射器包含若干个发射组,每个组的属性可以单独编辑,组发射子弹的时机也由时间参数控制。每个组还包括若干个“影响器”,在不同的时间点,修改子弹的运动属性,如位移,旋转,速度,角速度,加速度,角加速度,运动曲线等。具体细节已经超出本节范畴,就不再去实现了。

4. 范例

本章Demo使用Unity3D引擎开发,Demo工程已上传github: https://github.com/youlanhai/learn-physics/tree/master/Assets/07-2d-demo

本系列文章会和我的个人公众号同步更新,感兴趣的朋友可以关注下我的公众号:游戏引擎学习。扫下面的二维码加关注:

游戏引擎学习

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:52:55  更:2021-08-24 15:53:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 18:56:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码