【Godot4自学手册】第二十节增加游戏的打击感,镜头震颤、冻结帧和死亡特效

news2024/11/24 0:55:45

这节我主要学习增加游戏的打击感。我们通过镜头震颤、冻结帧、增加攻击点特效,增加死亡。开始了。

一、添加攻击点特效

增加攻击点特效就是,在攻击敌人时,会在敌人受击点显示一个受击动画。

1.添加动画。

第一步先做个受击点动画。切换到Enemy场景,给根节点添加AnimatedSprite2D节点,命名为HiteffectAnima。在其检查器Animation->Sprite Frames 属性选择新建SpriteFrames。过程如下:
请添加图片描述

在动画帧面板中选择从精灵表中添加按钮,在弹出的对话框中选择我们提前做好的图片素材HitParticle.png,然后在选择帧面板中水平设置4,垂直设置为1,然后单击全选,最后单击添加4帧按钮。
请添加图片描述

然后在动画帧面板中将动画命名为“Default”,动画速度设置10FPS,取消动画循环。
请添加图片描述

这样我们的动画就做好了。

2.编写代码

首先需要获取动画结点,代码如下:

@onready var hiteffect_anima = $HiteffectAnima

然后编写hitHide函数,代码如下:

func hitHide():
	hiteffect_anima.hide()

编写hitPlay函数,代码如下:

func hitPlay():
	var ran = RandomNumberGenerator.new()
	var jiaodu = ran.randi_range(1,30) #产生个1到30随机数
	hiteffect_anima.rotation=TAU/jiaodu 
	#TAU示一个弧度值,改行代码表示该动画随机旋转一个角度
	hiteffect_anima.show()  #动画显示
	hiteffect_anima.play("Default")  #播放Default动画

敌人刚开始载入时需要隐藏受击点动画的,所以_ready函数调用hitPlay()函数,代码如下:

func _ready():
	hitHide()

敌人受击时,要调用hitPlay()函数,现在我们敌人受击代码已经很丰富了,如下:

func hurt_state():	#受伤状态
	stats.health -=10  #受伤一次减去10点血量
	var dir = hurtdirecion.direction_to(global_position).normalized()
	if abs(dir.x)>abs(dir.y):
		if dir.x<0:
			velocity.x =-knockback
		else :
			velocity.x =knockback
	else:
		if dir.y<0:
			velocity.y =-knockback
		else :
			velocity.y =knockback
	anima_p.play("TakeHit")
	hitPlay()  #播放受击点动画
	await  anima_p.animation_finished	
	if stats.health<=0:#血量小于等于零时,敌人进入死亡状态
		state=DEATH
	else:
		velocity = Vector2.ZERO
		state=CHASE

选择HiteffectAnima结点,在结点面板双击nimation_finished(),在弹出的对话框中选择enemy结点,然后单击链接按钮。
请添加图片描述

在代码中添加如下代码,表示动画播放完成后隐藏

func _on_hiteffect_animation_finished():
	hitHide()

二、添加死亡动画

1.添加动画。

新建Node2D场景,命名为animations,保存到Scenes目录下。给animations结点添加AnimatedSprite2D结点,命名为anima。添加动画过程与第一点中的添加动画大同小异。只需要添加我们事先准备好的动画精灵,最后动画帧面板如下:
请添加图片描述

2.添加代码

为该场景根节点添加animations代码,并保存到Scripts文件夹下,具体代码如下:

extends Node2D
# Called when the node enters the scene tree for the first time.
func _ready():
	self.hide() #隐藏动画
	pass # Replace with function body.

'''
options.box 动画父类
options.ani_name 动画名称
options.position 动画生成坐标
opions.scale 动画缩放
'''
func run_animation(options):
	var ani_temp = self.duplicate() #复制本身动画
	options.box.add_child(ani_temp) #作为options.box的子节点
	ani_temp.show()  #显示动画
	ani_temp.scale= options.scale if options.has("scale") else Vector2(1,1) 
	#三项条件,当参数有scale属性的时候,动画设置为scale没有的时候设置为不缩放
	ani_temp.position = options.position#设置动画位置
	ani_temp.get_node("anima").play("Dealth")#播放Dealth动画
	pass


func _on_anima_animation_finished():#动画播放完毕
	self.queue_free() #释放该节点
	pass 
3.全局变量

切换到全局变量globals,添加如下代码

extends Node
var last_Player
var animation_scene = preload("res://Scenes/animations.tscn")#预加载动画
var animation_scene_obj=null #场景对象
var duplicate_node = null

func _ready():
	animation_scene_obj = animation_scene.instantiate() #实例化animation_scene动画场景
	add_child(animation_scene_obj) #添加到场景中	
	var node2d = Node2D.new() #新建Node2D结点
	node2d.name ="anima_node"#结点名称为duplicate_node
	get_window().add_child.call_deferred(node2d)#将node2d结点添加到主场景的最后位置
	duplicate_node=node2d #将该节点复制给duplicate_node
	pass
