player_sprite.gd 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. @tool
  2. extends Sprite2D
  3. const ANIMATION_FRAMERATE = 15
  4. var _direction := 0
  5. var _progress := 0.0
  6. var _parent_node25d: Node25D
  7. var _parent_math: PlayerMath25D
  8. @onready var _stand: Texture2D = preload("res://assets/player/textures/stand.png")
  9. @onready var _jump: Texture2D = preload("res://assets/player/textures/jump.png")
  10. @onready var _run: Texture2D = preload("res://assets/player/textures/run.png")
  11. func _ready() -> void:
  12. _parent_node25d = get_parent()
  13. _parent_math = _parent_node25d.get_child(0)
  14. func _process(delta: float) -> void:
  15. if Engine.is_editor_hint():
  16. return # Don't run this in the editor.
  17. _sprite_basis()
  18. var movement := _check_movement() # Always run to get direction, but don't always use return bool.
  19. # Test-only move and collide, check if the player is on the ground.
  20. var k := _parent_math.move_and_collide(Vector3.DOWN * 10 * delta, true, true, true)
  21. if k != null:
  22. if movement:
  23. hframes = 6
  24. texture = _run
  25. if Input.is_action_pressed(&"movement_modifier"):
  26. delta /= 2
  27. _progress = fmod((_progress + ANIMATION_FRAMERATE * delta), 6)
  28. frame = _direction * 6 + int(_progress)
  29. else:
  30. hframes = 1
  31. texture = _stand
  32. _progress = 0
  33. frame = _direction
  34. else:
  35. hframes = 2
  36. texture = _jump
  37. _progress = 0
  38. var jumping := 1 if _parent_math.vertical_speed < 0 else 0
  39. frame = _direction * 2 + jumping
  40. func set_view_mode(view_mode_index: int) -> void:
  41. match view_mode_index:
  42. 0: # 45 Degrees
  43. transform.x = Vector2(1, 0)
  44. transform.y = Vector2(0, 0.75)
  45. 1: # Isometric
  46. transform.x = Vector2(1, 0)
  47. transform.y = Vector2(0, 1)
  48. 2: # Top Down
  49. transform.x = Vector2(1, 0)
  50. transform.y = Vector2(0, 0.5)
  51. 3: # Front Side
  52. transform.x = Vector2(1, 0)
  53. transform.y = Vector2(0, 1)
  54. 4: # Oblique Y
  55. transform.x = Vector2(1, 0)
  56. transform.y = Vector2(0.75, 0.75)
  57. 5: # Oblique Z
  58. transform.x = Vector2(1, 0.25)
  59. transform.y = Vector2(0, 1)
  60. # Change the 2D basis of the sprite to try and make it "fit" multiple view modes.
  61. func _sprite_basis() -> void:
  62. if not Engine.is_editor_hint():
  63. if Input.is_action_pressed(&"forty_five_mode"):
  64. set_view_mode(0)
  65. elif Input.is_action_pressed(&"isometric_mode"):
  66. set_view_mode(1)
  67. elif Input.is_action_pressed(&"top_down_mode"):
  68. set_view_mode(2)
  69. elif Input.is_action_pressed(&"front_side_mode"):
  70. set_view_mode(3)
  71. elif Input.is_action_pressed(&"oblique_y_mode"):
  72. set_view_mode(4)
  73. elif Input.is_action_pressed(&"oblique_z_mode"):
  74. set_view_mode(5)
  75. # This method returns a bool but if true it also outputs to the direction variable.
  76. func _check_movement() -> bool:
  77. # Gather player input and store movement to these int variables.
  78. # NOTE: These indeed have to be integers.
  79. var x := 0
  80. var z := 0
  81. if Input.is_action_pressed(&"move_right"):
  82. x += 1
  83. if Input.is_action_pressed(&"move_left"):
  84. x -= 1
  85. if Input.is_action_pressed(&"move_forward"):
  86. z -= 1
  87. if Input.is_action_pressed(&"move_back"):
  88. z += 1
  89. # Check for isometric controls and add more to movement accordingly.
  90. # For efficiency, only check the X axis since this X axis value isn't used anywhere else.
  91. if not _parent_math.isometric_controls and is_equal_approx(Node25D.SCALE * 0.86602540378, _parent_node25d.get_basis()[0].x):
  92. if Input.is_action_pressed(&"move_right"):
  93. z += 1
  94. if Input.is_action_pressed(&"move_left"):
  95. z -= 1
  96. if Input.is_action_pressed(&"move_forward"):
  97. x += 1
  98. if Input.is_action_pressed(&"move_back"):
  99. x -= 1
  100. # Set the direction based on which inputs were pressed.
  101. if x == 0:
  102. if z == 0:
  103. return false # No movement.
  104. elif z > 0:
  105. _direction = 0
  106. else:
  107. _direction = 4
  108. elif x > 0:
  109. if z == 0:
  110. _direction = 2
  111. flip_h = true
  112. elif z > 0:
  113. _direction = 1
  114. flip_h = true
  115. else:
  116. _direction = 3
  117. flip_h = true
  118. else:
  119. if z == 0:
  120. _direction = 2
  121. flip_h = false
  122. elif z > 0:
  123. _direction = 1
  124. flip_h = false
  125. else:
  126. _direction = 3
  127. flip_h = false
  128. return true # There is movement.