a game about throwing hammers made for the github game off
-rw-r--r--autoloads/Utils.gd54
-rw-r--r--classes/Maze.gd224
-rw-r--r--colliders/hitbox.gd6
-rw-r--r--colliders/hittable.gd2
-rw-r--r--fx/dust.gd2
-rw-r--r--fx/enemy_death.gd18
-rw-r--r--fx/trail.gd80
-rw-r--r--levels/Level.gd92
-rw-r--r--levels/LevelManager.gd92
-rw-r--r--levels/Start.gd32
-rw-r--r--ui/components/aim/aim.gd44
-rw-r--r--ui/components/caretoptionbutton/caretoptionbutton.gd16
-rw-r--r--ui/graphics.gd60
-rw-r--r--ui/popup.gd20
-rw-r--r--world/one_way_platform.gd4
15 files changed, 373 insertions, 373 deletions
diff --git a/autoloads/Utils.gd b/autoloads/Utils.gd
index 631d2b0..19db63f 100644
--- a/autoloads/Utils.gd
+++ b/autoloads/Utils.gd
@@ -2,54 +2,54 @@ extends Node
class_name Util
static func dict_cmp(d1: Dictionary, d2: Dictionary) -> bool:
- return (
- len(d1) == len(d2)
- and sort(d1.keys()) == sort(d2.keys())
- and value_types(d1.values()) == value_types(d2.values())
- )
+ return (
+ len(d1) == len(d2)
+ and sort(d1.keys()) == sort(d2.keys())
+ and value_types(d1.values()) == value_types(d2.values())
+ )
static func sort(arr: Array) -> Array:
- arr.sort()
- return arr
+ arr.sort()
+ return arr
static func value_types(arr: Array) -> Array:
- var types = []
- for value in arr:
- types.append(typeof(value))
- types.sort()
- return types
+ var types = []
+ for value in arr:
+ types.append(typeof(value))
+ types.sort()
+ return types
static func is_in_range(val: float, start: float, end: float) -> bool:
- return val >= start and val <= end
+ return val >= start and val <= end
static func instance_scene(scene: PackedScene, position: Vector2, on: Node) -> Node:
- var instance := scene.instantiate() as Node2D
- on.add_child(instance)
- instance.global_position = position
- return instance
+ var instance := scene.instantiate() as Node2D
+ on.add_child(instance)
+ instance.global_position = position
+ return instance
func instance_scene_on_main(scene: PackedScene, position: Vector2) -> Node:
- return Util.instance_scene(scene, position, get_tree().current_scene)
+ return Util.instance_scene(scene, position, get_tree().current_scene)
func instance_scene_on_level(scene: PackedScene, position: Vector2) -> Node:
- return Util.instance_scene(scene, position, Globals.levelmanager.current_level)
+ return Util.instance_scene(scene, position, Globals.levelmanager.current_level)
static func str_vec(vec: Vector2) -> String:
- var map := {Vector2.UP: "up", Vector2.DOWN: "down", Vector2.LEFT: "left", Vector2.RIGHT: "right"}
- return map.get(vec, str(vec))
+ var map := {Vector2.UP: "up", Vector2.DOWN: "down", Vector2.LEFT: "left", Vector2.RIGHT: "right"}
+ return map.get(vec, str(vec))
static func sub(a: Array, b: Array) -> Array:
- return a.filter(func(item) -> bool: return not item in b)
+ return a.filter(func(item) -> bool: return not item in b)
static func out_of_bounds(v: Vector2i, rect: Vector2i) -> bool:
- return v.x > rect.x or v.y > rect.y or v.x < 0 or v.y < 0
+ return v.x > rect.x or v.y > rect.y or v.x < 0 or v.y < 0
const hammer_path_fmt := "res://hammers/hammer_%s.tscn"
const hammers: Array[PackedScene] = [
- preload(hammer_path_fmt % "01"),
- preload(hammer_path_fmt % "02"),
- preload(hammer_path_fmt % "03"),
+ preload(hammer_path_fmt % "01"),
+ preload(hammer_path_fmt % "02"),
+ preload(hammer_path_fmt % "03"),
]
func get_hammer() -> PackedScene:
- return hammers[randi() % len(hammers)]
+ return hammers[randi() % len(hammers)]
diff --git a/classes/Maze.gd b/classes/Maze.gd
index 8e57fda..f64f92b 100644
--- a/classes/Maze.gd
+++ b/classes/Maze.gd
@@ -27,143 +27,143 @@ const _dirs := [Vector2i.UP, Vector2i.RIGHT, Vector2i.DOWN, Vector2i.LEFT]
## The image representation of this maze.
var image: Image = null:
- get:
- if not image:
- _gen_image()
- return image
+ get:
+ if not image:
+ _gen_image()
+ return image
func _init(p_size: Vector2i) -> void:
- size = p_size
- generate()
- erase_walls()
+ size = p_size
+ generate()
+ erase_walls()
## Get a maze cells value.
func get_cellv(cell: Vector2i) -> int:
- return maze[cell.y][cell.x]
+ return maze[cell.y][cell.x]
## Turns a 4b tile into a array of walls. [code]4[/code] => [code][Vector2i.DOWN][/code].
static func tile_4b_to_wall_array(tile_4b: int) -> Array[Vector2i]:
- var array: Array[Vector2i] = []
- for dir in _dirs:
- if tile_4b & cell_walls[dir]:
- array.append(dir)
- return array
+ var array: Array[Vector2i] = []
+ for dir in _dirs:
+ if tile_4b & cell_walls[dir]:
+ array.append(dir)
+ return array
## Turns a 4b tile into a array of paths. [code]4[/code] => [code][Vector2i.UP, Vector2i.LEFT, Vector2i.RIGHT][/code].
static func tile_4b_to_path_array(tile_4b: int) -> Array[Vector2i]:
- var array: Array[Vector2i] = []
- for dir in cell_walls.keys():
- if not tile_4b & cell_walls[dir]:
- array.append(dir)
- return array
+ var array: Array[Vector2i] = []
+ for dir in cell_walls.keys():
+ if not tile_4b & cell_walls[dir]:
+ array.append(dir)
+ return array
func _check_neighbours(cell: Vector2i, unvisited: Array[Vector2i]) -> Array[Vector2i]:
- # checks if neighbour is visited.
- # returns array of unvisited neighbours.
- var list: Array[Vector2i] = []
- for n in cell_walls.keys():
- if cell + n in unvisited:
- list.append(cell + n)
- return list
+ # checks if neighbour is visited.
+ # returns array of unvisited neighbours.
+ var list: Array[Vector2i] = []
+ for n in cell_walls.keys():
+ if cell + n in unvisited:
+ list.append(cell + n)
+ return list
func _set_cellv(cell: Vector2i, v: int) -> void:
- maze[cell.y][cell.x] = v
+ maze[cell.y][cell.x] = v
## Generates the maze using the [url=https://en.wikipedia.org/wiki/Maze_generation_algorithm#Randomized_depth-first_search]recursive backtracker algorithm[/url].
func generate() -> void:
- randomize()
- var unvisited: Array[Vector2i] = []
- var stack: Array[Vector2i] = []
-
- # fill maze
- maze.clear()
- for x in range(size.x):
- var row: PackedInt32Array = []
- for y in range(size.y):
- row.append(N|E|S|W)
- unvisited.append(Vector2i(x, y))
- maze.append(row)
-
- var current := Vector2i(0, 0)
- unvisited.erase(current)
-
- # recurive backtracking algorithm
- while unvisited.size() > 0:
- # check neighbours of current cell.
- var neighbours := _check_neighbours(current, unvisited)
-
- # if neighbours exist, pick one at random and move in that direction.
- # remove wall between current cell and neighbour cell.
- if neighbours.size() > 0:
- var next := neighbours[randi() % neighbours.size()]
- stack.append(current)
-
- # remove wall from both cells.
- var dir := next - current
- var current_walls: int = get_cellv(current) - cell_walls[dir]
- var next_walls: int = get_cellv(next) - cell_walls[-dir]
- _set_cellv(current, current_walls)
- _set_cellv(next, next_walls)
- current = next
- unvisited.erase(current)
- elif stack:
- # if neighbours don't exist, retrieve new current from stack.
- current = stack.pop_back()
+ randomize()
+ var unvisited: Array[Vector2i] = []
+ var stack: Array[Vector2i] = []
+
+ # fill maze
+ maze.clear()
+ for x in range(size.x):
+ var row: PackedInt32Array = []
+ for y in range(size.y):
+ row.append(N|E|S|W)
+ unvisited.append(Vector2i(x, y))
+ maze.append(row)
+
+ var current := Vector2i(0, 0)
+ unvisited.erase(current)
+
+ # recurive backtracking algorithm
+ while unvisited.size() > 0:
+ # check neighbours of current cell.
+ var neighbours := _check_neighbours(current, unvisited)
+
+ # if neighbours exist, pick one at random and move in that direction.
+ # remove wall between current cell and neighbour cell.
+ if neighbours.size() > 0:
+ var next := neighbours[randi() % neighbours.size()]
+ stack.append(current)
+
+ # remove wall from both cells.
+ var dir := next - current
+ var current_walls: int = get_cellv(current) - cell_walls[dir]
+ var next_walls: int = get_cellv(next) - cell_walls[-dir]
+ _set_cellv(current, current_walls)
+ _set_cellv(next, next_walls)
+ current = next
+ unvisited.erase(current)
+ elif stack:
+ # if neighbours don't exist, retrieve new current from stack.
+ current = stack.pop_back()
## Randomly remove walls. Prefers deleting 3 and 2 walled cells.
func erase_walls() -> void:
- randomize()
- const three_walls: Array[int] = [7, 11, 13, 14]
- const two_walls: Array[int] = [3, 5, 6, 9, 10, 12]
-
- for x in range(size.x):
- for y in range(size.y):
- if maze[y][x] in three_walls or maze[x][y] in two_walls or randi() % 3 == 0:
- var cell := Vector2i(x, y)
- var i := randi() % 4
- for _i in range(4):
- var n: Vector2i = cell_walls.keys()[i]
- i = wrapi(i + _i, 0, 3)
- if get_cellv(cell) & cell_walls[n]:
- var n_cell := (cell + n)
- if n_cell.x > size.x - 1 or n_cell.y > size.y - 1 or n_cell.x < 0 or n_cell.y < 0:
- continue
- var walls: int = get_cellv(cell) - cell_walls[n]
- var n_walls: int = get_cellv(n_cell) - cell_walls[-n]
- if (
- (x == 0 and walls & W)
- or (y == 0 and walls & N)
- or (x == size.x and walls & E)
- or (y == size.y and walls & S)
- or (n_cell.x == 0 and n_walls & W)
- or (n_cell.y == 0 and n_walls & N)
- or (n_cell.x == size.x and n_walls & E)
- or (n_cell.y == size.y and n_walls & S)
- ):
- continue
- if walls in three_walls or n_walls in three_walls:
- continue
- _set_cellv(cell, walls)
- _set_cellv(n_cell, n_walls)
- break
+ randomize()
+ const three_walls: Array[int] = [7, 11, 13, 14]
+ const two_walls: Array[int] = [3, 5, 6, 9, 10, 12]
+
+ for x in range(size.x):
+ for y in range(size.y):
+ if maze[y][x] in three_walls or maze[x][y] in two_walls or randi() % 3 == 0:
+ var cell := Vector2i(x, y)
+ var i := randi() % 4
+ for _i in range(4):
+ var n: Vector2i = cell_walls.keys()[i]
+ i = wrapi(i + _i, 0, 3)
+ if get_cellv(cell) & cell_walls[n]:
+ var n_cell := (cell + n)
+ if n_cell.x > size.x - 1 or n_cell.y > size.y - 1 or n_cell.x < 0 or n_cell.y < 0:
+ continue
+ var walls: int = get_cellv(cell) - cell_walls[n]
+ var n_walls: int = get_cellv(n_cell) - cell_walls[-n]
+ if (
+ (x == 0 and walls & W)
+ or (y == 0 and walls & N)
+ or (x == size.x and walls & E)
+ or (y == size.y and walls & S)
+ or (n_cell.x == 0 and n_walls & W)
+ or (n_cell.y == 0 and n_walls & N)
+ or (n_cell.x == size.x and n_walls & E)
+ or (n_cell.y == size.y and n_walls & S)
+ ):
+ continue
+ if walls in three_walls or n_walls in three_walls:
+ continue
+ _set_cellv(cell, walls)
+ _set_cellv(n_cell, n_walls)
+ break
func _gen_image() -> void:
- var img = Image.create(size.x * 3, size.y * 3, false, Image.FORMAT_L8)
- var position := Vector2i.ZERO
- for i in len(maze):
- for j in len(maze[i]):
- var paths := Maze.tile_4b_to_path_array(maze[i][j])
- if not paths.is_empty():
- var middle := position + Vector2i.ONE
- img.set_pixelv(middle, Color.WHITE)
- for path in paths:
- img.set_pixelv(middle + path, Color.WHITE)
- position.x += 3
- position.y += 3
- position.x = 0
- image = img
+ var img = Image.create(size.x * 3, size.y * 3, false, Image.FORMAT_L8)
+ var position := Vector2i.ZERO
+ for i in len(maze):
+ for j in len(maze[i]):
+ var paths := Maze.tile_4b_to_path_array(maze[i][j])
+ if not paths.is_empty():
+ var middle := position + Vector2i.ONE
+ img.set_pixelv(middle, Color.WHITE)
+ for path in paths:
+ img.set_pixelv(middle + path, Color.WHITE)
+ position.x += 3
+ position.y += 3
+ position.x = 0
+ image = img
diff --git a/colliders/hitbox.gd b/colliders/hitbox.gd
index 4a63e61..56cb015 100644
--- a/colliders/hitbox.gd
+++ b/colliders/hitbox.gd
@@ -6,8 +6,8 @@ class_name Hitbox
signal hit_enemy
func _on_area_entered(hurtbox: Hurtbox) -> void:
- (hurtbox.owner as Hittable).hit(damage)
- hit_enemy.emit()
+ (hurtbox.owner as Hittable).hit(damage)
+ hit_enemy.emit()
func _ready() -> void:
- area_entered.connect(_on_area_entered)
+ area_entered.connect(_on_area_entered)
diff --git a/colliders/hittable.gd b/colliders/hittable.gd
index 9a74a1e..3e75619 100644
--- a/colliders/hittable.gd
+++ b/colliders/hittable.gd
@@ -4,4 +4,4 @@ class_name Hittable
# @virtual
func hit(_damage: int) -> void:
- pass
+ pass
diff --git a/fx/dust.gd b/fx/dust.gd
index 2974472..6bc9386 100644
--- a/fx/dust.gd
+++ b/fx/dust.gd
@@ -4,4 +4,4 @@ var motion := Vector2(randf_range(-20, 20), randf_range(-10, 10))
func _process(delta: float) -> void:
- position += motion * delta
+ position += motion * delta
diff --git a/fx/enemy_death.gd b/fx/enemy_death.gd
index 0d5638a..969eaff 100644
--- a/fx/enemy_death.gd
+++ b/fx/enemy_death.gd
@@ -3,12 +3,12 @@ extends Node2D
const DustFx := preload("./dust.tscn")
func _ready() -> void:
- # print(global_position)
- randomize()
- # print_stack()
- # get_tree().paused = true
- var randv := func randv(): return Vector2(randf_range(-10, 10), randf_range(-10, 10))
- for i in range(10):
- var inst := Utils.instance_scene_on_main(DustFx, global_position + randv.call())
- if i == 9:
- inst.tree_exited.connect(queue_free)
+ # print(global_position)
+ randomize()
+ # print_stack()
+ # get_tree().paused = true
+ var randv := func randv(): return Vector2(randf_range(-10, 10), randf_range(-10, 10))
+ for i in range(10):
+ var inst := Utils.instance_scene_on_main(DustFx, global_position + randv.call())
+ if i == 9:
+ inst.tree_exited.connect(queue_free)
diff --git a/fx/trail.gd b/fx/trail.gd
index c2edb76..a2d3577 100644
--- a/fx/trail.gd
+++ b/fx/trail.gd
@@ -6,15 +6,15 @@ extends Line2D
## Enable or disable the trail
@export var emitting := true:
- set(p_emitting):
- emitting = p_emitting
- if not is_inside_tree():
- await ready
+ set(p_emitting):
+ emitting = p_emitting
+ if not is_inside_tree():
+ await ready
- if emitting:
- clear_points()
- _points_creation_time.clear()
- _last_point = to_local(target.global_position)
+ if emitting:
+ clear_points()
+ _points_creation_time.clear()
+ _last_point = to_local(target.global_position)
## Resolution. Smaller = more points
@export var resolution := 2.0
@@ -33,53 +33,53 @@ var _last_point := Vector2.ZERO
var _clock := 0.0
func _ready() -> void:
- if not target:
- target = get_parent() as Node2D
+ if not target:
+ target = get_parent() as Node2D
- joint_mode = Line2D.LINE_JOINT_BEVEL
- top_level = true
- clear_points()
- position = Vector2.ZERO
- _last_point = to_local(target.global_position)
+ joint_mode = Line2D.LINE_JOINT_BEVEL
+ top_level = true
+ clear_points()
+ position = Vector2.ZERO
+ _last_point = to_local(target.global_position)
func _process(delta: float) -> void:
- _clock += delta
- remove_older()
+ _clock += delta
+ remove_older()
- if not emitting:
- return
+ if not emitting:
+ return
- # Adding new points if necessary.
- var desired_point := (target.global_position)
- var distance: float = _last_point.distance_to(desired_point)
- if distance > resolution:
- add_timed_point(desired_point, _clock)
+ # Adding new points if necessary.
+ var desired_point := (target.global_position)
+ var distance: float = _last_point.distance_to(desired_point)
+ if distance > resolution:
+ add_timed_point(desired_point, _clock)
## Creates a new point and stores its creation time.
func add_timed_point(point: Vector2, time: float) -> void:
- add_point(point)
- _points_creation_time.append(time)
- _last_point = point
- if get_point_count() > max_points:
- remove_first_point()
+ add_point(point)
+ _points_creation_time.append(time)
+ _last_point = point
+ if get_point_count() > max_points:
+ remove_first_point()
## Removes the first point in the line and the corresponding time.
func remove_first_point() -> void:
- if get_point_count() > 1:
- remove_point(0)
- _points_creation_time.remove_at(0)
+ if get_point_count() > 1:
+ remove_point(0)
+ _points_creation_time.remove_at(0)
## Remove points older than [code]lifetime[/code].
func remove_older() -> void:
- for creation_time in _points_creation_time:
- var delta := _clock - creation_time
- if delta > lifetime:
- remove_first_point()
- # Points in `_points_creation_time` are ordered from oldest to newest so as soon as a point
- # isn't older than `lifetime`, we know all remaining points should stay as well.
- else:
- break
+ for creation_time in _points_creation_time:
+ var delta := _clock - creation_time
+ if delta > lifetime:
+ remove_first_point()
+ # Points in `_points_creation_time` are ordered from oldest to newest so as soon as a point
+ # isn't older than `lifetime`, we know all remaining points should stay as well.
+ else:
+ break
diff --git a/levels/Level.gd b/levels/Level.gd
index b035293..33dcda8 100644
--- a/levels/Level.gd
+++ b/levels/Level.gd
@@ -16,11 +16,11 @@ const ALL_DOORS := [Vector2i.UP, Vector2i.DOWN, Vector2i.LEFT, Vector2i.RIGHT]
const rot_map := {Vector2i.LEFT: PI, Vector2i.RIGHT: 0, Vector2i.DOWN: PI / 2, Vector2i.UP: -PI / 2} # 180 # 90 # -90
var completed := false:
- set(value):
- if not is_inside_tree() and value == true:
- completed = value
- else:
- push_error("no")
+ set(value):
+ if not is_inside_tree() and value == true:
+ completed = value
+ else:
+ push_error("no")
@onready var enemys := $Enemys.get_children() if not completed else []
@onready var enemyqty := enemys.size() if not completed else 0
@@ -32,63 +32,63 @@ var completed := false:
## Utility fuction to create a [Node2D]
func create_node(p_name: StringName) -> Node2D:
- var n := Node2D.new()
- n.position = Vector2.ZERO
- n.name = p_name
- add_child(n)
- return n
+ var n := Node2D.new()
+ n.position = Vector2.ZERO
+ n.name = p_name
+ add_child(n)
+ return n
func _ready():
- var wall_array := Maze.tile_4b_to_wall_array(enabled_walls)
+ var wall_array := Maze.tile_4b_to_wall_array(enabled_walls)
- if completed:
- ($Enemys as Node2D).queue_free()
- if len(wall_array) != 4:
- var door_array := Util.sub(ALL_DOORS, wall_array)
- if Vector2i.DOWN in door_array:
- var n := create_node(&"one_way_platform")
- n.position = Vector2(128, 243)
- var p: OneWayPlatform = OneWayPlatform_scn.instantiate()
- n.call_deferred(&"add_child", p)
+ if completed:
+ ($Enemys as Node2D).queue_free()
+ if len(wall_array) != 4:
+ var door_array := Util.sub(ALL_DOORS, wall_array)
+ if Vector2i.DOWN in door_array:
+ var n := create_node(&"one_way_platform")
+ n.position = Vector2(128, 243)
+ var p: OneWayPlatform = OneWayPlatform_scn.instantiate()
+ n.call_deferred(&"add_child", p)
- if has_enemys:
- blockdoors = create_node(&"block_doors")
+ if has_enemys:
+ blockdoors = create_node(&"block_doors")
- for door_p in door_array:
- var door := add_door(door_p)
- if has_enemys:
- add_block_door(door)
+ for door_p in door_array:
+ var door := add_door(door_p)
+ if has_enemys:
+ add_block_door(door)
- for enemy in enemys:
- enemy.died.connect(_on_enemy_died)
+ for enemy in enemys:
+ enemy.died.connect(_on_enemy_died)
## Add a [Door] for given direction.
func add_door(dir: Vector2i) -> Door:
- var d := Door_scn.instantiate()
- var v := Vector2i(128, 128) # center
- d.rotation = rot_map[dir]
- d.position = Vector2(v + (v * dir)).move_toward(v, 16)
- d.dir = dir
- doors.add_child(d)
- return d
+ var d := Door_scn.instantiate()
+ var v := Vector2i(128, 128) # center
+ d.rotation = rot_map[dir]
+ d.position = Vector2(v + (v * dir)).move_toward(v, 16)
+ d.dir = dir
+ doors.add_child(d)
+ return d
## Add a [BlockDoor] on top of a [Door]
func add_block_door(door: Door) -> BlockDoor:
- var d := BlockDoor_scn.instantiate()
- d.rotation = door.rotation
- d.position = door.position.move_toward(Vector2(128, 128), -8)
- blockdoors.add_child(d)
- return d
+ var d := BlockDoor_scn.instantiate()
+ d.rotation = door.rotation
+ d.position = door.position.move_toward(Vector2(128, 128), -8)
+ blockdoors.add_child(d)
+ return d
func _on_enemy_died() -> void:
- enemyqty -= 1
- if enemyqty == 0:
- open_doors()
+ enemyqty -= 1
+ if enemyqty == 0:
+ open_doors()
## Opens all doors
func open_doors() -> void:
- var block_doors := blockdoors.get_children()
- for bloc_door in block_doors:
- bloc_door.open()
+ var block_doors := blockdoors.get_children()
+ for bloc_door in block_doors:
+ bloc_door.open()
diff --git a/levels/LevelManager.gd b/levels/LevelManager.gd
index 02e3816..45bf640 100644
--- a/levels/LevelManager.gd
+++ b/levels/LevelManager.gd
@@ -32,36 +32,36 @@ var t: SceneTreeTimer
var sorted := [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
func _init() -> void:
- Globals.levelmanager = self
+ Globals.levelmanager = self
func _exit_tree() -> void:
- Globals.levelmanager = null
+ Globals.levelmanager = null
func _ready() -> void:
- gen_map()
- lvl_position = size / 2
- Events.change_level.connect(go)
- print_map_pretty()
+ gen_map()
+ lvl_position = size / 2
+ Events.change_level.connect(go)
+ print_map_pretty()
## Goes to the next room in [param to] direction.
func go(to: Vector2i) -> void:
- completed_levels.append(lvl_position)
- if t and t.time_left > 0:
- print("skipping door enter")
- return
- t = get_tree().create_timer(0.1)
- lvl_position += to
- current_level.queue_free()
- current_level = map[lvl_position.y][lvl_position.x].instantiate() as TileMap
- var v := Vector2i(128, 128) # center
- player.position = Vector2(v - (v * to)).move_toward(v, 24)
- player.velocity = Vector2.ZERO
- main.call_deferred(&"add_child", current_level)
- if lvl_position in completed_levels:
- current_level.completed = true
- prints("welcome back to", current_level.name)
- else:
- prints("welcome to", current_level.name)
+ completed_levels.append(lvl_position)
+ if t and t.time_left > 0:
+ print("skipping door enter")
+ return
+ t = get_tree().create_timer(0.1)
+ lvl_position += to
+ current_level.queue_free()
+ current_level = map[lvl_position.y][lvl_position.x].instantiate() as TileMap
+ var v := Vector2i(128, 128) # center
+ player.position = Vector2(v - (v * to)).move_toward(v, 24)
+ player.velocity = Vector2.ZERO
+ main.call_deferred(&"add_child", current_level)
+ if lvl_position in completed_levels:
+ current_level.completed = true
+ prints("welcome back to", current_level.name)
+ else:
+ prints("welcome to", current_level.name)
## Prints out the map prettily.
## eg: [codeblock]
@@ -73,32 +73,32 @@ func go(to: Vector2i) -> void:
## 15 08 07 08 07 09
## [/codeblock]
func print_map_pretty() -> void:
- var string := ""
- for row in map:
- for item in row:
- string += str(item.get_state().get_node_name(0)).substr(0, 2) + " "
- string += "\n"
- print(string)
+ var string := ""
+ for row in map:
+ for item in row:
+ string += str(item.get_state().get_node_name(0)).substr(0, 2) + " "
+ string += "\n"
+ print(string)
## Split levels into [url=https://kidscancode.org/blog/img/cells_4bit.png]4bit wall[/url] groups.
func sort_levels():
- for level in levels:
- # property idx 1 is the enabled walls
- # if prop is not overriden, default to 0
- var n: int = 0 if level.get_state().get_node_property_count(0) == 1 else level.get_state().get_node_property_value(0, 1)
- sorted[n].append(level)
+ for level in levels:
+ # property idx 1 is the enabled walls
+ # if prop is not overriden, default to 0
+ var n: int = 0 if level.get_state().get_node_property_count(0) == 1 else level.get_state().get_node_property_value(0, 1)
+ sorted[n].append(level)
## Generates the maze.
func gen_map() -> void:
- sort_levels()
- maze = Maze.new(size)
- maze.image.save_png("res://maze.png")
- lvl_position = size / 2
- map.clear()
- for row in maze.maze:
- var map_row: Array[PackedScene] = []
- for i in row:
- map_row.append(sorted[i][randi() % len(sorted[i])])
- map.append(map_row)
- map[lvl_position.x][lvl_position.y] = start
- world_generated.emit(maze)
+ sort_levels()
+ maze = Maze.new(size)
+ maze.image.save_png("res://maze.png")
+ lvl_position = size / 2
+ map.clear()
+ for row in maze.maze:
+ var map_row: Array[PackedScene] = []
+ for i in row:
+ map_row.append(sorted[i][randi() % len(sorted[i])])
+ map.append(map_row)
+ map[lvl_position.x][lvl_position.y] = start
+ world_generated.emit(maze)
diff --git a/levels/Start.gd b/levels/Start.gd
index 0f9f251..ec8c441 100644
--- a/levels/Start.gd
+++ b/levels/Start.gd
@@ -1,20 +1,20 @@
extends Level
func _ready() -> void:
- var lm: LevelManager = Globals.levelmanager
- var maze: Maze = lm.maze
- if !maze:
- maze = await lm.world_generated
- enabled_walls = (maze.get_cellv(lm.size / 2))
- const wm := {
- Vector2i.UP: [Vector2i(7, 0), Vector2i(8, 0)],
- Vector2i.DOWN: [Vector2i(7, 15), Vector2i(8, 15)],
- Vector2i.LEFT: [Vector2i(0, 7), Vector2i(0, 8)],
- Vector2i.RIGHT: [Vector2i(15, 7), Vector2i(15, 8)]
- }
- var terrain: Array[Vector2i] = []
- for wall in Maze.tile_4b_to_wall_array(enabled_walls):
- terrain.append_array(wm[wall])
- set_cells_terrain_connect(0, terrain, 0, 0, true)
- super()
+ var lm: LevelManager = Globals.levelmanager
+ var maze: Maze = lm.maze
+ if !maze:
+ maze = await lm.world_generated
+ enabled_walls = (maze.get_cellv(lm.size / 2))
+ const wm := {
+ Vector2i.UP: [Vector2i(7, 0), Vector2i(8, 0)],
+ Vector2i.DOWN: [Vector2i(7, 15), Vector2i(8, 15)],
+ Vector2i.LEFT: [Vector2i(0, 7), Vector2i(0, 8)],
+ Vector2i.RIGHT: [Vector2i(15, 7), Vector2i(15, 8)]
+ }
+ var terrain: Array[Vector2i] = []
+ for wall in Maze.tile_4b_to_wall_array(enabled_walls):
+ terrain.append_array(wm[wall])
+ set_cells_terrain_connect(0, terrain, 0, 0, true)
+ super()
diff --git a/ui/components/aim/aim.gd b/ui/components/aim/aim.gd
index 4fdaf6c..c858fec 100644
--- a/ui/components/aim/aim.gd
+++ b/ui/components/aim/aim.gd
@@ -13,29 +13,29 @@ var cancel_left_time := cancel_time
@export var arrow: Line2D
@export var enabled := true:
- set(p_e):
- enabled = p_e
- set_process(enabled)
+ set(p_e):
+ enabled = p_e
+ set_process(enabled)
func _ready() -> void:
- enabled = enabled # trigger the setter
+ enabled = enabled # trigger the setter
func _process(delta: float) -> void:
- var v := Vector2(Input.get_axis(&"left", &"right"), Input.get_axis(&"up", &"down"))
- if Input.is_action_pressed("ui_cancel"):
- cancel_left_time = cancel_time
- cancel.emit()
- return
- if v.is_zero_approx():
- v.x = Globals.player.sprite.scale.x # default to current facing direction
- elif Util.is_in_range(v.y, 0.9, 1) and Util.is_in_range(v.x, -0.1, 0.1) and Globals.player.is_on_floor():
- cancel_left_time -= delta
- if cancel_left_time < 0:
- cancel_left_time = cancel_time
- cancel.emit()
- return
- var angle := v.angle()
- current_rotation = angle
- arrow.rotation = angle
- if Input.is_action_just_released(&"throw"):
- throw.emit(angle)
+ var v := Vector2(Input.get_axis(&"left", &"right"), Input.get_axis(&"up", &"down"))
+ if Input.is_action_pressed("ui_cancel"):
+ cancel_left_time = cancel_time
+ cancel.emit()
+ return
+ if v.is_zero_approx():
+ v.x = Globals.player.sprite.scale.x # default to current facing direction
+ elif Util.is_in_range(v.y, 0.9, 1) and Util.is_in_range(v.x, -0.1, 0.1) and Globals.player.is_on_floor():
+ cancel_left_time -= delta
+ if cancel_left_time < 0:
+ cancel_left_time = cancel_time
+ cancel.emit()
+ return
+ var angle := v.angle()
+ current_rotation = angle
+ arrow.rotation = angle
+ if Input.is_action_just_released(&"throw"):
+ throw.emit(angle)
diff --git a/ui/components/caretoptionbutton/caretoptionbutton.gd b/ui/components/caretoptionbutton/caretoptionbutton.gd
index b46ef1b..bcfbba6 100644
--- a/ui/components/caretoptionbutton/caretoptionbutton.gd
+++ b/ui/components/caretoptionbutton/caretoptionbutton.gd
@@ -6,17 +6,17 @@ signal changed(current_option: int)
@onready var button: Button = $button as Button
@export var options: PackedStringArray = []
@export var current_option: int = 0:
- set(val):
- current_option = wrapi(val, 0, len(options))
- if not button: return
- button.text = options[current_option]
- changed.emit(current_option)
+ set(val):
+ current_option = wrapi(val, 0, len(options))
+ if not button: return
+ button.text = options[current_option]
+ changed.emit(current_option)
func _ready() -> void:
- current_option = current_option
+ current_option = current_option
func sub() -> void:
- current_option -= 1
+ current_option -= 1
func add() -> void:
- current_option += 1
+ current_option += 1
diff --git a/ui/graphics.gd b/ui/graphics.gd
index 3bec0e1..15c7de0 100644
--- a/ui/graphics.gd
+++ b/ui/graphics.gd
@@ -5,12 +5,12 @@ const SaveLoad := preload("res://addons/remap/private/SaveLoadUtils.gd") # so wh
enum {FULLSCREEN, BORDERLESS_FS, WINDOWED}
const map := {
- FULLSCREEN: DisplayServer.WINDOW_MODE_FULLSCREEN,
- WINDOWED: DisplayServer.WINDOW_MODE_WINDOWED,
+ FULLSCREEN: DisplayServer.WINDOW_MODE_FULLSCREEN,
+ WINDOWED: DisplayServer.WINDOW_MODE_WINDOWED,
}
const default_settings_data := {
- window = WINDOWED,
- vsync = false,
+ window = WINDOWED,
+ vsync = false,
}
@onready var vsync: CheckBox = $"%vsyncbutton"
@@ -22,41 +22,41 @@ var has_loaded := false
var settings := default_settings_data
func save() -> void:
- SaveLoad.save(file, settings)
+ SaveLoad.save(file, settings)
func _ready() -> void:
- var lod := SaveLoad.load_file(file)
- settings = lod if Util.dict_cmp(lod, default_settings_data) else default_settings_data # check if the keys and vaue types are correct
- has_loaded = true
- update_button_visuals()
+ var lod := SaveLoad.load_file(file)
+ settings = lod if Util.dict_cmp(lod, default_settings_data) else default_settings_data # check if the keys and vaue types are correct
+ has_loaded = true
+ update_button_visuals()
func update_button_visuals():
- ignore_set_settings = true
- vsync.button_pressed = settings.vsync
- window.current_option = settings.window
- ignore_set_settings = false
+ ignore_set_settings = true
+ vsync.button_pressed = settings.vsync
+ window.current_option = settings.window
+ ignore_set_settings = false
func update_window():
- if settings.window == BORDERLESS_FS:
- DisplayServer.window_set_mode(map[FULLSCREEN])
- DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
- else:
- DisplayServer.window_set_mode(map[settings.window])
+ if settings.window == BORDERLESS_FS:
+ DisplayServer.window_set_mode(map[FULLSCREEN])
+ DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_BORDERLESS, true)
+ else:
+ DisplayServer.window_set_mode(map[settings.window])
func update_vsync():
- var vsync_mode := DisplayServer.VSYNC_DISABLED if not settings.vsync else DisplayServer.VSYNC_ENABLED
- DisplayServer.window_set_vsync_mode(vsync_mode)
+ var vsync_mode := DisplayServer.VSYNC_DISABLED if not settings.vsync else DisplayServer.VSYNC_ENABLED
+ DisplayServer.window_set_vsync_mode(vsync_mode)
func _on_vsync_toggled(button_pressed: bool) -> void:
- if not has_loaded: return
- if not ignore_set_settings:
- settings.vsync = button_pressed
- save()
- update_vsync()
+ if not has_loaded: return
+ if not ignore_set_settings:
+ settings.vsync = button_pressed
+ save()
+ update_vsync()
func _on_window_mode_changed(current_option: int) -> void:
- if not has_loaded: return
- if not ignore_set_settings:
- settings.window = current_option
- save()
- update_window()
+ if not has_loaded: return
+ if not ignore_set_settings:
+ settings.window = current_option
+ save()
+ update_window()
diff --git a/ui/popup.gd b/ui/popup.gd
index 5620f27..165bfa7 100644
--- a/ui/popup.gd
+++ b/ui/popup.gd
@@ -8,17 +8,17 @@ signal close
@export var focus: Control
func open() -> void:
- show()
- if focus is RemapButton:
- focus.button.grab_focus()
- else:
- focus.grab_focus()
+ show()
+ if focus is RemapButton:
+ focus.button.grab_focus()
+ else:
+ focus.grab_focus()
func _unhandled_input(event: InputEvent) -> void:
- if visible and event.is_action("ui_cancel"):
- accept_event()
- exit()
+ if visible and event.is_action("ui_cancel"):
+ accept_event()
+ exit()
func exit() -> void:
- close.emit()
- hide()
+ close.emit()
+ hide()
diff --git a/world/one_way_platform.gd b/world/one_way_platform.gd
index eb69c2f..e3faaa8 100644
--- a/world/one_way_platform.gd
+++ b/world/one_way_platform.gd
@@ -4,5 +4,5 @@ class_name OneWayPlatform
@onready @export var shape: CollisionShape2D
func _input(event: InputEvent) -> void:
- if event.is_action("down") and shape.disabled == not event.is_pressed():
- shape.set_deferred("disabled", event.is_pressed())
+ if event.is_action("down") and shape.disabled == not event.is_pressed():
+ shape.set_deferred("disabled", event.is_pressed())