【Godot4自学手册】第二十二节完成主人公的闪现功能

这一节我们主要自学主人公的闪现功能,当按下鼠标右键,我们的主人公根据不同的方向进行瞬间移动,并在身后留下一串残影,具体效果如下:
请添加图片描述

一、新建ghost场景

新建Node2D场景,命名为Ghost,存储到Scenes目录下。然后在根节点下添加4个Sprite2D精灵结点,用来展示主人公四个方向的图片,并在检查器中将Visibility->Visble关闭 。
请添加图片描述

然后为根节点添加脚本,存到Scriptes目录下命名为ghost,编写如下代码:

extends Node2D
var playerN=1 #定义显示的主任公

func _ready():
	#创建间补动画将主人公透明0.5秒后变为0
	var tween = create_tween()
	tween.tween_property(self,"modulate:a",0,0.5)
	tween.tween_callback(queue_free) 

func setShow(playernumber):#设置第几个Sprite2D显示
	get_node("Player"+str(playernumber)).visible=true

二、在Player场景编写代码

首先切换到Player场景,给根节点添加Timer结点,并命名为DashTime,在其检查器中将Timer->Wait Time设置为0.05,表示每0.05秒执行一次Timeout函数。然后切换到结点信号双击timeout信号,弹出对话框选择Player结点,然后单击连接按钮。
请添加图片描述

这样会在Player代码中添加func _on_dash_time_timeout()函数,然后编写代码如下:

func _on_dash_time_timeout():
	if dash_time > 0: #当闪现时间大于0时
		dash_time -= 1 #闪现时间减1
		var ghost = Ghost.instantiate() #实例化Ghost场景
		ghost.global_position = global_position #设置ghost节点位置为当前主人公位置
		if playerDirecion.x==1: #主人公面向右侧,对应设置ghost内Sprite2D图片向右
			ghost.setShow(1)
		elif  playerDirecion.x==-1:#主人公面向左侧,对应设置ghost内Sprite2D图片向做
			ghost.setShow(2)
		elif  playerDirecion.y==-1:#主人公面向下方,对应设置ghost内Sprite2D图片向下
			ghost.setShow(4)
		elif  playerDirecion.y==1:#主人公面向上方,对应设置ghost内Sprite2D图片向上
			ghost.setShow(3)
		else:
			ghost.setShow(1)			
		Globals.duplicate_node.add_child(ghost)#将实例化的ghost结点添加到主场景中显示
	else: #当闪现时间结束时
		velocity.x = 0 #设置速度为0
		dash_time = 5 #闪现时间重新计时
		$DashTime.stop() #DashTime停止
		state=IDLE #主人公切换到等待状态

在该函数调用前需要定义一些变量如下:

#预先加载ghost场景
var Ghost = preload("res://Scenes/ghost.tscn")
#定义闪现速度
var dash_speed = 300
#闪现时间为5
var dash_time=5

在_physics_process函数添加如下代码:

if state!=DASH and state!=HURT:
		if Input.is_action_just_pressed("dash"):
			state = DASH

编写函数dash_state函数

func dash_state():
	velocity = Vector2.ZERO #将速度设为0
	$DashTime.start() #启动计时器
	if playerDirecion.x <0: #当主人公面向右,x轴速度减去闪现速度
		velocity.x -= dash_speed
	elif playerDirecion.x>0: #当主人公面向左侧,x轴度减去闪现速度
		velocity.x += dash_speed
	elif playerDirecion.y>0:#当主人公面向下方,y轴度加上闪现速度
		velocity.y += dash_speed
	elif  playerDirecion.y<0:#当主人公面向上方,y轴度减去闪现速度
		velocity.y -= dash_speed	
	else:
		velocity.x -= dash_speed #默认
	pass

经过上面的步骤就完成了闪现残影效果,整改Player代码如下:

extends CharacterBody2D
@onready var anima_tree=$AnimationTree
@onready var animation_player = $AnimationPlayer
@onready var stats = $Stats
var playerDirecion = Vector2(-1,0)
var direcion = Vector2.ZERO
var Ghost = preload("res://Scenes/ghost.tscn")
enum {IDLE,WALK,SWORD,HURT,DASH}
var dash_speed = 300
var dash_time=5
var state = IDLE:
	set(v):
		state=v
		match  state:
			IDLE:
				idle_state()
			WALK:
				walk_state()
			SWORD:
				sword_state()
			HURT:
				hurt_state()
			DASH:
				dash_state()
		
