diff --git a/Scenes/main.tscn b/Scenes/main.tscn index dbec0f2..6a03a81 100644 --- a/Scenes/main.tscn +++ b/Scenes/main.tscn @@ -49,5 +49,4 @@ offset_top = 173.0 offset_right = 812.0 offset_bottom = 475.0 -[connection signal="area_exited" from="Level" to="SnakePart" method="_on_level_area_exited"] [connection signal="timeout" from="RestartTimer" to="Timer" method="start" binds= [0.3]] diff --git a/Scripts/game_over_menu.gd b/Scripts/game_over_menu.gd index d9fe7d0..9e4a61b 100644 --- a/Scripts/game_over_menu.gd +++ b/Scripts/game_over_menu.gd @@ -1,6 +1,6 @@ extends VBoxContainer -var level : PackedScene = load("res://Scenes/main.tscn") +#var level : PackedScene = load("res://Scenes/main.tscn") var main_menu : PackedScene = load("res://Scenes/main_menu.tscn") @onready var score_label : Label = $FinalScore @@ -10,7 +10,7 @@ func update_score() -> void: score_label.text = "Final Score\n{score}".format(GameManager) func restart(): - get_tree().change_scene_to_packed(level) + get_tree().change_scene_to_packed(load("res://Scenes/main.tscn")) func back(): get_tree().change_scene_to_packed(main_menu) diff --git a/Scripts/snake_part.gd b/Scripts/snake_part.gd index e4112df..77f919f 100644 --- a/Scripts/snake_part.gd +++ b/Scripts/snake_part.gd @@ -8,13 +8,15 @@ enum States {ALIVE, DEAD, OUROBOROS, OLD_OUROBOROS} var part_type : PartTypes = PartTypes.HEAD var state : States = States.ALIVE var current_direction : Vector2 = Vector2.RIGHT +var old_direction : Vector2 = Vector2.RIGHT var inputs : Dictionary[String, Vector2] = {"right": Vector2.RIGHT, "left": Vector2.LEFT, "up": Vector2.UP, "down": Vector2.DOWN} - +var possible_x : Array +var possible_y : Array @onready var raycast_right : RayCast2D = $RightRayCast2D @@ -34,11 +36,23 @@ var timer_ref : Timer = $"../Timer" @onready var game_over_menu : VBoxContainer = get_tree().get_first_node_in_group("GameOverMenu") +@onready +var sprite : Sprite2D = $Sprite2D + +var image_head : CompressedTexture2D = preload("res://Sprites/snake_head.png") +var image_head_dead : CompressedTexture2D = preload("res://Sprites/snake_head_dead.png") +var image_head_ouroboros : CompressedTexture2D = preload("res://Sprites/snake_head_ouroboros.png") +var image_left : CompressedTexture2D = preload("res://Sprites/snake_left.png") +var image_right : CompressedTexture2D = preload("res://Sprites/snake_right.png") +var image_straight : CompressedTexture2D = preload("res://Sprites/snake_straight.png") +var image_tail : CompressedTexture2D = preload("res://Sprites/snake_tail.png") + var next_part : SnakePart = null +var commanding_head : SnakePart = null var skip_next_move_propagation : bool = false var queued_growth : int = 0 -signal on_movement(new_dir) +signal on_movement(new_dir, prevent_move) signal on_death signal on_ouroboros @@ -48,10 +62,21 @@ func _ready() -> void: # Add to group for easy access from other nodes add_to_group("Head") + # Work out allowed positions + + # Determine the level limits + var level : Area2D = get_tree().get_first_node_in_group("Level") + var x_bounds : Vector2 = level.position.x * Vector2.ONE + Vector2(-TILE_SIZE, TILE_SIZE) * level.scale.x / 2 + var y_bounds : Vector2 = level.position.y * Vector2.ONE + Vector2(-TILE_SIZE, TILE_SIZE) * level.scale.y / 2 + + # Determine the possible x and y coordinates + possible_x = range(x_bounds.x, x_bounds.y, TILE_SIZE) + possible_y = range(y_bounds.x, y_bounds.y, TILE_SIZE) + # Attach clock var timer : Node = get_tree().get_first_node_in_group("GameClock") if timer is Timer: - timer.timeout.connect(process_movement.bind(Vector2.ZERO)) + timer.timeout.connect(process_movement.bind(Vector2.ZERO, false)) # Set up a body part var body = snake_part_obj.instantiate() @@ -72,6 +97,7 @@ func _ready() -> void: body.on_movement.connect(tail.process_movement) on_death.connect(tail.lose_game) on_ouroboros.connect(tail.ouroboros) + tail.commanding_head = self else: # Free raycasts if we don't need them (consider only loading them in for the head for performance if needed) @@ -133,7 +159,7 @@ func check_position_for_snake(query_position : Vector2) -> bool: return true return false -func process_movement(new_direction : Vector2) -> void: +func process_movement(new_direction : Vector2, prevent_movment : bool = false) -> void: # Only alive snakes can move if state != States.ALIVE: @@ -142,27 +168,75 @@ func process_movement(new_direction : Vector2) -> void: # The head needs to check if we are about to collide with something if part_type == PartTypes.HEAD: check_movement() - if queued_growth: + if queued_growth and state == States.ALIVE: extend() # Only alive snakes can move + update_sprite() if state != States.ALIVE: return # Update the position of this part - position = (position + current_direction * TILE_SIZE).snapped(Vector2.ONE * TILE_SIZE) + if !prevent_movment: + position = (position + current_direction * TILE_SIZE).snapped(Vector2.ONE * TILE_SIZE) # Tell the next part to move and give it the direction we are moving - if !skip_next_move_propagation: - on_movement.emit(current_direction) + on_movement.emit(current_direction, prevent_movment or skip_next_move_propagation) skip_next_move_propagation = false # Unless we are the head, change our direction to the direction given - if new_direction != Vector2.ZERO: + if !prevent_movment: + old_direction = current_direction + if new_direction != Vector2.ZERO and !prevent_movment: current_direction = new_direction + + # Update the sprite + update_sprite() + +func update_sprite() -> void: + + # Set the sprite based on state and part type + match part_type: + PartTypes.HEAD: + match state: + States.ALIVE: + sprite.texture = image_head + States.DEAD: + sprite.texture = image_head_dead + _: + sprite.texture = image_head_ouroboros + PartTypes.TAIL: + if state == States.OUROBOROS or state == States.OLD_OUROBOROS: + var tail_rel_direction : float = current_direction.angle_to(position - commanding_head.position) + if abs(tail_rel_direction) < 0.1: + sprite.texture = image_straight + elif tail_rel_direction > 0: + sprite.texture = image_left + elif tail_rel_direction < 0: + sprite.texture = image_right + else: + sprite.texture = image_tail + PartTypes.BODY: + var tail_rel_direction : float = current_direction.angle_to(old_direction) + if abs(tail_rel_direction) < 0.1: + sprite.texture = image_straight + elif tail_rel_direction > 0: + sprite.texture = image_left + elif tail_rel_direction < 0: + sprite.texture = image_right + + if current_direction != Vector2.ZERO: + sprite.rotation = current_direction.angle() + PI / 2 + else: + sprite.rotation = old_direction.angle() + PI / 2 func check_movement() -> void: + # Make sure we are going to stay in the arena + var new_position : Vector2 = (position + current_direction * TILE_SIZE).snapped(Vector2.ONE * TILE_SIZE) + if not int(new_position.x) in possible_x or not int(new_position.y) in possible_y: + lose_game() + # Get the correct raycast for the direction we are moving var raycast_to_use : RayCast2D if current_direction == Vector2.RIGHT: @@ -213,6 +287,7 @@ func extend() -> void: # Set direction of new part new_body.current_direction = current_direction + new_body.old_direction = old_direction # Update reference to next part next_part = new_body @@ -224,20 +299,22 @@ func extend() -> void: queued_growth -= 1 -func lose_game() -> void: +func lose_game(from_lack_of_space : bool = false) -> void: # You lose! print("Game lost") - state = States.DEAD - on_death.emit() + if !from_lack_of_space: + state = States.DEAD + on_death.emit() game_over_menu.visible = true func ouroboros() -> void: - print("You have achieved the ouroboros!") if state == States.OUROBOROS: state = States.OLD_OUROBOROS elif state == States.ALIVE: state = States.OUROBOROS + if part_type == PartTypes.TAIL: + update_sprite() on_ouroboros.emit() # The head can spawn a new snake @@ -282,7 +359,7 @@ func spawn_new_snake() -> void: # If there is no room to spawn a snake, we lose if spawn_positions.is_empty(): - lose_game() + lose_game(true) return # Pick a position @@ -304,5 +381,5 @@ func _unhandled_input(event: InputEvent) -> void: # If we leave the arena -func _on_level_area_exited(_area: Area2D) -> void: - lose_game() +#func _on_level_area_exited(_area: Area2D) -> void: + #lose_game() diff --git a/Sprites/snake_head.kra b/Sprites/snake_head.kra new file mode 100644 index 0000000..608de87 Binary files /dev/null and b/Sprites/snake_head.kra differ diff --git a/Sprites/snake_head.kra~ b/Sprites/snake_head.kra~ new file mode 100644 index 0000000..74571cd Binary files /dev/null and b/Sprites/snake_head.kra~ differ diff --git a/Sprites/snake_head.png b/Sprites/snake_head.png new file mode 100644 index 0000000..b67f7e8 Binary files /dev/null and b/Sprites/snake_head.png differ diff --git a/Sprites/snake_head.png.import b/Sprites/snake_head.png.import new file mode 100644 index 0000000..9336ee3 --- /dev/null +++ b/Sprites/snake_head.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://djqg2n4n81gqj" +path="res://.godot/imported/snake_head.png-d9b790ba6d57ab17f6536c547f091446.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/snake_head.png" +dest_files=["res://.godot/imported/snake_head.png-d9b790ba6d57ab17f6536c547f091446.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Sprites/snake_head_dead.kra b/Sprites/snake_head_dead.kra new file mode 100644 index 0000000..bc8ebd1 Binary files /dev/null and b/Sprites/snake_head_dead.kra differ diff --git a/Sprites/snake_head_dead.kra~ b/Sprites/snake_head_dead.kra~ new file mode 100644 index 0000000..242c32f Binary files /dev/null and b/Sprites/snake_head_dead.kra~ differ diff --git a/Sprites/snake_head_dead.png b/Sprites/snake_head_dead.png new file mode 100644 index 0000000..719d1ee Binary files /dev/null and b/Sprites/snake_head_dead.png differ diff --git a/Sprites/snake_head_dead.png.import b/Sprites/snake_head_dead.png.import new file mode 100644 index 0000000..bf6288a --- /dev/null +++ b/Sprites/snake_head_dead.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bm1cbd5uf6tlq" +path="res://.godot/imported/snake_head_dead.png-e3c3b818ce7ed644b9a37e714866ea73.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/snake_head_dead.png" +dest_files=["res://.godot/imported/snake_head_dead.png-e3c3b818ce7ed644b9a37e714866ea73.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Sprites/snake_head_dead.png~ b/Sprites/snake_head_dead.png~ new file mode 100644 index 0000000..6e7938b Binary files /dev/null and b/Sprites/snake_head_dead.png~ differ diff --git a/Sprites/snake_head_ouroboros.kra b/Sprites/snake_head_ouroboros.kra new file mode 100644 index 0000000..2388174 Binary files /dev/null and b/Sprites/snake_head_ouroboros.kra differ diff --git a/Sprites/snake_head_ouroboros.kra~ b/Sprites/snake_head_ouroboros.kra~ new file mode 100644 index 0000000..672e2a8 Binary files /dev/null and b/Sprites/snake_head_ouroboros.kra~ differ diff --git a/Sprites/snake_head_ouroboros.png b/Sprites/snake_head_ouroboros.png new file mode 100644 index 0000000..a283efc Binary files /dev/null and b/Sprites/snake_head_ouroboros.png differ diff --git a/Sprites/snake_head_ouroboros.png.import b/Sprites/snake_head_ouroboros.png.import new file mode 100644 index 0000000..e997d08 --- /dev/null +++ b/Sprites/snake_head_ouroboros.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://f31d1vxf6kdv" +path="res://.godot/imported/snake_head_ouroboros.png-880dd7bcf916adb92d621a92cede4944.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/snake_head_ouroboros.png" +dest_files=["res://.godot/imported/snake_head_ouroboros.png-880dd7bcf916adb92d621a92cede4944.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Sprites/snake_left.kra b/Sprites/snake_left.kra new file mode 100644 index 0000000..20f4a36 Binary files /dev/null and b/Sprites/snake_left.kra differ diff --git a/Sprites/snake_left.kra~ b/Sprites/snake_left.kra~ new file mode 100644 index 0000000..156d578 Binary files /dev/null and b/Sprites/snake_left.kra~ differ diff --git a/Sprites/snake_left.png b/Sprites/snake_left.png new file mode 100644 index 0000000..a5e7af2 Binary files /dev/null and b/Sprites/snake_left.png differ diff --git a/Sprites/snake_left.png.import b/Sprites/snake_left.png.import new file mode 100644 index 0000000..7b805b5 --- /dev/null +++ b/Sprites/snake_left.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b5lwghfk2spid" +path="res://.godot/imported/snake_left.png-badd0667030f5f0cf0ee9e32fe23f909.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/snake_left.png" +dest_files=["res://.godot/imported/snake_left.png-badd0667030f5f0cf0ee9e32fe23f909.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Sprites/snake_left.png~ b/Sprites/snake_left.png~ new file mode 100644 index 0000000..cffc014 Binary files /dev/null and b/Sprites/snake_left.png~ differ diff --git a/Sprites/snake_right.kra b/Sprites/snake_right.kra new file mode 100644 index 0000000..5576072 Binary files /dev/null and b/Sprites/snake_right.kra differ diff --git a/Sprites/snake_right.kra~ b/Sprites/snake_right.kra~ new file mode 100644 index 0000000..424c43a Binary files /dev/null and b/Sprites/snake_right.kra~ differ diff --git a/Sprites/snake_right.png b/Sprites/snake_right.png new file mode 100644 index 0000000..2a9e7d0 Binary files /dev/null and b/Sprites/snake_right.png differ diff --git a/Sprites/snake_right.png.import b/Sprites/snake_right.png.import new file mode 100644 index 0000000..fc4c488 --- /dev/null +++ b/Sprites/snake_right.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bvg583s86j3ca" +path="res://.godot/imported/snake_right.png-06790ccfafebd89ea6cb77e5510b3ad6.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/snake_right.png" +dest_files=["res://.godot/imported/snake_right.png-06790ccfafebd89ea6cb77e5510b3ad6.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Sprites/snake_right.png~ b/Sprites/snake_right.png~ new file mode 100644 index 0000000..13385b0 Binary files /dev/null and b/Sprites/snake_right.png~ differ diff --git a/Sprites/snake_straight.kra b/Sprites/snake_straight.kra new file mode 100644 index 0000000..0e066f7 Binary files /dev/null and b/Sprites/snake_straight.kra differ diff --git a/Sprites/snake_straight.kra~ b/Sprites/snake_straight.kra~ new file mode 100644 index 0000000..9aa3945 Binary files /dev/null and b/Sprites/snake_straight.kra~ differ diff --git a/Sprites/snake_straight.png b/Sprites/snake_straight.png new file mode 100644 index 0000000..83d611c Binary files /dev/null and b/Sprites/snake_straight.png differ diff --git a/Sprites/snake_straight.png.import b/Sprites/snake_straight.png.import new file mode 100644 index 0000000..fa661a2 --- /dev/null +++ b/Sprites/snake_straight.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0can5myhke8s" +path="res://.godot/imported/snake_straight.png-afe959d90748ce7a63c1d2cc542b0007.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/snake_straight.png" +dest_files=["res://.godot/imported/snake_straight.png-afe959d90748ce7a63c1d2cc542b0007.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Sprites/snake_straight.png~ b/Sprites/snake_straight.png~ new file mode 100644 index 0000000..93ab422 Binary files /dev/null and b/Sprites/snake_straight.png~ differ diff --git a/Sprites/snake_tail.kra b/Sprites/snake_tail.kra new file mode 100644 index 0000000..099bf17 Binary files /dev/null and b/Sprites/snake_tail.kra differ diff --git a/Sprites/snake_tail.png b/Sprites/snake_tail.png new file mode 100644 index 0000000..52d5d5f Binary files /dev/null and b/Sprites/snake_tail.png differ diff --git a/Sprites/snake_tail.png.import b/Sprites/snake_tail.png.import new file mode 100644 index 0000000..feda0af --- /dev/null +++ b/Sprites/snake_tail.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dkbr22xkxksaf" +path="res://.godot/imported/snake_tail.png-86597c4ec7b604cdaa9ee2880ddc84b9.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Sprites/snake_tail.png" +dest_files=["res://.godot/imported/snake_tail.png-86597c4ec7b604cdaa9ee2880ddc84b9.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1