这一节我们主要自学主人公的闪现功能,当按下鼠标右键,我们的主人公根据不同的方向进行瞬间移动,并在身后留下一串残影,具体效果如下:
一、新建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
同学们这节就到这了,下节见。