物理引擎学习07-小游戏飞机大战
到目前为止,碰撞检测的基本内容(狭义的碰撞检测)已经讲完了。广义的碰撞检测,我们到下一阶段再继续。本小节,在上节“碰撞反馈”的基础之上,扩展支持多物体间的碰撞检测。使用最简单的方法来检测哪些物体间会发生碰撞。算法每次遍历所有的物体,两两之间进行碰撞检测测试。所以时间复杂度是 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-小游戏飞机大战相关推荐
- 【游戏开发实战】使用Unity 2019制作仿微信小游戏飞机大战(七):主角飞机碰撞与爆炸
文章目录 零.教程目录 一.前言 二.本篇目标 三.飞机机碰撞组件:BoxCollider2D.Rigidbody2D 四.添加Tag:Enemy 五.主角飞机碰撞处理:OnTriggerEnter2 ...
- 【Python】Python小游戏--飞机大战
一.前言 今天已经初四,舒服的在家躺尸的春节也算过去了,又要开始辛勤的(苦逼的)学习和工作了.说点题外话,今年春节的病毒疫情真的弄的人心惶惶,我也在这为国家和武汉加油,也向一线工作人员致敬,希望早日结 ...
- 用JAVA制作小游戏——飞机大战(三)
本篇博客是对飞机大战游戏项目完整代码的展示 详细代码讲解: 用JAVA制作小游戏--飞机大战(一) 用JAVA制作小游戏--飞机大战(二) 最下方附整个程序的文件下载链接 代码展示 主界面 impor ...
- 用JAVA制作小游戏——飞机大战(二)
本篇博客是对飞机大战游戏使用代码的展示 重难点: 首先需要鼠标能够控制战机,使鼠标在窗口内时始终能够使战机的位置与鼠标相同,实现鼠标控制战斗机移动. 其次需要能够以一定的速度产生子弹和敌机,并且以一定 ...
- java小游戏-java小游戏-飞机大战
java小游戏-java小游戏-飞机大战 1 窗口创建 2 背景图片添加 3 启动页面制作 4 启动页面点击事件 5 游戏物体父类的编写 6 背景的移动 7 双缓存的添加 8 背景图片的循环出现 9 ...
- c 语言500行小游戏代码,500行代码使用python写个微信小游戏飞机大战游戏.pdf
500行行代代码码使使用用python写写个个微微信信小小游游戏戏飞飞机机大大战战游游戏戏 这篇文章主要介绍了500行代码使用python写个微信小游戏飞机大战游戏,本文通过实例代码给大家介绍的非常详 ...
- c语言小游戏-飞机大战
今天我们来尝试用easyx图形库实现c语言小游戏-飞机大战(源代码和图片已经在结尾给出) 先引用头文件 #include<stdio.h> #include<time.h>// ...
- Java小游戏——飞机大战
本程序是跟着尚学堂敲的,非常适合新手拿来练手.B站学习链接:047[飞机大战]_介绍视频_哔哩哔哩_bilibili 主类GameWin,是游戏运行的主面板(该类继承JFrame): pa ...
- 设计自己的小游戏-飞机大战奖励篇
在学习java基础知识后,根据网上飞机大战的内容和代码改变,设计出飞机大战的奖励篇小游戏,后期可将飞机大战和奖励篇等设计成一个完整游戏. 项目描述: 游戏开始,会出现若干蓝色空心圆形物体视为奖励道具会 ...
- python小游戏——飞机大战小游戏(附源码)
写在前面的一些P话: 大家之前用python编写过飞机大战的部分代码, 只能够展示英雄飞机,背景,敌机和发射子弹, 今天把背景音乐,击毁敌机,爆炸特效,得分等等相关功能一并加入进来, 代码有点长,三百 ...
最新文章
- android基础ui控件,Android基础——基础UI控件
- 从一个servlet转发到另一个servlet_javaweb02-创建第一个Servlet
- python语言可以在哪系统操作-python能检测到它运行的是哪个操作系统?
- TrueNorth:IBM的百万神经元类人脑芯片
- 3.Your First Machine Learning Model
- Java 数组常用操作二(扩充、扩容、重复数据、动态数组、数组差集、数组交集、查找指定元素、判断是否相同、数组合并)
- LeetCode 84. 柱状图中最大的矩形(Largest Rectangle in Histogram)
- 14-----表单输入绑定
- ssis 角本组件更新数据_使用SSIS脚本组件作为数据源
- 压缩感知及应用 源代码_信言动态|学院成功举办2019年机器学习与压缩感知理论及其应用研讨会...
- Android入门笔记09
- HIVE学习之(三)
- asp.net 连接SQL Server 数据库并进行相关操作
- cmd常用命令 cmd打开文件软件等
- JS对List集合进行排序
- 微信小程序语音播放功能的实现
- 线性系统理论和设计 (仝茂达)习题答案
- 控制面板设置java_win10系统打开java控制面板的具体技巧
- 树莓派--【vim配置】
- fatal: unable to access 'https://chromium.googlesource.com/webm/libwebp/': Failed to connect to chro
热门文章
- 计算机定时关机计划任务失败,电脑无法创建任务计划怎么办|电脑中创建任务计划失败的解决方法...
- Moblin: kernel编译和rpm打包(一):更换kernel
- Majordomo系列应用(1)clipboard
- 《孔子》主題歌《幽蘭操》與原詩
- 工程师读史:张居正和胡林翼的另一面
- 微信小程序获取用户信息,得到是匿名信息,微信用户,问题解决
- 迅雷、快车、旋风解加密
- jmeter----jtl文件解析
- 为什么吃鸡进不去显示服务器,为什么吃鸡进不去游戏显示服务器未正常运行 | 手游网游页游攻略大全...
- IP-GUARD如何通过流量控制策略限制客户端下载文件?