【Godot4自学手册】第十七节主人公的攻击和敌人的受伤

本节主要学习主人公是如何向敌人发起进攻的,敌人是如何受伤的,受伤时候动画显示,击退效果等。其原理和上一节内容相同,不过有许多细节需要关注和完善。

一、修改Bug

在本节学习之前,我将要对上一节的代码进行完善,修改一些Bug。

1.第一个Bug是敌人攻击动画没有播放完整。

主要原因是:但敌人动画底6帧攻击主人公HitBox起作用后,将会将主人公向后击退一部分距离,离开了HitArea碰撞区域会立即执行_on_hit_area_body_exited内代码,状态会改变为 CHASE。所以,第一要断开hit_area_body_exited信号,并删除下面的代码:

func _on_hit_area_body_exited(body):if body.name=="Player" :state = CHASE

第二删除代码后,需要将attack_state代码修改如下:

func attack_state():		anima.play("Attack")		await  anima.animation_finishedstate = IDLE$TraceArea/Trace_Collsion.disabled=true$TraceArea/Trace_Collsion.disabled=false$HitArea/HitArea_Collsion.disabled=true$HitArea/HitArea_Collsion.disabled=false

这段代码表示敌人攻击动画完成后切换敌人状态到IDLE,同时跟踪、攻击碰撞重新停止和启动,来判断目前敌人需要进入的状态,如果在跟踪区域,就进行跟踪;如果在攻击区域就进行攻击。

2.主人公进入敌人跟踪区域,停止移动,敌人跟踪到攻击范围,发起攻击,主人公闪白效果不对应

主要原因是:在动画树中,我在制作主人公受伤的动画时用了BlendSpace1D,只有两个方向上的受伤动画。所以进行如下修改:第一在动画树中删除Hurt节点,新建BlendSpace2D节点,命名为Hurt,进入节点内部建立四个方向的受伤动画。第二修改代码。首先在walk_state()中添加如下代码:

anima_tree.set("parameters/Hurt/blend_position",Vector2(playerdirection.x*-1,playerdirection.y))

这段代码表示最后主人公的在那个方向收到的攻击。然后修改func hurt_state()代码如下:

func hurt_state():	var dir = enemyPositon.direction_to(global_position).normalized()anima_tree["parameters/playback"].travel("Hurt")if dir.x>0:velocity.x +=10else :velocity.x -=10#await  get_tree().create_timer(.4).timeout	await anima_tree.animation_finishedstate=WALKvelocity = Vector2.ZERO
3.如果主人公进入敌人跟踪区域,在敌人上方停止移动,敌人跟踪到攻击范围,攻击敌人还是左右方向,并未与主人公发生碰撞

主要原因是:我们的敌人攻击动画只有左右连个方向,攻击范围用的是圆形碰撞体,在整改圆形区域任何边缘都会发生碰撞,所以将攻击范围的圆形碰撞体改为矩形,保持左右方向,这样就可以了,效果如下:
请添加图片描述

如果我们的敌人动画时四个方向的攻击,我们可以将HitArea节点下添加连个矩形碰撞,即可时限四个方向的攻击。

二、主人公的攻击

1.添加攻击节点。

在Player场景中,给Player节点添加一个Area2D节点,命名为HitBox;给HitBox节点添加CollisionShape2D节点,命名为DownCollision,检查器中shape设置为RectangleShape2D,方形碰撞;Disabled属性启用;根据Attack_Down动画挥刀位置调整节点DownCollision位置,过程如下:
请添加图片描述

2.调整攻击动画。

切换到AnimationPlayer节点,在动画面板中第一帧添加DownCollision节点Disabled属性未启用关键帧;第四帧添加DownCollision节点Disabled属性启用关键帧;第五帧添加DownCollision节点Disabled属性未启用关键帧。最后效果如上图的动画面板所示。
同理,在HitBox节点依次添加3个CollisionShape2D节点,名称分别命名为LeftCollision、RightCollision、UpCollision,然后对着动画依次调整位置和Disabled属性。这里着重强调一下,LeftCollision等3个节点,选择矩形碰撞后还要选择唯一化,这样避免调整其中一个碰撞图形大小影响到其它节点碰撞图形,唯一化操作如下图所示。
请添加图片描述

