这一节我们主要自学主人公的闪现功能,当按下鼠标右键,我们的主人公根据不同的方向进行瞬间移动,并在身后留下一串残影,具体效果如下:
一、新建ghost场景
新建Node2D场景,命名为Ghost,存储到Scenes目录下。然后在根节点下添加4个Sprite2D精灵结点,用来展示主人公四个方向的图片,并在检查器中将Visibility->Visble关闭 。
然后为根节点添加脚本,存到Scriptes目录下命名为ghost,编写如下代码:
extends Node2D
var playerN=1 #定义显示的主任公func _ready():#创建间补动画将主人公透明0.5秒后变为0var 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 #闪现时间减1var 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 #设置速度为0dash_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_speedelif playerDirecion.x>0: #当主人公面向左侧,x轴度减去闪现速度velocity.x += dash_speedelif playerDirecion.y>0:#当主人公面向下方,y轴度加上闪现速度velocity.y += dash_speedelif 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=vmatch state:IDLE:idle_state()WALK:walk_state()SWORD:sword_state()HURT:hurt_state()DASH:dash_state()const SPEED = 120.0
var enemyPositon
var knockback=200func _ready():Globals.last_Player = positionfunc _physics_process(delta): direcion = Vector2.ZEROdirecion.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 = WALKplayerDirecion = direcionelse:velocity=Vector2.ZEROstate=IDLEif Input.is_action_just_pressed("sword"):velocity= Vector2.ZEROstate = SWORDif state!=DASH and state!=HURT:if Input.is_action_just_pressed("dash"):state = DASHGlobals.last_Player = positionmove_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=IDLEfunc hurt_state():#受伤状态var dir = enemyPositon.direction_to(global_position).normalized()anima_tree["parameters/playback"].travel("Hurt")if dir.x>0:velocity.x +=knockbackelse:velocity.x -=knockbackawait anima_tree.animation_finishedstats.health -=10 state=WALK
func dash_state():velocity = Vector2.ZERO$DashTime.start()if playerDirecion.x <0:velocity.x -= dash_speedelif playerDirecion.x>0:velocity.x += dash_speedelif playerDirecion.y>0:velocity.y += dash_speedelif playerDirecion.y<0:velocity.y -= dash_speed else:velocity.x -= dash_speedpassfunc _on_hurt_box_area_entered(area):enemyPositon = area.owner.global_positionstate=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 -= 1var ghost = Ghost.instantiate()ghost.global_position = global_positionif 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 = 0dash_time = 5$DashTime.stop()state=IDLE
同学们这节就到这了,下节见。