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

算法伪代码:

for i = 1 to n - 1 dofor 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
玩家飞机 1 1
玩家子弹 1 1
  • 障碍物属于静态物体,不需要主动撞击任何其他物体。
  • 敌机也不需要主动撞击任何其他物体。敌机与玩家飞机的碰撞伤害计算,由玩家飞机来进行处理。
  • 敌机子弹会主动的撞击玩家飞机,由子弹来处理伤害计算。
  • 玩家飞机碰撞到障碍物之后,会进行位置矫正。碰撞到敌机之后会进行伤害计算。
  • 玩家子弹碰撞到障碍物后会销毁,碰撞到敌机之后进行伤害计算。

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

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

物理引擎学习07-小游戏飞机大战相关推荐

  1. 【游戏开发实战】使用Unity 2019制作仿微信小游戏飞机大战(七):主角飞机碰撞与爆炸

    文章目录 零.教程目录 一.前言 二.本篇目标 三.飞机机碰撞组件:BoxCollider2D.Rigidbody2D 四.添加Tag:Enemy 五.主角飞机碰撞处理:OnTriggerEnter2 ...

  2. 【Python】Python小游戏--飞机大战

    一.前言 今天已经初四,舒服的在家躺尸的春节也算过去了,又要开始辛勤的(苦逼的)学习和工作了.说点题外话,今年春节的病毒疫情真的弄的人心惶惶,我也在这为国家和武汉加油,也向一线工作人员致敬,希望早日结 ...

  3. 用JAVA制作小游戏——飞机大战(三)

    本篇博客是对飞机大战游戏项目完整代码的展示 详细代码讲解: 用JAVA制作小游戏--飞机大战(一) 用JAVA制作小游戏--飞机大战(二) 最下方附整个程序的文件下载链接 代码展示 主界面 impor ...

  4. 用JAVA制作小游戏——飞机大战(二)

    本篇博客是对飞机大战游戏使用代码的展示 重难点: 首先需要鼠标能够控制战机,使鼠标在窗口内时始终能够使战机的位置与鼠标相同,实现鼠标控制战斗机移动. 其次需要能够以一定的速度产生子弹和敌机,并且以一定 ...

  5. java小游戏-java小游戏-飞机大战

    java小游戏-java小游戏-飞机大战 1 窗口创建 2 背景图片添加 3 启动页面制作 4 启动页面点击事件 5 游戏物体父类的编写 6 背景的移动 7 双缓存的添加 8 背景图片的循环出现 9 ...

  6. c 语言500行小游戏代码,500行代码使用python写个微信小游戏飞机大战游戏.pdf

    500行行代代码码使使用用python写写个个微微信信小小游游戏戏飞飞机机大大战战游游戏戏 这篇文章主要介绍了500行代码使用python写个微信小游戏飞机大战游戏,本文通过实例代码给大家介绍的非常详 ...

  7. c语言小游戏-飞机大战

    今天我们来尝试用easyx图形库实现c语言小游戏-飞机大战(源代码和图片已经在结尾给出) 先引用头文件 #include<stdio.h> #include<time.h>// ...

  8. Java小游戏——飞机大战

    本程序是跟着尚学堂敲的,非常适合新手拿来练手.B站学习链接:047[飞机大战]_介绍视频_哔哩哔哩_bilibili​​​​​​ 主类GameWin,是游戏运行的主面板(该类继承JFrame): pa ...

  9. 设计自己的小游戏-飞机大战奖励篇

    在学习java基础知识后,根据网上飞机大战的内容和代码改变,设计出飞机大战的奖励篇小游戏,后期可将飞机大战和奖励篇等设计成一个完整游戏. 项目描述: 游戏开始,会出现若干蓝色空心圆形物体视为奖励道具会 ...

  10. python小游戏——飞机大战小游戏(附源码)

    写在前面的一些P话: 大家之前用python编写过飞机大战的部分代码, 只能够展示英雄飞机,背景,敌机和发射子弹, 今天把背景音乐,击毁敌机,爆炸特效,得分等等相关功能一并加入进来, 代码有点长,三百 ...

最新文章

  1. android基础ui控件,Android基础——基础UI控件
  2. 从一个servlet转发到另一个servlet_javaweb02-创建第一个Servlet
  3. python语言可以在哪系统操作-python能检测到它运行的是哪个操作系统?
  4. TrueNorth:IBM的百万神经元类人脑芯片
  5. 3.Your First Machine Learning Model
  6. Java 数组常用操作二(扩充、扩容、重复数据、动态数组、数组差集、数组交集、查找指定元素、判断是否相同、数组合并)
  7. LeetCode 84. 柱状图中最大的矩形(Largest Rectangle in Histogram)
  8. 14-----表单输入绑定
  9. ssis 角本组件更新数据_使用SSIS脚本组件作为数据源
  10. 压缩感知及应用 源代码_信言动态|学院成功举办2019年机器学习与压缩感知理论及其应用研讨会...
  11. Android入门笔记09
  12. HIVE学习之(三)
  13. asp.net 连接SQL Server 数据库并进行相关操作
  14. cmd常用命令 cmd打开文件软件等
  15. JS对List集合进行排序
  16. 微信小程序语音播放功能的实现
  17. 线性系统理论和设计 (仝茂达)习题答案
  18. 控制面板设置java_win10系统打开java控制面板的具体技巧
  19. 树莓派--【vim配置】
  20. fatal: unable to access 'https://chromium.googlesource.com/webm/libwebp/': Failed to connect to chro

热门文章

  1. 计算机定时关机计划任务失败,电脑无法创建任务计划怎么办|电脑中创建任务计划失败的解决方法...
  2. Moblin: kernel编译和rpm打包(一):更换kernel
  3. Majordomo系列应用(1)clipboard
  4. 《孔子》主題歌《幽蘭操》與原詩
  5. 工程师读史:张居正和胡林翼的另一面
  6. 微信小程序获取用户信息,得到是匿名信息,微信用户,问题解决
  7. 迅雷、快车、旋风解加密
  8. jmeter----jtl文件解析
  9. 为什么吃鸡进不去显示服务器,为什么吃鸡进不去游戏显示服务器未正常运行 | 手游网游页游攻略大全...
  10. IP-GUARD如何通过流量控制策略限制客户端下载文件?