用状态枚举和状态变量重构了代码,稍微清晰了一些。

  1. extends KinematicBody2D
  2. var speed = 120.0 # 速度 像素/秒
  3. var velocity = Vector2.ZERO # 速度向量
  4. var gravity = 5000 # 重力加速度
  5. var jump_force = 1000.0 # 单次跳跃高度
  6. enum state {
  7. STATE_ON_WALL,
  8. STATE_ON_AIR,
  9. STATE_ON_FLOOR,
  10. STATE_ON_TIZI, # 在爬梯
  11. }
  12. var n_state = state.STATE_ON_AIR
  13. func _physics_process(delta):
  14. match n_state:
  15. state.STATE_ON_AIR:
  16. # 掉到地板
  17. if is_on_floor():
  18. n_state = state.STATE_ON_FLOOR
  19. else:
  20. # 实现下落
  21. velocity.y += gravity * delta
  22. velocity = move_and_slide(velocity,Vector2.UP)
  23. state.STATE_ON_FLOOR:
  24. velocity.y = 0
  25. # 左右移动
  26. velocity.x = Input.get_axis("ui_left","ui_right") * speed
  27. # 跳跃
  28. if Input.is_action_just_pressed("ui_accept"): # 按空格键
  29. velocity.y = -jump_force
  30. n_state = state.STATE_ON_AIR
  31. velocity = move_and_slide(velocity,Vector2.UP)
  32. if is_on_wall():
  33. n_state = state.STATE_ON_WALL
  34. state.STATE_ON_TIZI:
  35. if is_on_floor():
  36. velocity.x = velocity.x * 0.9
  37. else:
  38. velocity.x = Input.get_axis("ui_left","ui_right") * speed
  39. velocity.y = Input.get_axis("ui_up","ui_down") * speed
  40. move_and_slide_with_snap(velocity,get_floor_normal(),Vector2.UP)
  41. state.STATE_ON_WALL:
  42. velocity.y = Input.get_axis("ui_up","ui_down") * speed
  43. velocity.x = Input.get_axis("ui_left","ui_right") * speed
  44. if Input.is_action_just_pressed("ui_accept"): # 按空格键
  45. velocity.y = -jump_force
  46. velocity = move_and_slide(velocity,Vector2.UP)
  47. if velocity.x != 0:
  48. velocity = move_and_slide(velocity,Vector2.UP)
  49. n_state = state.STATE_ON_AIR
  50. else:
  51. velocity = move_and_slide_with_snap(velocity,get_floor_normal(),Vector2.UP)
  52. if not is_on_wall():
  53. n_state = state.STATE_ON_AIR

改进后的代码

  1. extends KinematicBody2D
  2. var speed = 120.0 # 速度 像素/秒
  3. var velocity = Vector2.ZERO # 速度向量
  4. var gravity = 5000 # 重力加速度
  5. var jump_force = 1000.0 # 单次跳跃高度
  6. enum state {
  7. STATE_ON_WALL,
  8. STATE_ON_AIR,
  9. STATE_ON_FLOOR,
  10. STATE_ON_TIZI, # 在爬梯
  11. }
  12. var n_state = state.STATE_ON_AIR
  13. func input_x():
  14. velocity.x = Input.get_axis("ui_left","ui_right") * speed
  15. func input_y():
  16. velocity.y = Input.get_axis("ui_up","ui_down") * speed
  17. func input_jump() -> bool:
  18. return Input.is_action_just_pressed("ui_accept")
  19. func change_stage(new_state:int):
  20. n_state = new_state
  21. func _physics_process(delta):
  22. match n_state:
  23. state.STATE_ON_AIR:
  24. # 掉到地板
  25. if is_on_floor():
  26. change_stage(state.STATE_ON_FLOOR)
  27. else:
  28. # 实现下落
  29. velocity.y += gravity * delta
  30. velocity = move_and_slide(velocity,Vector2.UP)
  31. state.STATE_ON_FLOOR:
  32. velocity.y = 0
  33. # 左右移动
  34. velocity.x = Input.get_axis("ui_left","ui_right") * speed
  35. # 跳跃
  36. if input_jump(): # 按空格键
  37. velocity.y = -jump_force
  38. change_stage(state.STATE_ON_AIR)
  39. velocity = move_and_slide(velocity,Vector2.UP)
  40. if is_on_wall():
  41. change_stage(state.STATE_ON_WALL)
  42. state.STATE_ON_TIZI:
  43. if is_on_floor():
  44. velocity.x = velocity.x * 0.9
  45. else:
  46. input_x()
  47. input_y()
  48. move_and_slide_with_snap(velocity,get_floor_normal(),Vector2.UP)
  49. state.STATE_ON_WALL:
  50. input_x()
  51. input_y()
  52. if input_jump(): # 按空格键
  53. velocity.y = -jump_force / 2 # 在墙上时只能跳地面的一半
  54. velocity = move_and_slide(velocity,Vector2.UP)
  55. change_stage(state.STATE_ON_AIR)
  56. if velocity.x != 0: # 按左右键
  57. velocity = move_and_slide(velocity,Vector2.UP)
  58. change_stage(state.STATE_ON_AIR)
  59. else:
  60. velocity = move_and_slide_with_snap(velocity,get_floor_normal(),Vector2.UP)
  61. if not is_on_wall():
  62. change_stage(state.STATE_ON_AIR)

