hareqj   ♂  喵他  
 编程让人生更优雅

Godot3D简单FPS射击游戏入门5--简易射击

作者:多能豆
3D  单机游戏  第三人称RPG 
作为一个FPS游戏,灵魂所在就是开枪。这节我们来做一个简易的枪(严格上来说,它已经简易到只剩个枪管)
参考前辈们的经验,对于子弹的处理,一般有两种:
(1)真实处理法:
将碰撞节点作为子弹,每帧计算它的方向,每帧检测碰撞
这样可以十分真实地还原子弹在现实世界的状态,但性能是硬伤
(2)快速处理法:
将一条射线作为子弹路径,如果该射线上有碰撞物体,则判定子弹击中
这样可以很好地避免性能超载,但在真实度上十分尴尬


到底怎么取舍呢?
让我们参考一下其它在线FPS游戏:
像是cs,彩六,军团要塞,守望,脏弹这些FPS游戏,因为地图较小,所以两种处理方法均适用:
因为在较小地图中,子弹下坠程度不高,精度误差不大,所以(2)适用
因为在较小地图中,子弹处理量不多,所需性能不高,所以(1)也适用
但像是战地5,使命召唤16,PUBG,行星边际2这种大型FPS游戏,则将分类讨论:
射程较短的武器使用(2)如,霰弹枪,手枪
射程较远的武器使用(1)如,狙击枪


回归正题,毕竟我们做的是“简单的FPS游戏”,但我们也不能同一时刻发射“成百上千”发子弹
所以我们暂时选用(1)
思路:当玩家按下鼠标时,在枪的位置生成一个子弹,并朝着枪的指向移动


首先:为了便于添加,我们先创建一个新场景(并包含以下节点):


这个场景将作为我们的“子弹”
它大致是这样的:


(注:请让Area及其子节点位于世界中心,即世界坐标x,y,z都为0,如果不为0,后期添加它时位置会偏移)
脚本如下:


(不要在意注释)
从上到下:
首先,我们先声明了三个变量:
!子弹速度
!死亡时间(即最多存在时间)
!已存在时间
之所以要定义存在时间,是因为我们不希望子弹永远飞下去(“八百里开外,一枪爆了敌人的头”是不被允许的)


接下来看_physics_process()函数:
这个函数与_process()相似,但_physics_process()为“物理处理进程”,这意味着帧速率与物理同步,即delta变量应为常数。它与_process()的执行频率不同!!!


在这个函数中,我们先声明了behind_dir并将其赋值为它本身相对于全局的z轴指向
接着,我们利用global_translate()方法,使其相对于全局坐标移动
(因为我们需要它向前飞,所以要将它乘-1。为了与刷新速度同步,还得乘帧速率)


再下来,我们将其已存在时间加上帧速率,接下来判定它的存在时间是否大于最多存在时间,如果是
则用queue_free()方法,在这一帧完毕后将这个节点及其子节点删除


这就是“子弹”,把它保存,然后回到初始场景:


在eye下添加一个mesh作为简易的枪模型
然后打开KinematicBody的脚本:


前者加载刚才保存的“子弹”场景


再在_input()函数下添加如下代码:


解释:
首先检测鼠标是否按下(“on”我绑定的是鼠标左键)
接下来将but(刚才加载的“子弹”场景)实例化,并储存在clone
再把clone(实例化的“子弹”场景)相对于全局的坐标设置为枪相对于全局的坐标
再把clone加入到KinematicBody的父节点(world)中


这样,人物就可以简易地射击了


[举报]  赞↑ [0 踩↓ [0
暂无评论
[声明]

初衷和宗旨:共同努力,推动Godot游戏引擎在国内的普及和发展.
1.本站所有内容皆为用户发布,如有涉嫌侵权请联系hareqj#163.com,告知内容右上角所在编号以及侵权证据.
2.禁止发布色情/暴恐/时政/商广/带网址或二维码水印/涉嫌隐私或未经授权的私人图片.
3.举报和投稿:hareqj#163.com

Godot中文社区QQ群
Copyright Godot中文社区 Godott.com All Rights Reserved.
京ICP备13032831号