3.设置碰撞层。

新建第6物理层,命名为HitPlayer,将HitBox节点collision中的layer设置在HitPlayer层,Mask不进行设置,结果如下:
请添加图片描述

三、敌人的受伤

1.添加受伤结点

在Enemy场景中给Eneymy节点添加子结点Area2D,命名为HurtBox。给HurtBox节点添加子节点CollisionShape2D,在检查器中shape属性选择CapsuleShape2D椭圆形碰撞,表示敌人受伤碰撞,根据敌人形状调整碰撞大小。新建Node2D结点,命名为CheckBox,将HitArea、HitBox、HurtBox、TraceArea结点拖至子节点。效果如下:
请添加图片描述

2.修改碰撞层

将HurtBox节点collision中的layer设置为空,Mask设置HitPlayer,表示受伤层主动与主人公发生碰撞,结果如下:
请添加图片描述

3.修改信号,编辑代码

首先将HurtBox结点area_entered信号添加到Enemy代码中,并完善代码如下:

func _on_hurt_box_area_entered(area):state = HURThurtdirecion = area.owner.global_position

修改hurt_state代码如下:

func hurt_state():	$CheckBox.process_mode=Node.PROCESS_MODE_DISABLED	var dir = hurtdirecion.direction_to(global_position).normalized()if abs(dir.x)>abs(dir.y):if dir.x<0:velocity.x =-200else :velocity.x =200else:if dir.y<0:velocity.y =-200else :velocity.y =200			await  get_tree().create_timer(.05).timeout	velocity = Vector2.ZEROanima.play("TakeHit")await  anima.animation_finishedstate=IDLE$CheckBox.process_mode=Node.PROCESS_MODE_INHERIT

这段代码首先当敌人受伤时所有碰撞检测代码全部失效,敌人后退200后播放受伤动画,播放完毕所有碰撞检测代码恢复正常。
修改attack_state代码如下:

func attack_state():		anima.play("Attack")		await  anima.animation_finishedstate = IDLE$CheckBox.process_mode=Node.PROCESS_MODE_DISABLEDawait  get_tree().create_timer(.5).timeout	$CheckBox.process_mode=Node.PROCESS_MODE_INHERIT

这段代码主要修复了有碰撞检测代码全部失效和恢复功能。
修改_on_trace_area_body_exited代码如下:

func _on_trace_area_body_exited(body):	if body.name=="Player" :if state != HURT:state = IDLE

这样敌人的整改代码如下:

extends CharacterBody2D
enum {IDLE,CHASE,ATTACK,HURT,DEATH
}
const SPEED = 1.0
var hitCount=2
@onready var anima = $AnimaP
@onready var animaS =$AnimaS
@onready var hit_box = $CheckBox/HurtBox
var hurtdirecionvar state = IDLEfunc _physics_process(delta):match state:IDLE:idle_state()CHASE:chase_state()ATTACK:attack_state()HURT:hurt_state()DEATH:death_state()move_and_slide()func idle_state():anima.play("Idle")func chase_state():anima.play("Run")var direction =  Globals.last_Player-global_positionif direction.x<0:animaS.flip_h=truehit_box.scale.x =-1else:animaS.flip_h = falsehit_box.scale.x=1global_position = global_position.move_toward(Globals.last_Player,SPEED)func finattack():state=IDLEfunc attack_state():		anima.play("Attack")		await  anima.animation_finishedstate = IDLE$CheckBox.process_mode=Node.PROCESS_MODE_DISABLEDawait  get_tree().create_timer(.5).timeout	$CheckBox.process_mode=Node.PROCESS_MODE_INHERIT
func hurt_state():	$CheckBox.process_mode=Node.PROCESS_MODE_DISABLED	var dir = hurtdirecion.direction_to(global_position).normalized()if abs(dir.x)>abs(dir.y):if dir.x<0:velocity.x =-200else :velocity.x =200else:if dir.y<0:velocity.y =-200else :velocity.y =200			await  get_tree().create_timer(.05).timeout	velocity = Vector2.ZEROanima.play("TakeHit")await  anima.animation_finishedstate=IDLE$CheckBox.process_mode=Node.PROCESS_MODE_INHERITfunc death_state():	passfunc _on_trace_area_body_entered(body):if body.name=="Player" :state = CHASEfunc _on_trace_area_body_exited(body):	if body.name=="Player" :if state != HURT:state = IDLEfunc _on_hit_area_body_entered(body):if body.name=="Player" :state = ATTACKfunc _on_hurt_box_area_entered(area):state = HURThurtdirecion = area.owner.global_position

