【Godot4自学手册】第四十六节实现闪电攻击、闪电链

本节内容,主要学习闪电攻击魔法。闪电攻击又名为闪电链,就是在几个敌人之间产生不断跳动的闪电攻击效果。本节主要实现的是单击鼠标右键,会在敌人之间产生随机的闪电链条,效果如下:
请添加图片描述

一、基本闪电的建立

新建2D场景,命名为Lightning,添加子节点Sprite2D命名为light,目录结构如下:
请添加图片描述

将我们事先准备好的闪电蔬菜拖入到light的Texture属性。在其Region属性下将Enabled开启,如图所示:
请添加图片描述

同时开启图片无缝重复功能,开启方式如下图:
请添加图片描述

为根节点添加LightningSprite脚本,编写如下代码:

extends Node2D
@onready var lsprite = $light  #获取闪电图片
@export var waittime:float=0.05  #动画间隔时间

#释放闪电函数,一个参数表示第一个物体,参数二表示第二个物体,这样会在两个物体间产生一条闪电。
func  flicker(objectone,objecttwo):
	position = objectone.position#设置闪电起始位置为第一个物体
	var vector2:Vector2 = objectone.position - objecttwo.position#计算连个物体间有关向量
	set_deferred("rotation",vector2.angle() - PI/2.1) #设置闪电旋转角度
	var length = vector2.length() #计算闪电长度
	lsprite.show()  #显示闪电
	playLightiingAnima(length) #播放闪电动画

#闪电动画,主要原理是对图片素材进行剪切,每个一段时间播放一张图片
func  playLightiingAnima(length:float):
	chargeSize(Rect2(3,0,11,length))  #切割素材图片,选取其中一部分
	await  get_tree().create_timer(waittime).timeout #等待一段时间进行下一部分图片显示
	chargeSize(Rect2(20,0,11,length))
	await  get_tree().create_timer(waittime).timeout
	chargeSize(Rect2(35,0,11,length))
	await  get_tree().create_timer(waittime).timeout
	chargeSize(Rect2(51,0,11,length))
	await  get_tree().create_timer(waittime).timeout
	chargeSize(Rect2(65,0,11,length))
	await  get_tree().create_timer(waittime).timeout
	queue_free()
	
#切割素材图片,选取其中一部分
func chargeSize(RegionBox:Rect2):		
	lsprite.offset= Vector2(0,RegionBox.size.y/2*-1)  #移到图片素材的对应位置
	lsprite.region_rect = RegionBox  #切割的具体图片大小

二、场景建立魔法管理

新建2D场景,命名为light_sence。拖入敌人的素材,然后添加分组enemy。如下:
请添加图片描述
添加Node2d节点,命名为SkillManger,并添加如下代码:

extends Node2D
#预加载闪电场景
@onready var ligtningO:PackedScene = preload("res://Scenes/lightning_sprite.tscn")

#释放闪电函数 第一个参数表示释放闪电的物体数组,第二个参数表示释放深度,也就是可以释放几条闪电链	
func castLigtning(enemyObject:Array,depth:int):
	if enemyObject.size()==0: #没有释放物体直接退出
		return
	if enemyObject.size()==1:
		print("长度为1")#如果只有一个物体不会释放闪电链,咱可以释放闪电球
		return
	if enemyObject.size()==2:#两个物体直接释放一条闪电链条
		var lightskill = ligtningO.instantiate()
		add_child(lightskill)
		lightskill.flicker(enemyObject[0],enemyObject[1])
	else:
		#随机排列数组
		var array_length = enemyObject.size()    
   		 # 随机排列数组
		for i in range(array_length):
			# 获取一个随机索引
			var random_index = randi_range(0, array_length - 1) 
			# 交换当前索引和随机索引的元素
			var temp = enemyObject[i]
			enemyObject[i] = enemyObject[random_index]
			enemyObject[random_index] = temp
		#如果物体的数量多余或等于释放深度,根据深度进行如下释放闪电链
		if enemyObject.size()>=depth:
			for i in depth:
				var lightskill = ligtningO.instantiate()
				add_child(lightskill)
				lightskill.flicker(enemyObject[i],enemyObject[i+1])
				await  get_tree().create_timer(.1).timeout #间隔0.1秒释放下一闪电链
		else:#如果物体的数量多余或等于释放深度,根据物体数量进行如下释放闪电链
			var index:int = 0
			for child in enemyObject:
				if index>=enemyObject.size()-1:
					return
				else:	
					var lightskill = ligtningO.instantiate()
					add_child(lightskill)
					lightskill.flicker(enemyObject[index],enemyObject[index+1])
					index =index+1
					await  get_tree().create_timer(.05).timeout
	

为根节点添加代码如下:

extends Node2D
@onready var skill_manger = $SkillManger #获取技能管理节点

func _input(event):
	if event.is_action_pressed("sword"):#如果按下鼠标攻击键
		var enemyList = get_tree().get_nodes_in_group("enemy") #通过分组获取敌人
		skill_manger.castLigtning(enemyList,randi_range(1,3)) #释放闪电技能,随机产生闪电链深度

这里重点说明一下 event.is_action_pressed(“sword”)是我们以前设置好的攻击键,这里用的是鼠标单击左键。这个映射是在菜单栏项目下的项目设置里面进行的设置,如下:
请添加图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游戏自学

生活不易,打赏随意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值