From 898877f09808691a5e5d45850d27ae85f270db16 Mon Sep 17 00:00:00 2001 From: David Luevano Alvarado Date: Thu, 2 Jun 2022 02:35:03 -0600 Subject: add food system --- assets/food/apple.aseprite | Bin 0 -> 599 bytes assets/food/apple.png | Bin 0 -> 148 bytes src/Main.tscn | 9 +++-- src/entities/actors/snake/scenes/Body.tscn | 2 +- src/entities/actors/snake/scenes/Head.tscn | 7 ++-- .../actors/snake/scripts/generic_segment.gd | 10 ++++++ src/entities/actors/snake/scripts/snake.gd | 22 +++++++----- src/entities/food/scenes/Food.tscn | 16 +++++++++ src/entities/food/scenes/FoodManager.tscn | 8 +++++ src/entities/food/scripts/food.gd | 23 ++++++++++++ src/entities/food/scripts/food_manager.gd | 39 +++++++++++++++++++++ src/entities/food/sprites/apple.png | Bin 0 -> 148 bytes src/entities/food/sprites/apple.png.import | 35 ++++++++++++++++++ src/event.gd | 9 +++-- src/global.gd | 5 +-- src/main.gd | 20 +++++++++++ src/project.godot | 28 ++++++++++++++- src/tools/ScreenRecorder.tscn | 10 ++---- src/ui/UI.tscn | 24 +++++++++++++ src/ui/ui.gd | 17 +++++++++ 20 files changed, 256 insertions(+), 28 deletions(-) create mode 100644 assets/food/apple.aseprite create mode 100644 assets/food/apple.png create mode 100644 src/entities/food/scenes/Food.tscn create mode 100644 src/entities/food/scenes/FoodManager.tscn create mode 100644 src/entities/food/scripts/food.gd create mode 100644 src/entities/food/scripts/food_manager.gd create mode 100644 src/entities/food/sprites/apple.png create mode 100644 src/entities/food/sprites/apple.png.import create mode 100644 src/ui/UI.tscn create mode 100644 src/ui/ui.gd diff --git a/assets/food/apple.aseprite b/assets/food/apple.aseprite new file mode 100644 index 0000000..9dd7a6b Binary files /dev/null and b/assets/food/apple.aseprite differ diff --git a/assets/food/apple.png b/assets/food/apple.png new file mode 100644 index 0000000..d4fd6ad Binary files /dev/null and b/assets/food/apple.png differ diff --git a/src/Main.tscn b/src/Main.tscn index ef84fce..1442e36 100644 --- a/src/Main.tscn +++ b/src/Main.tscn @@ -1,16 +1,21 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://entities/actors/snake/scenes/Snake.tscn" type="PackedScene" id=1] [ext_resource path="res://tools/ScreenRecorder.tscn" type="PackedScene" id=2] +[ext_resource path="res://ui/UI.tscn" type="PackedScene" id=3] [ext_resource path="res://main.gd" type="Script" id=4] +[ext_resource path="res://entities/food/scenes/FoodManager.tscn" type="PackedScene" id=5] [node name="Main" type="Node2D"] script = ExtResource( 4 ) +[node name="FoodManager" parent="." instance=ExtResource( 5 )] + [node name="Snake" parent="." instance=ExtResource( 1 )] [node name="Camera" type="Camera2D" parent="."] current = true -zoom = Vector2( 0.5, 0.5 ) + +[node name="UI" parent="." instance=ExtResource( 3 )] [node name="ScreenRecorder" parent="." instance=ExtResource( 2 )] diff --git a/src/entities/actors/snake/scenes/Body.tscn b/src/entities/actors/snake/scenes/Body.tscn index 8e4a8a4..49694c0 100644 --- a/src/entities/actors/snake/scenes/Body.tscn +++ b/src/entities/actors/snake/scenes/Body.tscn @@ -4,7 +4,7 @@ [ext_resource path="res://entities/actors/snake/scripts/generic_segment.gd" type="Script" id=2] [sub_resource type="CapsuleShape2D" id=1] -radius = 5.99999 +radius = 4.99999 height = 4.00002 [node name="BodyPathFollow" type="PathFollow2D"] diff --git a/src/entities/actors/snake/scenes/Head.tscn b/src/entities/actors/snake/scenes/Head.tscn index 22aa7e6..d118fbf 100644 --- a/src/entities/actors/snake/scenes/Head.tscn +++ b/src/entities/actors/snake/scenes/Head.tscn @@ -3,12 +3,11 @@ [ext_resource path="res://entities/actors/snake/sprites/head.png" type="Texture" id=1] [ext_resource path="res://entities/actors/snake/scripts/head.gd" type="Script" id=2] -[sub_resource type="CircleShape2D" id=1] -radius = 5.0 +[sub_resource type="ConvexPolygonShape2D" id=1] +points = PoolVector2Array( -5, 0, 5, 0, 5, -3, 3, -4, 1, -5, -1, -5, -3, -4, -5, -3 ) [node name="Head" type="KinematicBody2D"] -position = Vector2( -1, 0 ) -collision_mask = 0 +collision_mask = 262 script = ExtResource( 2 ) [node name="Sprite" type="Sprite" parent="."] diff --git a/src/entities/actors/snake/scripts/generic_segment.gd b/src/entities/actors/snake/scripts/generic_segment.gd index 6c65d11..e2db91d 100644 --- a/src/entities/actors/snake/scripts/generic_segment.gd +++ b/src/entities/actors/snake/scripts/generic_segment.gd @@ -2,6 +2,16 @@ extends PathFollow2D export(String, "body", "tail") var TYPE: String = "body" +onready var _segment: Area2D = get_child(0) + + +func _ready() -> void: + _segment.connect("body_entered", self, "_on_body_entered") + func _physics_process(delta: float) -> void: offset += Global.SNAKE_SPEED * delta + + +func _on_body_entered(body: Node) -> void: + Event.emit_signal("snake_segment_body_entered", body) diff --git a/src/entities/actors/snake/scripts/snake.gd b/src/entities/actors/snake/scripts/snake.gd index 76b8bee..ead6254 100644 --- a/src/entities/actors/snake/scripts/snake.gd +++ b/src/entities/actors/snake/scripts/snake.gd @@ -18,9 +18,11 @@ var body_segment_queue: Array func _ready(): set_physics_process(false) set_process_input(false) - Event.connect("snake_path_new_point", self, "_on_Head_snake_path_new_point") - Event.connect("snake_added_new_segment", self, "_on_Snake_snake_added_new_segment") - Event.connect("snake_added_initial_segments", self, "_on_Snake_snake_added_initial_segments") + Event.connect("snake_path_new_point", self, "_on_snake_path_new_point") + Event.connect("snake_added_new_segment", self, "_on_snake_added_new_segment") + Event.connect("snake_added_initial_segments", self, "_on_snake_added_initial_segments") + + Event.connect("food_eaten", self, "_on_food_eaten") func _physics_process(delta: float) -> void: @@ -42,7 +44,7 @@ func _add_new_segment() -> void: var _path_length_threshold: float = body_segment_queue[0] + Global.SNAKE_SEGMENT_SIZE if path.curve.get_baked_length() >= _path_length_threshold: var _temp_body_segment: PathFollow2D = BODY_SEGMENT_NP.instance() - Event.emit_signal("snake_add_new_segment", "body") + Event.emit_signal("snake_adding_new_segment", "body") var _new_body_offset: float = body_segment_stack.back().offset - Global.SNAKE_SEGMENT_SIZE _temp_body_segment.offset = _new_body_offset @@ -58,7 +60,7 @@ func _add_new_segment() -> void: func _add_initial_segment(type: PackedScene) -> void: if path.curve.get_baked_length() >= (current_body_segments + 1.0) * Global.SNAKE_SEGMENT_SIZE: var _temp_body_segment: PathFollow2D = type.instance() - Event.emit_signal("snake_add_new_segment", _temp_body_segment.TYPE) + Event.emit_signal("snake_adding_new_segment", _temp_body_segment.TYPE) if _temp_body_segment.TYPE == "body": body_segment_stack.append(_temp_body_segment) else: @@ -78,7 +80,7 @@ func _add_segment_to_queue() -> void: body_segment_queue.append(body_segment_queue.back() + Global.SNAKE_SEGMENT_SIZE) -func _on_Head_snake_path_new_point(coordinates: Vector2) -> void: +func _on_snake_path_new_point(coordinates: Vector2) -> void: path.curve.add_point(coordinates) # update call is to draw curve as there are new points to the path's curve update() @@ -89,11 +91,15 @@ func _on_Head_snake_path_new_point(coordinates: Vector2) -> void: _add_initial_segment(TAIL_SEGMENT_NP) -func _on_Snake_snake_added_new_segment(type: String) -> void: +func _on_snake_added_new_segment(type: String) -> void: if type == "tail": Event.emit_signal("snake_added_initial_segments") -func _on_Snake_snake_added_initial_segments() -> void: +func _on_snake_added_initial_segments() -> void: set_physics_process(true) set_process_input(true) + + +func _on_food_eaten(type: int) -> void: + _add_segment_to_queue() \ No newline at end of file diff --git a/src/entities/food/scenes/Food.tscn b/src/entities/food/scenes/Food.tscn new file mode 100644 index 0000000..bc330e2 --- /dev/null +++ b/src/entities/food/scenes/Food.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://entities/food/scripts/food.gd" type="Script" id=2] + +[sub_resource type="CircleShape2D" id=1] +radius = 7.0 + +[node name="Food" type="Area2D"] +collision_layer = 256 +collision_mask = 0 +script = ExtResource( 2 ) + +[node name="Sprite" type="Sprite" parent="."] + +[node name="Collision" type="CollisionShape2D" parent="."] +shape = SubResource( 1 ) diff --git a/src/entities/food/scenes/FoodManager.tscn b/src/entities/food/scenes/FoodManager.tscn new file mode 100644 index 0000000..3287271 --- /dev/null +++ b/src/entities/food/scenes/FoodManager.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://entities/food/scenes/Food.tscn" type="PackedScene" id=1] +[ext_resource path="res://entities/food/scripts/food_manager.gd" type="Script" id=2] + +[node name="FoodManager" type="Node2D"] +script = ExtResource( 2 ) +FOOD = ExtResource( 1 ) diff --git a/src/entities/food/scripts/food.gd b/src/entities/food/scripts/food.gd new file mode 100644 index 0000000..1689837 --- /dev/null +++ b/src/entities/food/scripts/food.gd @@ -0,0 +1,23 @@ +class_name Food +extends Area2D + +enum Type { + APPLE +} + +var _type_texture: Dictionary = { + Type.APPLE: preload("res://entities/food/sprites/apple.png") +} + +export(Type) var TYPE +onready var _sprite: Sprite = $Sprite + + +func _ready(): + connect("body_entered", self, "_on_body_entered") + _sprite.texture = _type_texture[TYPE] + + +func _on_body_entered(body: Node) -> void: + Event.emit_signal("food_eaten", TYPE) + queue_free() \ No newline at end of file diff --git a/src/entities/food/scripts/food_manager.gd b/src/entities/food/scripts/food_manager.gd new file mode 100644 index 0000000..20772db --- /dev/null +++ b/src/entities/food/scripts/food_manager.gd @@ -0,0 +1,39 @@ +class_name FoodManager +extends Node2D + +export(PackedScene) var FOOD: PackedScene + +var max_apples: int = 10 +var current_apples: int = 0 + + +func _ready(): + Event.connect("food_eaten", self, "_on_food_eaten") + randomize() + + +func _process(delta) -> void: + if current_apples < max_apples: + _place_new_food() + current_apples += 1 + + +func _place_new_food() -> void: + var food: Area2D = FOOD.instance() + Event.emit_signal("food_placing_new_food", food.TYPE) + var position: Vector2 = _get_random_pos() + food.global_position = position + add_child(food) + Event.emit_signal("food_placed_new_food", food.TYPE) + + +func _get_random_pos() -> Vector2: + var screen_size: Vector2 = get_viewport().get_visible_rect().size + var temp_x: float = randf() * screen_size.x - screen_size.x / 2.0 + var temp_y: float = randf() * screen_size.y - screen_size.y / 2.0 + + return Vector2(temp_x, temp_y) + + +func _on_food_eaten(type: int) -> void: + current_apples -= 1 \ No newline at end of file diff --git a/src/entities/food/sprites/apple.png b/src/entities/food/sprites/apple.png new file mode 100644 index 0000000..d4fd6ad Binary files /dev/null and b/src/entities/food/sprites/apple.png differ diff --git a/src/entities/food/sprites/apple.png.import b/src/entities/food/sprites/apple.png.import new file mode 100644 index 0000000..c007dad --- /dev/null +++ b/src/entities/food/sprites/apple.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/apple.png-3f0e1c07d45c9f73006d6dd04c7dfa93.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://entities/food/sprites/apple.png" +dest_files=[ "res://.import/apple.png-3f0e1c07d45c9f73006d6dd04c7dfa93.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=false +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/src/event.gd b/src/event.gd index e03c159..7e72aca 100644 --- a/src/event.gd +++ b/src/event.gd @@ -1,6 +1,11 @@ extends Node signal snake_path_new_point(coordinates) -signal snake_add_new_segment(type) +signal snake_adding_new_segment(type) signal snake_added_new_segment(type) -signal snake_added_initial_segments \ No newline at end of file +signal snake_added_initial_segments +signal snake_segment_body_entered(body) + +signal food_placing_new_food(type) +signal food_placed_new_food(type) +signal food_eaten(type) \ No newline at end of file diff --git a/src/global.gd b/src/global.gd index 1682819..2885443 100644 --- a/src/global.gd +++ b/src/global.gd @@ -1,8 +1,9 @@ extends Node +var GAME_SCALE: float = 2.0 + var SNAKE_SPEED: float = 50.0 var SNAKE_ROT_SPEED: float = 200.0 -var SNAKE_SEGMENT_ROT_SPEED: float = 80.0 var SNAKE_POSITION_UPDATE_INTERVAL: float = 0.01 # this usually corresponds to the sprite size -var SNAKE_SEGMENT_SIZE: float = 14.0 \ No newline at end of file +var SNAKE_SEGMENT_SIZE: float = 14.0 diff --git a/src/main.gd b/src/main.gd index 3e709ef..cdfbbf1 100644 --- a/src/main.gd +++ b/src/main.gd @@ -1,2 +1,22 @@ class_name Main extends Node + +onready var _snake: Node2D = $Snake + + +func _ready() -> void: + Event.connect("snake_segment_body_entered", self, "_on_snake_segment_body_entered") + # OS.window_size = Global.GAME_SCALE * OS.window_size + + +func _on_snake_segment_body_entered(body: Node) -> void: + if body is KinematicBody2D: + _snake_disabled(false) + + +func _snake_disabled(on_off: bool) -> void: + _snake.propagate_call("set_process", [on_off]) + _snake.propagate_call("set_process_internal", [on_off]) + _snake.propagate_call("set_physics_process", [on_off]) + _snake.propagate_call("set_physics_process_internal", [on_off]) + _snake.propagate_call("set_process_input", [on_off]) diff --git a/src/project.godot b/src/project.godot index 941300b..bf55ea9 100644 --- a/src/project.godot +++ b/src/project.godot @@ -9,6 +9,16 @@ config_version=4 _global_script_classes=[ { +"base": "Area2D", +"class": "Food", +"language": "GDScript", +"path": "res://entities/food/scripts/food.gd" +}, { +"base": "Node2D", +"class": "FoodManager", +"language": "GDScript", +"path": "res://entities/food/scripts/food_manager.gd" +}, { "base": "Node", "class": "GifDecoder", "language": "GDScript", @@ -33,13 +43,21 @@ _global_script_classes=[ { "class": "Snake", "language": "GDScript", "path": "res://entities/actors/snake/scripts/snake.gd" +}, { +"base": "CanvasLayer", +"class": "UI", +"language": "GDScript", +"path": "res://ui/ui.gd" } ] _global_script_class_icons={ +"Food": "", +"FoodManager": "", "GifDecoder": "", "GifRecorder": "res://addons/GifMaker/gif.svg", "GifRectangle": "res://addons/GifMaker/GifRectangle.svg", "Main": "", -"Snake": "" +"Snake": "", +"UI": "" } [application] @@ -59,6 +77,13 @@ gdscript/warnings/unused_argument=false gdscript/warnings/unused_signal=false gdscript/warnings/return_value_discarded=false +[display] + +window/size/width=320 +window/size/height=180 +window/stretch/mode="2d" +window/stretch/aspect="keep" + [editor_plugins] enabled=PoolStringArray( "res://addons/GifMaker/plugin.cfg" ) @@ -98,6 +123,7 @@ add_body_part={ 2d_physics/layer_1="snake_head" 2d_physics/layer_2="snake_body" 2d_physics/layer_3="snake_tail" +2d_physics/layer_9="food" [physics] diff --git a/src/tools/ScreenRecorder.tscn b/src/tools/ScreenRecorder.tscn index d29753a..96d6dff 100644 --- a/src/tools/ScreenRecorder.tscn +++ b/src/tools/ScreenRecorder.tscn @@ -12,14 +12,8 @@ anchor_right = 1.0 anchor_bottom = 1.0 [node name="GifRectangle" type="ReferenceRect" parent="Control"] -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -margin_left = -128.0 -margin_top = -128.0 -margin_right = 128.0 -margin_bottom = 128.0 +anchor_right = 1.0 +anchor_bottom = 1.0 script = ExtResource( 1 ) [node name="GifRecorder" type="Viewport" parent="Control"] diff --git a/src/ui/UI.tscn b/src/ui/UI.tscn new file mode 100644 index 0000000..f5b0ac3 --- /dev/null +++ b/src/ui/UI.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://ui/ui.gd" type="Script" id=1] + +[node name="UI" type="CanvasLayer"] +script = ExtResource( 1 ) + +[node name="Root" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 + +[node name="StatsHUD" type="MarginContainer" parent="Root"] +margin_left = 10.0 +margin_top = 10.0 +margin_right = 310.0 +margin_bottom = 110.0 + +[node name="VBox" type="VBoxContainer" parent="Root/StatsHUD"] +margin_right = 300.0 +margin_bottom = 100.0 + +[node name="SnakeSize" type="Label" parent="Root/StatsHUD/VBox"] +margin_right = 300.0 +margin_bottom = 14.0 diff --git a/src/ui/ui.gd b/src/ui/ui.gd new file mode 100644 index 0000000..cb7353e --- /dev/null +++ b/src/ui/ui.gd @@ -0,0 +1,17 @@ +class_name UI +extends CanvasLayer + +onready var _snake_size_label: Label = $Root/StatsHUD/VBox/SnakeSize + +var snake_size: int = 0 +var _snake_size_fmt: String = "Snake size: %s" + + +func _ready(): + Event.connect("snake_added_new_segment", self, "_on_Snake_added_new_segment") + _snake_size_label.text =_snake_size_fmt % snake_size + + +func _on_Snake_added_new_segment(type: String) -> void: + snake_size += 1 + _snake_size_label.text =_snake_size_fmt % snake_size -- cgit v1.2.3