可以看到我们可以将按键语句封装为简单函数,这样对判断非常有利。
比如下面的形式

  1. func input_jump() -> bool:
  2. return Input.is_action_just_pressed("ui_accept")

或者干脆我们可以封装一个单例

  1. # mInput.gd 单例 用于统一处理按键输入
  2. extends Node
  3. var left_action = "ui_left"
  4. var right_action = "ui_right"
  5. var up_action = "ui_up"
  6. var down_action = "ui_down"
  7. var jump_action = "ui_accept"
  8. func just_pressed(action:String) -> bool:
  9. return Input.is_action_just_pressed(action)
  10. func pressed(action:String) -> bool:
  11. return Input.is_action_pressed(action)
  12. # 跳跃
  13. func input_jump() -> bool:
  14. return just_pressed(jump_action)
  15. func get_x():
  16. return Input.get_axis(left_action,right_action)
  17. func get_y():
  18. return Input.get_axis(left_action,right_action)
  19. func get_dir():
  20. return Input.get_vector(left_action,right_action,up_action,down_action)

此时,我们的玩家代码中将彻底看不到各种按键检测。

  1. extends KinematicBody2D
  2. var speed = 120.0 # 速度 像素/秒
  3. var velocity = Vector2.ZERO # 速度向量
  4. var gravity = 5000 # 重力加速度
  5. var jump_force = 1000.0 # 单次跳跃高度
  6. enum state {
  7. STATE_ON_WALL,
  8. STATE_ON_AIR,
  9. STATE_ON_FLOOR,
  10. STATE_ON_TIZI, # 在爬梯
  11. }
  12. var n_state = state.STATE_ON_AIR
  13. func input_x():
  14. velocity.x = MInput.get_x() * speed
  15. func input_y():
  16. velocity.y = MInput.get_y() * speed
  17. func change_stage(new_state:int):
  18. n_state = new_state
  19. func _physics_process(delta):
  20. match n_state:
  21. state.STATE_ON_AIR:
  22. # 掉到地板
  23. if is_on_floor():
  24. change_stage(state.STATE_ON_FLOOR)
  25. else:
  26. # 实现下落
  27. velocity.y += gravity * delta
  28. velocity = move_and_slide(velocity,Vector2.UP)
  29. state.STATE_ON_FLOOR:
  30. velocity.y = 0
  31. # 左右移动
  32. input_x()
  33. # 跳跃
  34. if MInput.input_jump(): # 按空格键
  35. velocity.y = -jump_force
  36. change_stage(state.STATE_ON_AIR)
  37. velocity = move_and_slide(velocity,Vector2.UP)
  38. if is_on_wall():
  39. change_stage(state.STATE_ON_WALL)
  40. state.STATE_ON_TIZI:
  41. if is_on_floor():
  42. velocity.x = velocity.x * 0.9
  43. else:
  44. input_x()
  45. input_y()
  46. move_and_slide_with_snap(velocity,get_floor_normal(),Vector2.UP)
  47. state.STATE_ON_WALL:
  48. input_x()
  49. input_y()
  50. if MInput.input_jump(): # 按空格键
  51. velocity.y = -jump_force / 2 # 在墙上时只能跳地面的一半
  52. velocity = move_and_slide(velocity,Vector2.UP)
  53. change_stage(state.STATE_ON_AIR)
  54. if velocity.x != 0: # 按左右键
  55. velocity = move_and_slide(velocity,Vector2.UP)
  56. change_stage(state.STATE_ON_AIR)
  57. else:
  58. velocity = move_and_slide_with_snap(velocity,get_floor_normal(),Vector2.UP)
  59. if not is_on_wall():
  60. change_stage(state.STATE_ON_AIR)