Godot 中仅播放 jump/fall 动画的第一帧
Only first frame of jump/fall animation is playing in Godot
所以我试图在 godot 中编写一个双跳的代码,我设法做到了,但是由于某种原因,当我跳跃时它只播放动画的第一帧
if is_on_floor():
if on_ground == false:
on_ground = true
jump_count = 0
else:
if on_ground == true:
on_ground = false
jump_count = 1
if velocity.y < 0:
$Sprite.play("jump")
else:
$Sprite.play("fall")
这里是完整的代码以防万一
const SPEED = 100
const GRAVITY = 8
const JUMPFORCE = -150
const FLOOR = Vector2.UP
var velocity = Vector2(0, 0)
var on_ground = false
var jump_count = 0
var should_change_animation = true
func _physics_process(_delta):
if Input.is_action_pressed("right"):
velocity.x = SPEED
$Sprite.play("run")
$Sprite.flip_h = false
elif Input.is_action_pressed("left"):
velocity.x = -SPEED
$Sprite.play("run")
$Sprite.flip_h = true
else:
$Sprite.play("idle")
if is_on_floor():
if on_ground == false:
on_ground = true
jump_count = 0
else:
if on_ground == true:
on_ground = false
jump_count = 1
if velocity.y < 0:
$Sprite.play("jump")
else:
$Sprite.play("fall")
velocity.y = velocity.y + GRAVITY
if Input.is_action_just_pressed("jump"):
if jump_count < 2:
jump_count += 1
velocity.y = JUMPFORCE
on_ground = false
velocity = move_and_slide(velocity, FLOOR)
velocity.x = lerp(velocity.x, 0, 0.1)
有办法解决这个问题吗?
此代码在每个物理帧的开头运行:
if Input.is_action_pressed("right"):
velocity.x = SPEED
$Sprite.play("run")
$Sprite.flip_h = false
elif Input.is_action_pressed("left"):
velocity.x = -SPEED
$Sprite.play("run")
$Sprite.flip_h = true
else:
$Sprite.play("idle")
因此,通过将 sprite 动画设置为 "idle"
或 "run"
,每个物理帧都会成为星星。
我会继续关注点分离(我建议您阅读)。我认为你应该重构代码,将运动逻辑与视觉逻辑分开。目前它们是交错的。将关于某事的所有决定放在一起而不是与其他决定混在一起会很方便。因此,例如,如果播放了错误的动画,您只需查看一个地方,因为只有一个地方可以播放动画。如果你让我做,我会重写你的整个代码……但是,你的代码仍然很小,你可以承受一点混乱,所以我会让你做的。
对于这种特殊情况,您需要考虑:应用动画的条件是什么?
比如播放"run"
动画需要玩家按下一个方向。但这还不够,化身也必须在地板上。您可以为该效果添加条件。
顺便说一下,lerp(velocity.x, 0, 0.1)
相当于这个 velocity.x * 0.9
。我相信有一些教程教授一些货物崇拜。这里不需要 lerp
。无论如何,效果是(取决于帧)减速,化身不会立即停止(停止的速度取决于物理帧率)。
但是,一旦没有输入,您将更改为 "idle"
动画,无论化身是否在空中(与此问题相关),或者化身是否仍在移动。
因此,底线是:不要根据输入选择动画。取而代之的是根据化身的状态选择动画,特别是如果它在地板上和 velocity
.
的值
所以我试图在 godot 中编写一个双跳的代码,我设法做到了,但是由于某种原因,当我跳跃时它只播放动画的第一帧
if is_on_floor():
if on_ground == false:
on_ground = true
jump_count = 0
else:
if on_ground == true:
on_ground = false
jump_count = 1
if velocity.y < 0:
$Sprite.play("jump")
else:
$Sprite.play("fall")
这里是完整的代码以防万一
const SPEED = 100
const GRAVITY = 8
const JUMPFORCE = -150
const FLOOR = Vector2.UP
var velocity = Vector2(0, 0)
var on_ground = false
var jump_count = 0
var should_change_animation = true
func _physics_process(_delta):
if Input.is_action_pressed("right"):
velocity.x = SPEED
$Sprite.play("run")
$Sprite.flip_h = false
elif Input.is_action_pressed("left"):
velocity.x = -SPEED
$Sprite.play("run")
$Sprite.flip_h = true
else:
$Sprite.play("idle")
if is_on_floor():
if on_ground == false:
on_ground = true
jump_count = 0
else:
if on_ground == true:
on_ground = false
jump_count = 1
if velocity.y < 0:
$Sprite.play("jump")
else:
$Sprite.play("fall")
velocity.y = velocity.y + GRAVITY
if Input.is_action_just_pressed("jump"):
if jump_count < 2:
jump_count += 1
velocity.y = JUMPFORCE
on_ground = false
velocity = move_and_slide(velocity, FLOOR)
velocity.x = lerp(velocity.x, 0, 0.1)
有办法解决这个问题吗?
此代码在每个物理帧的开头运行:
if Input.is_action_pressed("right"):
velocity.x = SPEED
$Sprite.play("run")
$Sprite.flip_h = false
elif Input.is_action_pressed("left"):
velocity.x = -SPEED
$Sprite.play("run")
$Sprite.flip_h = true
else:
$Sprite.play("idle")
因此,通过将 sprite 动画设置为 "idle"
或 "run"
,每个物理帧都会成为星星。
我会继续关注点分离(我建议您阅读)。我认为你应该重构代码,将运动逻辑与视觉逻辑分开。目前它们是交错的。将关于某事的所有决定放在一起而不是与其他决定混在一起会很方便。因此,例如,如果播放了错误的动画,您只需查看一个地方,因为只有一个地方可以播放动画。如果你让我做,我会重写你的整个代码……但是,你的代码仍然很小,你可以承受一点混乱,所以我会让你做的。
对于这种特殊情况,您需要考虑:应用动画的条件是什么?
比如播放"run"
动画需要玩家按下一个方向。但这还不够,化身也必须在地板上。您可以为该效果添加条件。
顺便说一下,lerp(velocity.x, 0, 0.1)
相当于这个 velocity.x * 0.9
。我相信有一些教程教授一些货物崇拜。这里不需要 lerp
。无论如何,效果是(取决于帧)减速,化身不会立即停止(停止的速度取决于物理帧率)。
但是,一旦没有输入,您将更改为 "idle"
动画,无论化身是否在空中(与此问题相关),或者化身是否仍在移动。
因此,底线是:不要根据输入选择动画。取而代之的是根据化身的状态选择动画,特别是如果它在地板上和 velocity
.