Player.gd 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. extends Area2D
  2. # Nodes
  3. var grid:TileMap
  4. onready var tween = $Tween
  5. # Signals
  6. signal crash
  7. # Misc
  8. const cell_size = 64
  9. const cell_half_size = 32
  10. var running = false
  11. # Enum
  12. enum Direction {
  13. UP = 0
  14. RIGHT = 1
  15. DOWN = 2
  16. LEFT = 3
  17. }
  18. enum Side {
  19. LEFT = -1
  20. RIGHT = 1
  21. }
  22. # Movement
  23. var posix
  24. var posiy
  25. var dirx = 0
  26. var diry = 0
  27. var dire = 0
  28. var dire_delta = 0
  29. var target_pos
  30. const LEVEL_SPAWN_DURATION = 2
  31. # Controls
  32. export var turn_left_action:String
  33. export var turn_right_action:String
  34. func _ready():
  35. assert(turn_left_action)
  36. assert(turn_right_action)
  37. tween.connect_into(self)
  38. func _unhandled_input(event):
  39. if event.is_pressed():
  40. if event.is_action(turn_left_action):
  41. prepare_turn(Side.LEFT)
  42. get_tree().set_input_as_handled()
  43. elif event.is_action(turn_right_action):
  44. prepare_turn(Side.RIGHT)
  45. get_tree().set_input_as_handled()
  46. func spawn(newGrid, newPosition, newOrientation):
  47. # Update arena
  48. grid = newGrid
  49. # Adjust spawn situation
  50. dire_delta = 0
  51. posix = int (newPosition.x / cell_size)
  52. posiy = int (newPosition.y / cell_size)
  53. dire = int((newOrientation + 45) / 90)
  54. apply_turn()
  55. # Animate spawning
  56. tween.rotate_char(self, rotation_degrees, newOrientation, LEVEL_SPAWN_DURATION)
  57. tween.move_char(self, newPosition, LEVEL_SPAWN_DURATION)
  58. tween.start()
  59. func _on_round_start():
  60. assert(grid)
  61. spring()
  62. func _on_round_won():
  63. if running:
  64. stop()
  65. func _on_tween_completed(_o, key):
  66. if (key == ":position"):
  67. move()
  68. func _on_crash(body):
  69. if running:
  70. stop()
  71. # TODO : use enum for blocks
  72. grid.set_cell(posix, posiy, 2)
  73. emit_signal("crash")
  74. func generate_wall():
  75. # TODO : use enum for blocks
  76. grid.set_cell(posix - dirx, posiy - diry, 1)
  77. func prepare_turn(left_or_right:int):
  78. if !running:
  79. return
  80. var current_angle = (dire + dire_delta) * 90
  81. dire_delta += left_or_right
  82. if dire_delta > Side.RIGHT:
  83. dire_delta = Side.RIGHT
  84. return
  85. elif dire_delta < Side.LEFT:
  86. dire_delta = Side.LEFT
  87. return
  88. var aim_angle = current_angle + 90 * left_or_right
  89. tween.rotate_char(self, current_angle, aim_angle)
  90. tween.start()
  91. func can_turn():
  92. return dire_delta != 0 and !has_block_on(dire_delta)
  93. func apply_turn():
  94. dire += dire_delta
  95. dire_delta = 0
  96. if dire < 0:
  97. dire = 3
  98. elif dire > 3:
  99. dire = 0
  100. dirx = 0
  101. diry = 0
  102. if dire == Direction.UP:
  103. diry -= 1
  104. elif dire == Direction.RIGHT:
  105. dirx += 1
  106. elif dire == Direction.DOWN:
  107. diry += 1
  108. elif dire == Direction.LEFT:
  109. dirx -= 1
  110. else:
  111. push_error("dire out of range")
  112. func move():
  113. if !running:
  114. return
  115. generate_wall()
  116. if can_turn():
  117. apply_turn()
  118. go_forward()
  119. func go_forward():
  120. posix += dirx
  121. posiy += diry
  122. target_pos = Vector2(posix * cell_size + cell_half_size, posiy * cell_size + cell_half_size)
  123. tween.move_char(self, target_pos)
  124. tween.start()
  125. func has_block_on(left_or_right:int):
  126. var bposx:int = posix - diry * left_or_right
  127. var bposy:int = posiy + dirx * left_or_right
  128. # TODO : use enum for blocks
  129. return grid.get_cell(bposx, bposy) == 1
  130. func stop():
  131. if running:
  132. remove_from_group("running")
  133. generate_wall()
  134. running = false
  135. func spring():
  136. running = true
  137. add_to_group("running")
  138. move()
  139. func is_running():
  140. return running