const SPEED = 120.0
var enemyPositon
var knockback=200


func _ready():
	Globals.last_Player = position
	

func _physics_process(delta):	
	direcion = Vector2.ZERO
	direcion.x = Input.get_axis("left", "right")
	direcion.y = Input.get_axis("up", "down")
	if state!=SWORD and state!=HURT and state !=DASH:
		if direcion:
			anima_tree.set("parameters/Idle/blend_position",direcion)
			anima_tree.set("parameters/Walk/blend_position",direcion)
			anima_tree.set("parameters/Sword/blend_position",direcion)
			anima_tree.set("parameters/Hurt/blend_position",Vector2(direcion.x*-1,direcion.y))
			state = WALK
			playerDirecion = direcion
		else:
			velocity=Vector2.ZERO
			state=IDLE
	if Input.is_action_just_pressed("sword"):
		velocity= Vector2.ZERO
		state = SWORD
	if state!=DASH and state!=HURT:
		if Input.is_action_just_pressed("dash"):
			state = DASH
	Globals.last_Player = position
	move_and_slide()	

func idle_state():#待机状态
	anima_tree["parameters/playback"].travel("Idle")
func walk_state():#行走状态
	anima_tree["parameters/playback"].travel("Walk")
	velocity = direcion * SPEED	

func sword_state():#进攻状态
	anima_tree["parameters/playback"].travel("Sword")
	await anima_tree.animation_finished	
	state=IDLE
	
func hurt_state():#受伤状态
	var dir = enemyPositon.direction_to(global_position).normalized()
	anima_tree["parameters/playback"].travel("Hurt")
	if dir.x>0:
		velocity.x +=knockback
	else:
		velocity.x -=knockback
	await anima_tree.animation_finished
	stats.health -=10	
	state=WALK
func dash_state():
	velocity = Vector2.ZERO
	$DashTime.start()
	if playerDirecion.x <0:
		velocity.x -= dash_speed
	elif playerDirecion.x>0:
		velocity.x += dash_speed
	elif playerDirecion.y>0:
		velocity.y += dash_speed
	elif  playerDirecion.y<0:
		velocity.y -= dash_speed	
	else:
		velocity.x -= dash_speed
	pass
	
func _on_hurt_box_area_entered(area):
	enemyPositon = area.owner.global_position
	state=HURT	
	
func hit_effect():
	$Camera2D._hit(Vector2(1.99,1.99),Vector2(7,-9))
	$Camera2D.frameFreeze(0.1,0.09)


	
func _on_dash_time_timeout():
	if dash_time > 0:
		dash_time -= 1
		var ghost = Ghost.instantiate()
		ghost.global_position = global_position
		if playerDirecion.x==1:
			ghost.setShow(1)
		elif  playerDirecion.x==-1:
			ghost.setShow(2)
		elif  playerDirecion.y==-1:
			ghost.setShow(4)
		elif  playerDirecion.y==1:
			ghost.setShow(3)
		else:
			ghost.setShow(1)			
		Globals.duplicate_node.add_child(ghost)
	else:
		velocity.x = 0
		dash_time = 5
		$DashTime.stop()
		state=IDLE

同学们这节就到这了,下节见。

最近更新

  1. TCP协议是安全的吗?

    2024-03-09 22:18:09       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-09 22:18:09       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-09 22:18:09       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-09 22:18:09       18 阅读

热门阅读

  1. nginx作为tcp的负载均衡

    2024-03-09 22:18:09       22 阅读
  2. C++从零开始的打怪升级之路(day44)

    2024-03-09 22:18:09       21 阅读
  3. logstash和elasticsearch的几种交互接口

    2024-03-09 22:18:09       22 阅读
  4. 负载均衡 dubbo

    2024-03-09 22:18:09       34 阅读
  5. 探究短链接生成算法

    2024-03-09 22:18:09       23 阅读
  6. html地铁跑酷

    2024-03-09 22:18:09       24 阅读
  7. Markdown语法与基础使用

    2024-03-09 22:18:09       20 阅读
  8. 国内免费好用 Chat GPT推荐

    2024-03-09 22:18:09       23 阅读
  9. c++ primer中文版第五版作业第十五章

    2024-03-09 22:18:09       19 阅读
  10. Moving Points(二维偏序,树状数组做法)

    2024-03-09 22:18:09       40 阅读