4.添加死亡代码

切换到敌人代码中,对死亡代码进行修改如下:

func death_state():		
	Globals.animation_scene_obj.run_animation({
		"box":Globals.duplicate_node,
		"ani_name":"Dealth",
		"position":self.global_position,
		"scale":Vector2(1,1)
	})
	self.queue_free()

这样就完成了敌人的死亡动画调用。

三、添加镜头震颤和冻结帧

1.给相机添加代码

切换到Player场景,给Camera2D添加代码,存在Scriptes目录下命名为HitEffect.gd,具体代码如下:

extends Camera2D
	
func _hit(_scale,_offset):#震颤效果
	var tween= create_tween()
	tween.tween_property(self,"offset",Vector2.ZERO,0.12).from(_offset)
	#偏移量从_offset到ector2.ZERO,需要0.12秒
	tween.parallel().tween_property(self,"zoom",Vector2(2.00,2.00),0.12).from(_scale)
	#缩放从_scale到Vector2(2.00,2.00),需要0.12秒,这里面为啥是2不是1,是因为我本身就给主人公放大二倍显示
func frameFreeze(time_scale,duration):#冻结帧
	Engine.time_scale = time_scale 
	#控制游戏中的时钟与现实生活中的时钟的快慢。默认值为 1.0。值为 2.0 意味着游戏的移动速度是现实生活的两倍,
	#而值为 0.5 意味着游戏的移动速度是常规速度的一半
	await get_tree().create_timer(duration*time_scale).timeout
	Engine.time_scale=1
2.给Player代码中添加函数

切换到Player代码,添加hit_effect函数

func hit_effect():
	$Camera2D._hit(Vector2(1.99,1.99),Vector2(7,-9))
	$Camera2D.frameFreeze(0.1,0.09)
3.敌人受伤时调用

切换到Enemy场景,选择HurtBox节点,在其结点信号面板中双击area_enterd(area:Area2D)信号,在弹出框选择Enemy结点,并在脚本中添加如下代码:

func _on_hurt_box_area_entered(area):	#进入受伤范围
	hurtdirecion = area.owner.global_position
	area.owner.hit_effect()
	state = HURT

这样我们这节就OK了,需要源代码的同学请在顶端下载下载。

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

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

相关文章

鲸鱼优化算法(WOA)优化随机森林回归预测(RF)

WOA-RF回归 鲸鱼优化算法(WOA)优化随机森林回归预测&#xff08;RF&#xff09; 可以更换算法和替换成自己需要预测的数据集 实验结果如下

PAT——1020月饼(python)

题目要求 题目思路 计算每种月饼的均价&#xff0c;优先卖出均价最高的月饼计算总价格&#xff0c;需要注意&#xff0c;当全部月饼都不够需求时&#xff0c;价格就是当前总价格 题目代码&#xff08;python&#xff09; def mooncake(cakelist,need_cake): # 输入月饼信…

Leetcode 239:滑动窗口最大值

题意 大小为 k 的滑动窗口从整数数组 nums 的最左侧移到最右侧&#xff0c;只能看到滑动窗口中的 k 个数字&#xff0c;窗口每次向右移动一位。 返回滑动窗口的最大值。 示例 1&#xff1a; 输入&#xff1a;nums [1,3,-1,-3,5,3,6,7], k 3 输出&#xff1a;[3,3,5,5,6,7] …

Common Sense Machines(CSM):立志成为图像生成适用于游戏引擎的3D资产AI产品

详细说明 Common Sense Machines&#xff08;CMS&#xff09;&#xff1a;立志成为图像生成适用于游戏引擎的3D资产AI产品-喜好儿aigc详细说明&#xff1a;https://heehel.com/CSM-3d 官方网站&#xff1a;https://www.csm.ai/ 使用体验网址&#xff1a;https://3d.csm.ai/ 来…

stable diffusion的额外信息融入方式

conditioning怎么往sd中添加&#xff0c;一般有三种&#xff0c;一种是直接和latent拼一下&#xff0c;另外很多是在unet结构Spatialtransformers上加&#xff0c;和文本特征一样&#xff0c;通过cross-attention往unet上加&#xff0c;这里还需要注意一点&#xff0c;在文本嵌…

就业班 2401--3.5 Linux Day11--DNS解析

DNS域名解析服务 少壮不努力&#xff0c;老大徒伤悲。一、 1.DNS介绍 DNS 是域名系统 (Domain Name System) 的缩写&#xff0c;是因特网的一项核心服务&#xff0c;它作为可以将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便的访问互联网&#xff0c;…

MySQL 空间碎片详解

文章目录 前言1. 空间碎片如何产生2. 空间碎片如何查看3. 空间碎片如何回收后记 前言 MySQL 数据库在运行过程中&#xff0c;随着时间的推移&#xff0c;可能会出现空间碎片的问题。空间碎片是指数据库表中不再使用的空间&#xff0c;但由于各种原因&#xff0c;这些空间并没有…

