Godot 游戏引擎学习 第四课

Godot 游戏引擎学习 第四课

December 22, 2020

今天 UP 主的这节课没什么内容,主要时优化了跳跃和移动,本来像提前看 UP 主的下一个视频:在场景中增加移动的砖块,但是因为一些事情耽搁,这篇文章写完的时候已经快 11 点钟了,自己也有点累了,今天就学到这里把。

优化移动和跳跃

目前角色的移动方式是按下就走,放开按键就立马停止,像个机器人。我们可以利用 move_toward() 函数实现一个加速效果,这样角色在移动和停止的时候会有一个加速和减速效果。

# 如果在地上则给与地面加速度,如果在空中则给与空中加速度,这是要给GDScript中的三元表达式,if后面的表达式如果为真则将前面的额值给acc,否则给后面的值
var acc = acceleration if is_on_floor() else air_acceleration
# move_toward 利用delta值从a值到b值进行增量增长,到达max_speed
velocity.x = move_toward(velocity.x, direction * max_speed, acc * delta)

跳跃的更改了大部分以前的跳跃逻辑,之前的角色在平台上跳跃出去后在空中还可以进行一次二段跳,这有点不符合逻辑,所以这里更改了跳跃逻辑。

首先解决从平台上跳跃出去后还可以在空中跳跃一次的问题。增了一个主要状态变量 can_jump,因为代码很琐碎,等会直接把代码贴上来把。我在这里说下主体思路把。

首先跳跃不能仅仅判断角色是否处于跳跃状态了,还得判断是否在地板上,如果是刚刚刚离开地面一定时间内允许跳跃,超过了则不允许。所以这里要用要新的节点组件 Timer,这个就时一个计时器,可以控制多少时间内计时一次。让角色在离开里面时便开始计时,如果在指定时间内则允许继续跳跃(课件作者这个好像有点不严谨,如果在地面上跳跃不是会有一个很短的 2 连跳?)

且怎加了一个小跳功能,如果在跳跃状态松开了跳跃按钮,且跳跃高度低于设定的小跳高度则变为小跳。

另外增加角色的快要落地时玩家想立马起跳的判断,之前时角色必须完全落地时才能进行跳跃。

修改后的相关代码如下:

extends KinematicBody2D

# 设置人物重力
const gravity = 2000 
# 设置人物移动速度
const max_speed = 350
# 地面的加速度和空中的加速度
const acceleration = max_speed / 0.2
const air_acceleration = max_speed / 0.05
# 设置人物跳跃高度
const jump_force = 800


# 速度
var velocity = Vector2.ZERO
# 是否处于跳跃状态
var is_jumping = false
# 人物方向
var direction

# 在Godot可以通过$符号获取当前目录的所有节点,onready表示只要游戏一准备好就首先把节点取出来存到变量中
onready var animation_palyer = $AnimationPlayer
onready var sprite = $Sprite
# 获取两个计时器的节点对象
onready var coyote_timer = $CoyoteTimer
onready var jump_request_timer = $JumpRequestTimer

# 物理帧处理,delta参数忘记是啥意思了,好像是同步画面的。
func _physics_process(_delta):
	# 在每一帧判断角色是否在地板之上
	var was_on_floor = is_on_floor()

	# move_and_slide为父类函数,用于sprite移动,第二个参数指定天花板是那个方向
	velocity = move_and_slide(velocity, Vector2.UP)
	# is_on_floor父类函数,如果主体在地板上,则返回true。仅在调用move_and_slide()时更新。
	if is_on_floor():
		# 如果人物在地板上则允许进行跳操作
		is_jumping = false
	# 如果在地板上,且是允许跳跃状态才进行跳跃
	elif was_on_floor and not is_jumping:
		# 在跳跃的瞬间开其计时器
		coyote_timer.start()
	#sprite.flip_h = direction

# 检测玩家输入(这个函数只在玩家有按下按键时才进行调用)
func _input(event):
	# 实现落地的瞬间跳跃功能,开启计时器
	if event.is_action_pressed("move_jump"):
		jump_request_timer.start()
	# 通过event.is_action_released判断是否在起跳过程中释放了空格键,并且跳跃高度没有超过小跳高度则进行小跳。
	if event.is_action_released("move_jump") and velocity.y < -jump_force / 2:
		velocity.y = -jump_force / 2
	
	

# 每一帧都会执行这个函数
func _process(delta):
	# 检测用户按钮,get_action_strength返回按下状态,按下为1,没按则0,如果按下right则返回复数,按下left返回正数
	direction = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
	# 如果在地上则给与地面加速度,如果在空中则给与空中加速度,这是要给GDScript中的三元表达式,if后面的表达式如果为真则将前面的额值给acc,否则给后面的值
	var acc = acceleration if is_on_floor() else air_acceleration

	# 利用获取到的方向值进行人物左右移动。
	# move_toward 利用delta值让从a值到b值进行增量增长,到达max_speed
	velocity.x = move_toward(velocity.x, direction * max_speed, acc * delta)
	# 跳跃
	velocity.y += gravity * delta
	
	# 新增状态变量can_jump ,如果在地上,或者coyote_timer小于0.2则允许跳跃
	var can_jump = is_on_floor() or coyote_timer.time_left < 0
	# 如果允许跳跃(在地上或者处于coyote时间内)或者同时处于落地瞬间,则可触犯跳状态则让精灵腾空
	if can_jump and jump_request_timer.time_left > 0:
		velocity.y = -jump_force
		# 设置跳跃状态,避免可以进行连跳操作
		is_jumping = true
		# 避免bug,关闭掉两个计时器
		jump_request_timer.stop()
		coyote_timer.stop()
	
	# 控制sprite动画
	# 如果处于可跳跃状态,则播放跳跃动画
	if is_jumping:
		animation_palyer.play("jump")
	# 空闲状态播放空闲动画
	elif velocity.x == 0:
		animation_palyer.play("idle")
	# 移动状态则播放移动动画
	else:
		animation_palyer.play("walk")
		
	# 根据移动方向更新角色朝向
	if direction != 0:
		sprite.flip_h = direction < 0
	

第四课

加入评论