最后我们预览一下效果如下:
请添加图片描述

这一节就到这了,同学们下节再见!
需要源代码的同学,请单击下载。下载源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/706960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

租赁系统|租赁软件提供免押金等多种租赁方式

租赁小程序是一种全新的租赁模式&#xff0c;为用户提供了免押金、多种租赁方式、定制化服务等多项优势&#xff0c;让用户的租赁体验更加美好。让我们来了解一下它的特点和功能。 首先&#xff0c;租赁小程序支持租完即送&#xff0c;无需等待固定租期。它提供了多种租赁方式&…

NR 2-STEP RA Absolute Timing Advance Command MAC CE的应用场景

3 GPP在 R2-2002413中将2-step RA引入&#xff0c;进而R16 38.321出现了 Absolute TAC MAC CE&#xff0c;在 NR Timing Advance(TA)_ntn rrc-CSDN博客 有提到这个MAC CE&#xff0c;当时以“absolute timing advance command MAC CE 在2-step RA的某个场景下使用”一笔带过&am…

设计模式----装饰器模式

在软件开发过程中&#xff0c;有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下&#xff0c;可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。 装饰器模式 允许向一个现有的对象添加新的功能&#xff0c;同时又不改变他的…

MQTT协议解析:揭秘固定报头、可变报头与有效载荷的奥秘

MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;是一种轻量级的通讯协议&#xff0c;常用于远程传感器和控制设备的通讯。MQTT协议基于发布/订阅模式&#xff0c;为大量计算能力有限且工作在低带宽、不可靠网络环境中的设备…

Java集合基础梳理(集合体系+ArrayList)

目录 Java集合体系 为什么要使用集合类 ? 如何选用集合? 哪些集合类是线程安全的&#xff1f;哪些不安全&#xff1f; 快速失败(fail-fast)和安全失败(fail-safe)的区别是什么&#xff1f; 遍历的同时修改一个List有几种方式 ArrayList 如何进行元素的遍历操作&#x…

Spring Boot项目误将Integer类型写成int来进行传参

在处理项目中Idea中无报错&#xff1a; 问题&#xff1a; localhost:8080/param/m2在浏览器中输入&#xff1a;localhost:8080/param/m2 产生报错&#xff1a; This application has no explicit mapping for /error, so you are seeing this as a fallback. Tue Feb 27 20:55…

Redis哨兵模式和Redis Cluster模式

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容Redis Cluster 模式支持自动故障转移功能吗&#xff1f;Redis Cluster 模式支持自动故障转移功能和哨兵有什么区别&#xff1f;Redis Cluster 模式和哨兵模式&#xff08;Sentinel&#xff09;在自动故障转移方面有一些关键…

Java最新面试宝典 SpringMVC面试题)

Java最新面试宝典 SpringMVC面试题 前言1、什么是SpringMVC&#xff1f;2、SpringMVC 的优点&#xff1f;3、Spring MVC配置步骤&#xff1f;4、SpringMVC工作原理了解吗&#xff1f;5、Spring MVC 核心组件的功能&#xff1f;6、B/S 系统标准的三层架构是什么&#xff1f;7、C…

计算机网络:深入探索HTTP

