123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- extends Area2D
- # Nodes
- var grid:TileMap
- onready var tween = $Tween
- # Misc
- var cell_size
- var cell_half_size
- var alive = false
- # Enum
- enum Direction {
- UP = 0
- RIGHT = 1
- DOWN = 2
- LEFT = 3
- }
- enum Side {
- LEFT = -1
- RIGHT = 1
- }
- # Movement
- var posix
- var posiy
- var dirx = 0
- var diry = 0
- var dire
- var dire_delta = 0
- var target_pos
- # Controls
- export var turn_left_action:String
- export var turn_right_action:String
- func _ready():
- add_to_group("players")
- spring()
- assert(grid)
- assert(turn_left_action)
- assert(turn_right_action)
- cell_size = int (grid.get_cell_size().x)
- cell_half_size = cell_size / 2
- # Adjust spawn situation
- posix = int (position.x / 64)
- posiy = int (position.y / 64)
- dire = int((rotation_degrees + 45) / 90)
- apply_turn()
- tween.connect_into(self)
- func _unhandled_input(event):
- if event.is_pressed():
- if event.is_action(turn_left_action):
- prepare_turn(Side.LEFT)
- get_tree().set_input_as_handled()
- elif event.is_action(turn_right_action):
- prepare_turn(Side.RIGHT)
- get_tree().set_input_as_handled()
- func _on_game_start():
- move()
- func _on_tween_completed(_o, key):
- if (key == ":position"):
- move()
- func _on_crash(body):
- die()
- generate_wall()
- # TODO : use enum for blocks
- grid.set_cell(posix, posiy, 2)
- func generate_wall():
- # TODO : use enum for blocks
- grid.set_cell(posix - dirx, posiy - diry, 1)
- func prepare_turn(left_or_right:int):
- var current_angle = (dire + dire_delta) * 90
- dire_delta += left_or_right
- if dire_delta > Side.RIGHT:
- dire_delta = Side.RIGHT
- return
- elif dire_delta < Side.LEFT:
- dire_delta = Side.LEFT
- return
- var aim_angle = current_angle + 90 * left_or_right
- tween.rotate_char(self, current_angle, aim_angle)
- tween.start()
- func can_turn():
- return dire_delta != 0 and !has_block_on(dire_delta)
- func apply_turn():
- dire += dire_delta
- dire_delta = 0
- if dire < 0:
- dire = 3
- elif dire > 3:
- dire = 0
- dirx = 0
- diry = 0
- if dire == Direction.UP:
- diry -= 1
- elif dire == Direction.RIGHT:
- dirx += 1
- elif dire == Direction.DOWN:
- diry += 1
- elif dire == Direction.LEFT:
- dirx -= 1
- else:
- push_error("dire out of range")
- func move():
- if !alive:
- return
- generate_wall()
- if can_turn():
- apply_turn()
- go_forward()
- func go_forward():
- posix += dirx
- posiy += diry
- target_pos = Vector2(posix * cell_size + cell_half_size, posiy * cell_size + cell_half_size)
- tween.move_char(self, target_pos)
- tween.start()
- func has_block_on(left_or_right:int):
- var bposx:int = posix - diry * left_or_right
- var bposy:int = posiy + dirx * left_or_right
- # TODO : use enum for blocks
- return grid.get_cell(bposx, bposy) == 1
- func die():
- if alive:
- remove_from_group("living")
- alive = false
- func spring():
- alive = true
- add_to_group("living")
- func is_alive():
- return alive
|