diff --git a/scenes/game_control.tscn b/scenes/game_control.tscn new file mode 100644 index 0000000..ed845a1 --- /dev/null +++ b/scenes/game_control.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=3 format=3 uid="uid://c2qpcf4un5wgv"] + +[ext_resource type="Script" path="res://scripts/game_control.gd" id="1_0xttm"] +[ext_resource type="Theme" uid="uid://dlygxgt8hfakm" path="res://pixel_theme.tres" id="1_23hjq"] + +[node name="Control" type="Control"] +layout_mode = 3 +anchor_right = 0.057 +anchor_bottom = 0.088 +offset_top = 1.0 +offset_right = 0.335999 +offset_bottom = -0.0240059 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_0xttm") + +[node name="MenuButton" type="Button" parent="."] +layout_mode = 0 +offset_left = 10.0 +offset_top = 9.0 +offset_right = 102.0 +offset_bottom = 43.0 +scale = Vector2(0.5, 0.5) +focus_mode = 0 +theme = ExtResource("1_23hjq") +theme_override_font_sizes/font_size = 26 +action_mode = 0 +text = "Menu" + +[node name="RestartButton" type="Button" parent="."] +layout_mode = 0 +offset_left = 10.0 +offset_top = 29.0 +offset_right = 102.0 +offset_bottom = 63.0 +scale = Vector2(0.5, 0.5) +focus_mode = 0 +theme = ExtResource("1_23hjq") +theme_override_font_sizes/font_size = 26 +action_mode = 0 +text = "Restart" + +[connection signal="pressed" from="MenuButton" to="." method="_on_menu_button_pressed"] +[connection signal="pressed" from="RestartButton" to="." method="_on_restart_button_pressed"] diff --git a/scenes/game_snake.tscn b/scenes/game_snake.tscn index bdba498..1cdfb72 100644 --- a/scenes/game_snake.tscn +++ b/scenes/game_snake.tscn @@ -1,15 +1,29 @@ -[gd_scene load_steps=7 format=3 uid="uid://dmwdah80guhrt"] +[gd_scene load_steps=12 format=3 uid="uid://dmwdah80guhrt"] [ext_resource type="Texture2D" uid="uid://cr8rakanl4m66" path="res://assets/snake.png" id="1_fd47j"] +[ext_resource type="Script" path="res://scripts/game_snake.gd" id="1_tfb5x"] [ext_resource type="PackedScene" uid="uid://bihvgleiqyjpt" path="res://scenes/snake_head.tscn" id="2_ugn0y"] [ext_resource type="Script" path="res://scripts/snake_head.gd" id="3_ppvnp"] [ext_resource type="PackedScene" uid="uid://bxpoy2277fyov" path="res://scenes/snake_segment.tscn" id="4_ja3ss"] [ext_resource type="PackedScene" uid="uid://xtxoqxqu3ycg" path="res://scenes/snake_food.tscn" id="6_hib7g"] +[ext_resource type="Theme" uid="uid://dlygxgt8hfakm" path="res://pixel_theme.tres" id="7_8hc3g"] +[ext_resource type="FontFile" uid="uid://bvlg0bt6ugohe" path="res://assets/fonts/SummerPixel22Regular-jE0W7.ttf" id="8_lv7pa"] +[ext_resource type="PackedScene" uid="uid://c2qpcf4un5wgv" path="res://scenes/game_control.tscn" id="9_tugdq"] [sub_resource type="CircleShape2D" id="CircleShape2D_aawv3"] radius = 1.0 +[sub_resource type="LabelSettings" id="LabelSettings_c3csw"] +font = ExtResource("8_lv7pa") +font_size = 13 +font_color = Color(0, 0, 0, 1) +shadow_size = 0 +shadow_color = Color(1, 1, 1, 0.278431) +shadow_offset = Vector2(0, 1) + [node name="Node" type="Node"] +script = ExtResource("1_tfb5x") +snake_food_scene = ExtResource("6_hib7g") [node name="ColorRect" type="ColorRect" parent="."] offset_left = -426.0 @@ -18,11 +32,11 @@ offset_right = 424.0 offset_bottom = 266.0 color = Color(0.623529, 0.721569, 0.223529, 1) -[node name="NinePatchRect" type="NinePatchRect" parent="."] -offset_left = -115.0 -offset_top = -66.0 -offset_right = 122.0 -offset_bottom = 70.0 +[node name="Bounds" type="NinePatchRect" parent="."] +offset_left = -32.0 +offset_top = -32.0 +offset_right = 32.0 +offset_bottom = 32.0 texture = ExtResource("1_fd47j") draw_center = false region_rect = Rect2(16, 16, 4, 4) @@ -49,12 +63,6 @@ autostart = true [node name="CollisionShape2D" type="CollisionShape2D" parent="SnakeHead/Area2D"] shape = SubResource("CircleShape2D_aawv3") -[node name="SnakeFood" parent="." instance=ExtResource("6_hib7g")] -position = Vector2(0, -24) - -[node name="SnakeFood2" parent="." instance=ExtResource("6_hib7g")] -position = Vector2(0, -51) - [node name="Body" parent="." node_paths=PackedStringArray("next") instance=ExtResource("4_ja3ss")] next = NodePath("../Tail") @@ -62,5 +70,43 @@ next = NodePath("../Tail") position = Vector2(0, 4) animation = &"tail" +[node name="GameOverLabel" type="Label" parent="."] +offset_left = -27.0 +offset_top = -4.0 +offset_right = 27.0 +offset_bottom = 19.0 +theme = ExtResource("7_8hc3g") +text = "Game over" +label_settings = SubResource("LabelSettings_c3csw") + +[node name="SnakeFood3" parent="." instance=ExtResource("6_hib7g")] +position = Vector2(-56, 0) + +[node name="ScoreLabel" type="Label" parent="."] +offset_left = -112.0 +offset_top = -75.0 +offset_right = -70.0 +offset_bottom = -62.0 +theme = ExtResource("7_8hc3g") +theme_override_colors/font_color = Color(0, 0, 0, 1) +text = "Score: " + +[node name="ScoreLabelValue" type="Label" parent="."] +offset_left = -73.0 +offset_top = -75.0 +offset_right = -31.0 +offset_bottom = -62.0 +theme = ExtResource("7_8hc3g") +theme_override_colors/font_color = Color(0, 0, 0, 1) +text = "0" + +[node name="Control" parent="." instance=ExtResource("9_tugdq")] +offset_left = -186.0 +offset_top = -102.0 +offset_right = -186.0 +offset_bottom = -102.0 + +[connection signal="food_collected" from="SnakeHead" to="." method="_on_snake_head_food_collected"] +[connection signal="self_collided" from="SnakeHead" to="." method="_on_snake_head_self_collided"] [connection signal="timeout" from="SnakeHead/Timer" to="SnakeHead" method="_on_timer_timeout"] [connection signal="area_entered" from="SnakeHead/Area2D" to="SnakeHead" method="_on_area_2d_area_entered"] diff --git a/scenes/game_tetris.tscn b/scenes/game_tetris.tscn index 8347f3c..c44577a 100644 --- a/scenes/game_tetris.tscn +++ b/scenes/game_tetris.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=9 format=3 uid="uid://ok137eghwank"] +[gd_scene load_steps=10 format=3 uid="uid://ok137eghwank"] [ext_resource type="Texture2D" uid="uid://bjcjdusr08ly3" path="res://assets/Terrain (16x16).png" id="1_1hb1v"] [ext_resource type="Script" path="res://scripts/game_tetris.gd" id="1_pss6a"] [ext_resource type="Texture2D" uid="uid://dvkmgv2tby1pi" path="res://assets/background/Blue.png" id="2_g03vg"] [ext_resource type="Theme" uid="uid://dlygxgt8hfakm" path="res://pixel_theme.tres" id="4_ewmbd"] [ext_resource type="FontFile" uid="uid://bvlg0bt6ugohe" path="res://assets/fonts/SummerPixel22Regular-jE0W7.ttf" id="4_oek5f"] +[ext_resource type="PackedScene" uid="uid://c2qpcf4un5wgv" path="res://scenes/game_control.tscn" id="6_0rggg"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_slitq"] texture = ExtResource("1_1hb1v") @@ -207,31 +208,11 @@ offset_bottom = 18.0 text = "Game over" label_settings = SubResource("LabelSettings_eao2s") -[node name="MenuButton" type="Button" parent="."] -offset_left = -277.0 -offset_top = -145.0 -offset_right = -185.0 -offset_bottom = -111.0 -scale = Vector2(0.5, 0.5) -focus_mode = 0 -theme = ExtResource("4_ewmbd") -theme_override_font_sizes/font_size = 26 -action_mode = 0 -text = "Menu" - -[node name="RestartButton" type="Button" parent="."] -offset_left = -277.0 -offset_top = -125.0 -offset_right = -185.0 -offset_bottom = -91.0 -scale = Vector2(0.5, 0.5) -focus_mode = 0 -theme = ExtResource("4_ewmbd") -theme_override_font_sizes/font_size = 26 -action_mode = 0 -text = "Restart" +[node name="Control" parent="." instance=ExtResource("6_0rggg")] +offset_left = -288.0 +offset_top = -162.0 +offset_right = -288.0 +offset_bottom = -162.0 [connection signal="ready" from="." to="." method="_on_ready"] [connection signal="timeout" from="FallTimer" to="." method="_on_fall_timer_timeout"] -[connection signal="pressed" from="MenuButton" to="." method="_on_menu_button_pressed"] -[connection signal="pressed" from="RestartButton" to="." method="_on_restart_button_pressed"] diff --git a/scenes/snake_segment.tscn b/scenes/snake_segment.tscn index 316fbcd..5cafa35 100644 --- a/scenes/snake_segment.tscn +++ b/scenes/snake_segment.tscn @@ -50,7 +50,7 @@ sprite_frames = SubResource("SpriteFrames_g8mil") animation = &"straight" script = ExtResource("2_jjlsv") -[node name="Area2D" type="Area2D" parent="."] +[node name="snake_segment_area" type="Area2D" parent="."] -[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] +[node name="CollisionShape2D" type="CollisionShape2D" parent="snake_segment_area"] shape = SubResource("CircleShape2D_pp02b") diff --git a/scripts/game_control.gd b/scripts/game_control.gd new file mode 100644 index 0000000..1e7d8ac --- /dev/null +++ b/scripts/game_control.gd @@ -0,0 +1,9 @@ +extends Control + + +func _on_menu_button_pressed(): + get_tree().change_scene_to_file("scenes/game_selection.tscn") + + +func _on_restart_button_pressed(): + get_tree().reload_current_scene() diff --git a/scripts/game_snake.gd b/scripts/game_snake.gd new file mode 100644 index 0000000..a1b765f --- /dev/null +++ b/scripts/game_snake.gd @@ -0,0 +1,32 @@ +extends Node + +@export var snake_food_scene: PackedScene + +var current_score = 0 +var score_increment = 100 +var width = 64 +var height = 32 +var cell_size = 4 + +func to_world(x, y) -> Vector2: + return Vector2(x * cell_size - width/2.0 * cell_size, y * cell_size - height/2.0 * cell_size) + +func _ready(): + $GameOverLabel.visible = false + $Bounds.size = Vector2(width * cell_size, height * cell_size) + $Bounds.position = to_world(0, 0) + + +func _on_snake_head_self_collided(): + $GameOverLabel.visible = true + $SnakeHead.set_process(false) + + +func _on_snake_head_food_collected(): + current_score += score_increment + $ScoreLabelValue.text = str(current_score) + + var food = snake_food_scene.instantiate() + food.position = to_world(randi_range(1, width - 2), randi_range(1, height - 2)) + call_deferred("add_child", food) + diff --git a/scripts/game_tetris.gd b/scripts/game_tetris.gd index be1e997..68d9abc 100644 --- a/scripts/game_tetris.gd +++ b/scripts/game_tetris.gd @@ -238,10 +238,3 @@ func block_position(x, y): (x - cols_count/2) * block_size, (y - rows_count/2) * block_size) - -func _on_menu_button_pressed(): - get_tree().change_scene_to_file("scenes/game_selection.tscn") - - -func _on_restart_button_pressed(): - get_tree().reload_current_scene() diff --git a/scripts/snake_head.gd b/scripts/snake_head.gd index 3c9b4a8..1972e1a 100644 --- a/scripts/snake_head.gd +++ b/scripts/snake_head.gd @@ -1,5 +1,8 @@ extends Sprite2D +signal food_collected +signal self_collided + @export var snake_segment_scene: PackedScene @export var tail: AnimatedSprite2D var current_direction = Vector2.UP @@ -54,7 +57,8 @@ func _on_timer_timeout() -> void: new_direction = input_buffer.pop_front() update_segment_type(segment, new_direction) - update_head_rotation(new_direction) + + rotation_degrees = direction_to_degress(new_direction) tail = segment add_sibling(segment) @@ -85,29 +89,28 @@ func update_segment_type(segment: AnimatedSprite2D, new_direction: Vector2) -> v segment.rotation_degrees = 270 segment.play("corner") elif current_direction == new_direction: - match current_direction: - DIRECTION_LEFT: - segment.rotation_degrees = 270 - DIRECTION_RIGHT: - segment.rotation_degrees = 90 - DIRECTION_UP: - segment.rotation_degrees = 0 - DIRECTION_DOWN: - segment.rotation_degrees = 180 + segment.rotation_degrees = direction_to_degress(current_direction) segment.play("straight") - -func update_head_rotation(new_direction: Vector2) -> void: - match new_direction: + +func direction_to_degress(dir) -> float: + var value = 0 + match dir: DIRECTION_LEFT: - rotation_degrees = 270 + value = 270 DIRECTION_UP: - rotation_degrees = 0 + value = 0 DIRECTION_RIGHT: - rotation_degrees = 90 + value = 90 DIRECTION_DOWN: - rotation_degrees = 180 + value = 180 + return value func _on_area_2d_area_entered(area) -> void: - if area.name == 'snake_food': - area.get_parent().queue_free() - grow = true + match area.name: + 'snake_food': + food_collected.emit() + area.get_parent().queue_free() + grow = true + 'snake_segment_area': + $Timer.stop() + self_collided.emit()