引言&#xff1a; HTTP&#xff0c;全称超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff09;&#xff0c;是互联网上数据通信的基础。它定义了客户端&#xff08;如浏览器&#xff09;和服务器之间如何交互和传输数据。HTTP最初是为了支持Web浏览而设计的&…

1200页文档笔记,java数据库面试问题

Spring框架自诞生以来一直备受开发者青睐&#xff0c;有人亲切的称之为&#xff1a;Spring 全家桶。Spring更是避免了重复造轮子的工作并跟随着互联网行业的发展做出不断的更新&#xff0c;很多研发人员把spring看作心目中最好的Java项目&#xff0c;没有之一。 **可以毫不夸张…

MySQL篇—持久化和非持久化统计信息介绍(第一篇,总共三篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…

c++委托构造函数与类的类型自动转换

前言 记录看书复习到的2个知识点 委托构造函数类类型自动转换 c11标准之后&#xff0c;类允许初始化数据成员&#xff0c;但是根据抽象派&#xff08;老派&#xff09;人员的观点&#xff0c;类一个抽象的东西&#xff0c;怎么能有具体的数值呢&#xff0c;就算要有默认数据…

送给2024数学建模参赛者20句话,学到就是赚到!

新学期来临&#xff0c;又到了备战数学建模竞赛火热时期&#xff0c;昨天为大家分享了常见的高含金量数模赛事&#xff0c;结合往届数学建模竞赛常见的问题及误区&#xff0c;数乐君给数模乐园铁粉们总结了20条数学建模竞赛参赛忠告&#xff0c;比赛期间绝对可以用到&#xff0…

Maya笔记 设置工作目录

Maya会把素材场景等自动保存在工作目录里&#xff0c;我们可以自己定义工作目录 步骤1 创建workspace.mel文件 文件/设置项目 ——>选择一个文件夹&#xff0c;点击设置——>创建默认工作区 这一个后&#xff0c;可以在文件夹里看到.mel文件 步骤2 自动创建文件夹…

Python把excel内容保存为图片(非统计图而是纯原表格数据)

一、引入 excel2img 库&#xff0c;没有的话使用 pip install excel2img进行安装 二、采用如下方法进行图片生成 excel文件名为&#xff1a;111.xlsx excel表格里面的sheet名称列表为 [Sheet1, Sheet2] 最终保存为以sheet名称.png的图片 支持跨表格合并项 import excel2i…

当Web3叙事寒冬到来,游戏是否是冬日里的“一把火”?

出品&#xff5c;欧科云链研究院 作者&#xff5c;Jason Jiang 以太坊创始人Vitalik在2019年曾说&#xff1a;金融与游戏会是区块链最先落地的场景。 在DeFi金融创新驱动上个周期后&#xff0c;沉寂近两年的Web3游戏板块&#xff0c;如今似乎也在复苏。无论是频繁获得融资&a…

【MySQL】学习多表查询和笛卡尔积 - 副本

](https://img-blog.csdnimg.cn/21dd41dce63a4f2da07b9d879ad0120b.png#pic_center) ??个人主页: ??热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ??个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-N8PeTKG6uLu4bJuM {font-family:“trebuchet ms”,…

在CentOS上使用Docker搭建Halo博客并实现远程访问的详细指南

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. Docker部署Halo1.1 检查Docker版本1.2 在Docker中部署Halo 二. Linux安装Cpol…

[CISCN 2019华东南]Web11

打开题目 看到xff就应该想到抓包 看回显也是127.0.0.1&#xff0c;我们盲猜是不是ssti模板注入 输入{{7*7}}显示49 可以看的出来flag在根目录下 输入{system(‘cat /flag’)} 得到flag 知识点&#xff1a; 漏洞确认 一般情况下输入{$smarty.version}就可以看到返回的smarty…

[数据集][目标检测]狗狗表情识别VOC+YOLO格式3971张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3971 标注数量(xml文件个数)&#xff1a;3971 标注数量(txt文件个数)&#xff1a;3971 标注…