集简云SDK嵌入支持传值,支持通过接口创建和管理流程

集简云SDK嵌入方案&#xff0c;允许开发者将集简云的产品功能直接嵌入到自己的产品中&#xff0c;用户无需单独注册或登录集简云&#xff0c;即可在第三方产品内使用集简云提供的功能。 目前&#xff0c;SDK嵌入方案已支持传值功能&#xff0c;通过SDK嵌入&#xff0c;可以在创…

电子电器架构刷写策略 —— 队列刷写

电子电器架构刷写策略 —— 队列刷写 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己…

嵌入式面试

1.关键字static的作用是什么&#xff1f;为什么static变量只初始化一次&#xff1f; 1&#xff09;修饰局部变量&#xff1a;使得变量变成静态变量&#xff0c;存储在静态区&#xff0c;存储在静态区的数据周期和程序相同&#xff0c; 在main函数开始前初始化&#xff0c;在退…

Wireshark_labs TCP

在本实验中&#xff0c;我们将详细研究著名的TCP协议的行为。我们将通过从您的电脑向远程服务器传输一份150KB 的文件(一份Lewis Carrol 的“爱丽丝梦游仙境”文本)&#xff0c; 并分析TCP传输内容的发送和接收过程来实现。我们将研究TCP对序列和确认号的使用&#xff0c;以提供…

Sparse A*算法的时间复杂度

Sparse A*(SAS)算法是A*算法的变型算法&#xff0c;下面将结合A*算法的流程分析SAS的时间复杂度。对于SAS算法而言&#xff0c;其航迹规划的时间 T T T主要由两部分组成&#xff1a; T s T_s Ts​&#xff1a;在当前结点扩展可行子结点的时间&#xff1b; T 0 T_0 T0​&#…

LeetCode每日一题只 快乐数

目录 题目介绍&#xff1a; 算法原理&#xff1a; 鸽巢原理&#xff1a; 如何找到环里元素&#xff1a; 代码实现&#xff1a; 题目介绍&#xff1a; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 算法原理&#xff1a; 我先简单举两个例子&#xff…

阿里云重新更新系统导致秘钥失效

报错解决方案&#xff1a; ssh-keygen -f "/Users/pengzhanliang/.ssh/known_hosts" -R "39.105.149.49"这个命令会从~/.ssh/known_hosts文件中移除与IP地址39.105.149.49相关的所有条目 再次尝试连接到远程服务器。这次&#xff0c;SSH将提示您接受新的主…

力扣hot100:239.滑动窗口最大值(优先队列/单调队列)

本题是一个经典的单调队列题。不过用优先队列也能解决。 一、优先队列 在使用优先队列时&#xff0c;我们会遇到这样的问题&#xff1a;如何将一个目标数从优先队列中弹出&#xff1f;如果使用stl这是办不到的&#xff0c;虽然可以自行实现这样的功能。但是我们可以这样思考&am…

Cesium 自定义Primitive - 圆

一、创作思路 1、创建一个自定义CustomPrimitive 2、然后根据两个点&#xff0c;生成圆 3、方便后期绘制圆 二、实现代码 1、在vue的包中加入turf. npm install turf/turf 1、创建一个CustomCirclePrimitive类,并加入更新的代码 export default class CustomCirclePrimitive …

面试问答之Spring进阶

文章目录 &#x1f412;个人主页&#xff1a;信计2102罗铠威&#x1f3c5;JavaEE系列专栏&#x1f4d6;前言&#xff1a;&#x1f380;说说你对Spring的认识与理解&#x1f415;Bean的分类&#x1f415; BeanFactory 接口和ApplicationContex 接口 的区别&#x1f415;SpringBe…

Text-to-SQL任务中的思维链(Chain-of-thought)探索

导语 在探索LLM在解决Text-to-SQL任务中的潜能时&#xff0c;本文提出了一种创新的‘问题分解’Prompt格式&#xff0c;结合每个子问题的表列信息&#xff0c;实现了与顶尖微调模型&#xff08;RASATPICARD&#xff09;相媲美的性能。 会议&#xff1a;EMNLP 2023链接&#x…

Python给图片加水印

受到“手动给证件加文字太麻烦”的感触&#xff0c;想用Python来实现给图片加水印&#xff0c;这不方便多了。 这里使用PIL模块&#xff1a; from PIL import Image from PIL import ImageFont from PIL import ImageDrawimg_t Image.open(cat.jpg) img_size_t img_t.size…

力扣hot100:560.和为K的子数组(前缀和+哈希表)

分析&#xff1a; 这个题目乍一看&#xff0c;数据大小用暴力解法大概率会超时&#xff0c;可能想用双指针&#xff0c;但是问题出现在 可能存在负数&#xff0c;也就是说即使是找到了一个答案&#xff0c;后面也可能存在负数和正数抵消&#xff0c;又是答案&#xff0c;因此不…