diff --git a/.gitignore b/.gitignore index dd59a16..d44a61b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ .import/ .export/ export.cfg -export_presets.cfg # Imported translations (automatically generated from CSV files) *.translation diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..2948ac0 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "geequlim.godot-tools", + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..71e1197 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "files.exclude": { + ".godot": true, + "**/*.godot": true, + "**/*.tres": true, + "**/*.tscn": true, + "**/*.import": true, + }, + "files.associations": { + "*.gdignore": "ignore", + }, + "editor.insertSpaces": false, +} diff --git a/Game.gd b/Game.gd new file mode 100644 index 0000000..3a8cf79 --- /dev/null +++ b/Game.gd @@ -0,0 +1,8 @@ +extends Node2D + +func _on_roller_failure(): + print("failure") + + +func _on_roller_success(): + print("success") diff --git a/bottle/bottle.gd b/bottle/bottle.gd new file mode 100644 index 0000000..7edbaf4 --- /dev/null +++ b/bottle/bottle.gd @@ -0,0 +1,11 @@ +extends TileMap + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass diff --git a/bottle/gravity_from_gyro.gd b/bottle/gravity_from_gyro.gd index 52cc29b..7d91eb0 100644 --- a/bottle/gravity_from_gyro.gd +++ b/bottle/gravity_from_gyro.gd @@ -4,6 +4,8 @@ class_name GravityFromGyro func _physics_process(_delta): var accel_3d = Input.get_accelerometer() + if accel_3d == Vector3.ZERO: # If accelerometer is not supported + accel_3d = Vector3.DOWN * 9.8 + var accel_2d = Vector2(accel_3d.x, -accel_3d.y) / 9.8 PhysicsServer2D.area_set_param(get_viewport().find_world_2d().space, PhysicsServer2D.AREA_PARAM_GRAVITY_VECTOR, accel_2d) - diff --git a/collector/collectible.gd b/collector/collectible.gd new file mode 100644 index 0000000..7905c1e --- /dev/null +++ b/collector/collectible.gd @@ -0,0 +1,18 @@ +extends Node +class_name Collectible +## A marker for collectible entities. +## +## Used by [Collector]s to determine which entities to pick up. + + +## The type of collectible entity the parent entity represents. +@export var type: StringName + +## Emitted when this entity has been collected by a collector. +signal collected + +## Mark this entity as collected. +## +## You'll probably want to connect this to an AudioSource2D, which will disable the node and play a sound, and when the sound is over a new signal will queue_free it. +func collect(): + emit_signal("collected") diff --git a/collector/collectible.tscn b/collector/collectible.tscn new file mode 100644 index 0000000..0713a93 --- /dev/null +++ b/collector/collectible.tscn @@ -0,0 +1,9 @@ +[gd_scene load_steps=3 format=3 uid="uid://bk1vvq5rug01m"] + +[ext_resource type="Script" path="res://collector/collectible.gd" id="1_qilbk"] +[ext_resource type="PackedScene" uid="uid://ujpra0s1kpqi" path="res://value/valuable.tscn" id="2_2nvfu"] + +[node name="Collectible" type="Node"] +script = ExtResource("1_qilbk") + +[node name="Valuable" parent="." instance=ExtResource("2_2nvfu")] diff --git a/collector/collector.gd b/collector/collector.gd new file mode 100644 index 0000000..c9a4266 --- /dev/null +++ b/collector/collector.gd @@ -0,0 +1,39 @@ +extends Area2D +class_name Collector +## Area that will pick up [Collectible]s with a given name, keeping track of the amount collected. + + +## The current amount of collected entities. +var collected_count: int = 0 + +## The types of [Collectible]s to pick up. +## +## The strings will match only if exactly the same. +@export var collecting_types: Array[StringName] + +## The collision mask to check colliding body against. +@export_flags_2d_physics var collecting_collision_mask: int + +## The goal amount of entities to collect. +## +## When [collected_count] reaches it, it will be reset to zero, and the "goal" signal will be emitted. +@export var collecting_amount: int + +## The collector has picked up an object. +signal collected(what: PhysicsBody2D) + +## The collector has received its collection goal and is about to reset. +signal goal + + +func _on_body_entered(body: Node2D): + if body is PhysicsBody2D: + if body.collision_layer & collecting_collision_mask: + var collectible: Collectible = body.get_node("Collectible") + if collectible.type in collecting_types: + collected_count += 1 + collectible.collect() + emit_signal("collected", body) + if collected_count >= collecting_amount: + emit_signal("goal") + collected_count = 0 diff --git a/collector/collector.tscn b/collector/collector.tscn new file mode 100644 index 0000000..0273735 --- /dev/null +++ b/collector/collector.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=3 uid="uid://c5w3b55aiui6c"] + +[ext_resource type="Script" path="res://collector/collector.gd" id="1_1xtt5"] + +[node name="Collector" type="Area2D"] +script = ExtResource("1_1xtt5") + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/convertitore.tscn b/convertitore.tscn new file mode 100644 index 0000000..a4b80f1 --- /dev/null +++ b/convertitore.tscn @@ -0,0 +1,26 @@ +[gd_scene load_steps=3 format=3 uid="uid://ei1b0ity3nwg"] + +[ext_resource type="Script" path="res://Convertitore.gd" id="1_7de38"] +[ext_resource type="Texture2D" uid="uid://cxsl5yvdhswc7" path="res://icon.png" id="2_8bfs6"] + +[node name="Convertitore" type="Node2D"] +script = ExtResource("1_7de38") + +[node name="Icon" type="Sprite2D" parent="."] +position = Vector2(61, 76) +rotation = 1.5708 +scale = Vector2(0.2, 0.2) +texture = ExtResource("2_8bfs6") + +[node name="StaticBody2D" type="StaticBody2D" parent="."] + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="StaticBody2D"] +polygon = PackedVector2Array(36, 114, 36, 38, 42, 56, 61, 57, 79, 56, 85, 38, 85, 115, 61, 91) + +[node name="Ingresso" type="Area2D" parent="."] +position = Vector2(56, 42) + +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Ingresso"] +polygon = PackedVector2Array(-20, -6, 29, -6, 23, 11, 5, 14, -12, 12) + +[connection signal="body_shape_entered" from="Ingresso" to="." method="_on_ingresso_body_shape_entered"] diff --git a/entity/coin_copper.tscn b/entity/coin_copper.tscn index a788a5f..20fb5ea 100644 --- a/entity/coin_copper.tscn +++ b/entity/coin_copper.tscn @@ -1,8 +1,10 @@ -[gd_scene load_steps=5 format=3 uid="uid://c3kitncwpi42j"] +[gd_scene load_steps=7 format=3 uid="uid://c3kitncwpi42j"] [ext_resource type="PhysicsMaterial" uid="uid://c6kn1an85lccr" path="res://entity/coin_physics_material.tres" id="1_8k46m"] [ext_resource type="Texture2D" uid="uid://dbdkb4vt7dh85" path="res://entity/coin_copper_4.png" id="1_wedw1"] [ext_resource type="Texture2D" uid="uid://2vtvoj6ua3cb" path="res://entity/coin_copper_outline_2.png" id="2_2ifq3"] +[ext_resource type="PackedScene" uid="uid://bk1vvq5rug01m" path="res://collector/collectible.tscn" id="4_yefrx"] +[ext_resource type="PackedScene" uid="uid://ujpra0s1kpqi" path="res://value/valuable.tscn" id="5_jdvvd"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_c6byl"] size = Vector2(16, 5) @@ -28,3 +30,9 @@ texture = ExtResource("1_wedw1") z_index = -10 texture_filter = 1 texture = ExtResource("2_2ifq3") + +[node name="Collectible" parent="." instance=ExtResource("4_yefrx")] +type = &"Copper" + +[node name="Valuable" parent="." instance=ExtResource("5_jdvvd")] +value = 1 diff --git a/export_presets.cfg b/export_presets.cfg new file mode 100644 index 0000000..20ed2b4 --- /dev/null +++ b/export_presets.cfg @@ -0,0 +1,201 @@ +[preset.0] + +name="Android" +platform="Android" +runnable=true +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="" +encryption_include_filters="" +encryption_exclude_filters="" +encrypt_pck=false +encrypt_directory=false + +[preset.0.options] + +custom_template/debug="" +custom_template/release="" +gradle_build/use_gradle_build=false +gradle_build/export_format=0 +gradle_build/min_sdk="" +gradle_build/target_sdk="" +architectures/armeabi-v7a=false +architectures/arm64-v8a=true +architectures/x86=false +architectures/x86_64=false +version/code=1 +version/name="1.0" +package/unique_name="org.godotengine.$genname" +package/name="" +package/signed=true +package/app_category=2 +package/retain_data_on_uninstall=false +package/exclude_from_recents=false +launcher_icons/main_192x192="" +launcher_icons/adaptive_foreground_432x432="" +launcher_icons/adaptive_background_432x432="" +graphics/opengl_debug=false +xr_features/xr_mode=0 +xr_features/hand_tracking=0 +xr_features/hand_tracking_frequency=0 +xr_features/passthrough=0 +screen/immersive_mode=true +screen/support_small=true +screen/support_normal=true +screen/support_large=true +screen/support_xlarge=true +user_data_backup/allow=false +command_line/extra_args="" +apk_expansion/enable=false +apk_expansion/SALT="" +apk_expansion/public_key="" +permissions/custom_permissions=PackedStringArray() +permissions/access_checkin_properties=false +permissions/access_coarse_location=false +permissions/access_fine_location=false +permissions/access_location_extra_commands=false +permissions/access_mock_location=false +permissions/access_network_state=false +permissions/access_surface_flinger=false +permissions/access_wifi_state=false +permissions/account_manager=false +permissions/add_voicemail=false +permissions/authenticate_accounts=false +permissions/battery_stats=false +permissions/bind_accessibility_service=false +permissions/bind_appwidget=false +permissions/bind_device_admin=false +permissions/bind_input_method=false +permissions/bind_nfc_service=false +permissions/bind_notification_listener_service=false +permissions/bind_print_service=false +permissions/bind_remoteviews=false +permissions/bind_text_service=false +permissions/bind_vpn_service=false +permissions/bind_wallpaper=false +permissions/bluetooth=false +permissions/bluetooth_admin=false +permissions/bluetooth_privileged=false +permissions/brick=false +permissions/broadcast_package_removed=false +permissions/broadcast_sms=false +permissions/broadcast_sticky=false +permissions/broadcast_wap_push=false +permissions/call_phone=false +permissions/call_privileged=false +permissions/camera=false +permissions/capture_audio_output=false +permissions/capture_secure_video_output=false +permissions/capture_video_output=false +permissions/change_component_enabled_state=false +permissions/change_configuration=false +permissions/change_network_state=false +permissions/change_wifi_multicast_state=false +permissions/change_wifi_state=false +permissions/clear_app_cache=false +permissions/clear_app_user_data=false +permissions/control_location_updates=false +permissions/delete_cache_files=false +permissions/delete_packages=false +permissions/device_power=false +permissions/diagnostic=false +permissions/disable_keyguard=false +permissions/dump=false +permissions/expand_status_bar=false +permissions/factory_test=false +permissions/flashlight=false +permissions/force_back=false +permissions/get_accounts=false +permissions/get_package_size=false +permissions/get_tasks=false +permissions/get_top_activity_info=false +permissions/global_search=false +permissions/hardware_test=false +permissions/inject_events=false +permissions/install_location_provider=false +permissions/install_packages=false +permissions/install_shortcut=false +permissions/internal_system_window=false +permissions/internet=false +permissions/kill_background_processes=false +permissions/location_hardware=false +permissions/manage_accounts=false +permissions/manage_app_tokens=false +permissions/manage_documents=false +permissions/manage_external_storage=false +permissions/master_clear=false +permissions/media_content_control=false +permissions/modify_audio_settings=false +permissions/modify_phone_state=false +permissions/mount_format_filesystems=false +permissions/mount_unmount_filesystems=false +permissions/nfc=false +permissions/persistent_activity=false +permissions/process_outgoing_calls=false +permissions/read_calendar=false +permissions/read_call_log=false +permissions/read_contacts=false +permissions/read_external_storage=false +permissions/read_frame_buffer=false +permissions/read_history_bookmarks=false +permissions/read_input_state=false +permissions/read_logs=false +permissions/read_phone_state=false +permissions/read_profile=false +permissions/read_sms=false +permissions/read_social_stream=false +permissions/read_sync_settings=false +permissions/read_sync_stats=false +permissions/read_user_dictionary=false +permissions/reboot=false +permissions/receive_boot_completed=false +permissions/receive_mms=false +permissions/receive_sms=false +permissions/receive_wap_push=false +permissions/record_audio=false +permissions/reorder_tasks=false +permissions/restart_packages=false +permissions/send_respond_via_message=false +permissions/send_sms=false +permissions/set_activity_watcher=false +permissions/set_alarm=false +permissions/set_always_finish=false +permissions/set_animation_scale=false +permissions/set_debug_app=false +permissions/set_orientation=false +permissions/set_pointer_speed=false +permissions/set_preferred_applications=false +permissions/set_process_limit=false +permissions/set_time=false +permissions/set_time_zone=false +permissions/set_wallpaper=false +permissions/set_wallpaper_hints=false +permissions/signal_persistent_processes=false +permissions/status_bar=false +permissions/subscribed_feeds_read=false +permissions/subscribed_feeds_write=false +permissions/system_alert_window=false +permissions/transmit_ir=false +permissions/uninstall_shortcut=false +permissions/update_device_stats=false +permissions/use_credentials=false +permissions/use_sip=false +permissions/vibrate=false +permissions/wake_lock=false +permissions/write_apn_settings=false +permissions/write_calendar=false +permissions/write_call_log=false +permissions/write_contacts=false +permissions/write_external_storage=false +permissions/write_gservices=false +permissions/write_history_bookmarks=false +permissions/write_profile=false +permissions/write_secure_settings=false +permissions/write_settings=false +permissions/write_sms=false +permissions/write_social_stream=false +permissions/write_sync_settings=false +permissions/write_user_dictionary=false diff --git a/game/game.gd b/game/game.gd new file mode 100644 index 0000000..e2e8253 --- /dev/null +++ b/game/game.gd @@ -0,0 +1,9 @@ +extends Node2D +class_name Game + + +@onready var button_spawner = $ButtonSpawner + + +func trigger_spawn(): + button_spawner.spawn() diff --git a/game/game.tscn b/game/game.tscn new file mode 100644 index 0000000..e5a29fd --- /dev/null +++ b/game/game.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=6 format=3 uid="uid://c3rxmcwa5nqng"] + +[ext_resource type="Script" path="res://game/game.gd" id="1_i3ly0"] +[ext_resource type="PackedScene" uid="uid://bllsprv8orpn4" path="res://bottle/bottle.tscn" id="1_y7o2l"] +[ext_resource type="PackedScene" uid="uid://d05b8jy3xmpcb" path="res://bottle/gravity_from_gyro.tscn" id="2_h2pfr"] +[ext_resource type="PackedScene" uid="uid://c67lfbk4gf1ga" path="res://spawner/spawner.tscn" id="3_qwsty"] +[ext_resource type="PackedScene" uid="uid://c3kitncwpi42j" path="res://entity/coin_copper.tscn" id="4_e5nwi"] + +[node name="Game" type="Node2D"] +texture_filter = 1 +script = ExtResource("1_i3ly0") + +[node name="Bottle" parent="." instance=ExtResource("1_y7o2l")] + +[node name="GravityFromGyro" parent="Bottle" instance=ExtResource("2_h2pfr")] + +[node name="TimeSpawner" parent="." instance=ExtResource("3_qwsty")] +position = Vector2(0, -480) +scene = ExtResource("4_e5nwi") +buffer_cap = 1 +spawn_position_range_x = 32.0 +spawn_rotation_range = 15.0 +overlapping_bodies_collision_mask = 4 +overlapping_body_count_limit = 4 + +[node name="Timer" type="Timer" parent="TimeSpawner"] + +[node name="ButtonSpawner" parent="." instance=ExtResource("3_qwsty")] +position = Vector2(0, -480) +scene = ExtResource("4_e5nwi") +buffer_cap = 50 +spawn_position_range_x = 32.0 +spawn_rotation_range = 15.0 +overlapping_bodies_collision_mask = 4 +overlapping_body_count_limit = 4 + +[connection signal="timeout" from="TimeSpawner/Timer" to="TimeSpawner" method="spawn"] diff --git a/interface/game_container.tscn b/interface/game_container.tscn new file mode 100644 index 0000000..fb1b98c --- /dev/null +++ b/interface/game_container.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=2 format=3 uid="uid://c0uce7ssweke"] + +[ext_resource type="PackedScene" uid="uid://c3rxmcwa5nqng" path="res://game/game.tscn" id="1_dbqdv"] + +[node name="GameContainer" type="Control"] +layout_mode = 3 +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 0 + +[node name="Game" parent="." instance=ExtResource("1_dbqdv")] diff --git a/interface/game_ui.gd b/interface/game_ui.gd new file mode 100644 index 0000000..5717b98 --- /dev/null +++ b/interface/game_ui.gd @@ -0,0 +1,21 @@ +extends VBoxContainer +class_name GameUI + +## Emitted when the Score button is pressed. +signal score_button_pressed + +## Emitted when the Spawn button is pressed. +signal spawn_button_pressed + +## Emitted when the Shop button is presesd. +signal shop_button_pressed + + +func _on_score_button_pressed(): + score_button_pressed.emit() + +func _on_spawn_button_pressed(): + spawn_button_pressed.emit() + +func _on_shop_button_pressed(): + shop_button_pressed.emit() diff --git a/interface/game_ui.tscn b/interface/game_ui.tscn new file mode 100644 index 0000000..13b44fb --- /dev/null +++ b/interface/game_ui.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=3 format=3 uid="uid://bo5unrhqpoyim"] + +[ext_resource type="Theme" uid="uid://ba5utvfhnxa5i" path="res://interface/interface_theme.tres" id="1_ppf8y"] +[ext_resource type="Script" path="res://interface/game_ui.gd" id="2_33nqa"] + +[node name="GameUI" type="VBoxContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_ppf8y") +script = ExtResource("2_33nqa") + +[node name="UpperButtons" type="HBoxContainer" parent="."] +custom_minimum_size = Vector2(0, 54) +layout_mode = 2 +size_flags_vertical = 8 +alignment = 1 + +[node name="ScoreButton" type="Button" parent="UpperButtons"] +custom_minimum_size = Vector2(72, 0) +layout_mode = 2 +size_flags_horizontal = 0 +text = "$0" +alignment = 0 + +[node name="UpperButtonsSpacerLeft" type="Control" parent="UpperButtons"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="SpawnButton" type="Button" parent="UpperButtons"] +custom_minimum_size = Vector2(72, 0) +layout_mode = 2 +size_flags_horizontal = 4 +text = "Drop" + +[node name="UpperButtonsSpacerRight" type="Control" parent="UpperButtons"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ShopButton" type="Button" parent="UpperButtons"] +custom_minimum_size = Vector2(72, 0) +layout_mode = 2 +size_flags_horizontal = 8 +text = "Shop" +alignment = 2 + +[connection signal="pressed" from="UpperButtons/ScoreButton" to="." method="_on_score_button_pressed"] +[connection signal="pressed" from="UpperButtons/SpawnButton" to="." method="_on_spawn_button_pressed"] +[connection signal="pressed" from="UpperButtons/ShopButton" to="." method="_on_shop_button_pressed"] diff --git a/interface/interface_theme.tres b/interface/interface_theme.tres new file mode 100644 index 0000000..7381328 --- /dev/null +++ b/interface/interface_theme.tres @@ -0,0 +1,6 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://ba5utvfhnxa5i"] + +[ext_resource type="FontFile" uid="uid://cs8tiwyb76gig" path="res://font/press-start/prstart.ttf" id="1_mtdor"] + +[resource] +default_font = ExtResource("1_mtdor") diff --git a/interface/purchasable_item.gd b/interface/purchasable_item.gd new file mode 100644 index 0000000..817e5fb --- /dev/null +++ b/interface/purchasable_item.gd @@ -0,0 +1,95 @@ +extends Panel +class_name PurchasableItem + +## Icon of the item that can be purchased. +@export var item_icon: Texture2D: + get: + return item_icon + set(value): + item_icon = value + $Contents/Header/IconRect.texture = item_icon + +## Name of the item that can be purchased. +@export var item_name: String: + get: + return item_name + set(value): + item_name = value + $Contents/Header/NameLabel.text = value + +## Description of the item that can be purchased. +@export var item_description: String: + get: + return item_description + set(value): + item_description = value + $Contents/Header/DescriptionLabel.text = value + +## Text to be displayed on the cost label of the item. +@export var item_cost_text: String: + get: + return item_cost_text + set(value): + item_cost_text = value + $Contents/Action/CostLabel.text = value + +## Collectible type of the item required to buy the item. +@export var item_cost_type: StringName + +## Amount of items of the given type to collect to buy the item. +@export var item_cost_goal: int + +## Whether the player can click or not the Buy button. +## +## Used to prevent two items from getting bought at the same time. +@export var can_buy: bool = true: + get: + return can_buy + set(value): + can_buy = value + $Contents/Action/BuyButton.disabled = not (can_buy && has_unlocked) + +## Whether the player has unlocked this item for purchase. +## +## Used to force the player to follow the tech tree. +@export var has_unlocked: bool = true: + get: + return has_unlocked + set(value): + has_unlocked = value + $Contents/Action/BuyButton.disabled = not (can_buy && has_unlocked) + +## Whether the player is currently buying this item. +## +## Used to cancel the purchase. +var is_buying: bool: + get: + return is_buying + set(value): + is_buying = value + $Contents/Action/BuyButton.text = "Cancel" if value else "Buy" + + +## Emitted when a purchase has started. +signal purchase_begin + +## Emitted when a purchase is cancelled. +signal purchase_cancel + +## Emitted when a purchase is completed. +## +## Emitted by complete_purchase(). +signal purchase_success + + +func _on_buy_button_pressed(): + if is_buying: + is_buying = false + purchase_cancel.emit() + else: + is_buying = true + purchase_begin.emit() + +func complete_purchase(): + is_buying = false + purchase_success.emit() diff --git a/interface/purchasable_item.tscn b/interface/purchasable_item.tscn new file mode 100644 index 0000000..e1ef5f6 --- /dev/null +++ b/interface/purchasable_item.tscn @@ -0,0 +1,118 @@ +[gd_scene load_steps=4 format=3 uid="uid://dul1fpyh733t7"] + +[ext_resource type="Texture2D" uid="uid://cxsl5yvdhswc7" path="res://icon.png" id="1_drwcj"] +[ext_resource type="Script" path="res://interface/purchasable_item.gd" id="1_h8jix"] +[ext_resource type="Theme" uid="uid://ba5utvfhnxa5i" path="res://interface/interface_theme.tres" id="1_r2qbu"] + +[node name="PurchasableItem" type="Panel"] +custom_minimum_size = Vector2(0, 182) +anchors_preset = 10 +anchor_right = 1.0 +grow_horizontal = 2 +size_flags_horizontal = 3 +theme = ExtResource("1_r2qbu") +script = ExtResource("1_h8jix") + +[node name="Contents" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="HeaderPaddingTop" type="Control" parent="Contents"] +custom_minimum_size = Vector2(0, 4) +layout_mode = 2 + +[node name="Header" type="HBoxContainer" parent="Contents"] +layout_mode = 2 +size_flags_vertical = 8 + +[node name="IconPaddingLeft" type="Control" parent="Contents/Header"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="IconRect" type="TextureRect" parent="Contents/Header"] +custom_minimum_size = Vector2(54, 54) +layout_mode = 2 +texture = ExtResource("1_drwcj") +expand_mode = 2 + +[node name="IconNameSeparator" type="Control" parent="Contents/Header"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="NameLabel" type="Label" parent="Contents/Header"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_font_sizes/font_size = 16 +text = "ITEMNAME" +uppercase = true + +[node name="NamePaddingRight" type="Control" parent="Contents/Header"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="HeaderDescriptionPadding" type="Control" parent="Contents"] +custom_minimum_size = Vector2(0, 4) +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Description" type="HBoxContainer" parent="Contents"] +layout_mode = 2 +size_flags_vertical = 4 + +[node name="DescriptionPaddingLeft" type="Control" parent="Contents/Description"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="DescriptionLabel" type="Label" parent="Contents/Description"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_font_sizes/font_size = 16 +text = "What does this item do? Nobody knows." +autowrap_mode = 2 + +[node name="DescriptionPaddingRight" type="Control" parent="Contents/Description"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="DescriptionActionPadding" type="Control" parent="Contents"] +custom_minimum_size = Vector2(0, 4) +layout_mode = 2 +size_flags_vertical = 3 + +[node name="Action" type="HBoxContainer" parent="Contents"] +layout_mode = 2 +size_flags_vertical = 0 + +[node name="BuyButtonPaddingLeft" type="Control" parent="Contents/Action"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="BuyButton" type="Button" parent="Contents/Action"] +layout_mode = 2 +text = "Buy" + +[node name="BuyCostPadding" type="Control" parent="Contents/Action"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="CostLabel" type="Label" parent="Contents/Action"] +layout_mode = 2 +size_flags_horizontal = 10 +theme_override_font_sizes/font_size = 16 +text = "3 fiorygi" +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="CostLabelPaddingRight" type="Control" parent="Contents/Action"] +custom_minimum_size = Vector2(8, 0) +layout_mode = 2 + +[node name="ActionPaddingBottom" type="Control" parent="Contents"] +custom_minimum_size = Vector2(0, 4) +layout_mode = 2 + +[connection signal="pressed" from="Contents/Action/BuyButton" to="." method="_on_buy_button_pressed"] diff --git a/interface/purchasable_item_padding.tscn b/interface/purchasable_item_padding.tscn new file mode 100644 index 0000000..a249774 --- /dev/null +++ b/interface/purchasable_item_padding.tscn @@ -0,0 +1,6 @@ +[gd_scene format=3 uid="uid://wodgj6rp2ewm"] + +[node name="PurchasableItemPadding" type="Control"] +custom_minimum_size = Vector2(0, 8) +layout_mode = 3 +anchors_preset = 0 diff --git a/interface/shop_ui.gd b/interface/shop_ui.gd new file mode 100644 index 0000000..b17c66c --- /dev/null +++ b/interface/shop_ui.gd @@ -0,0 +1,71 @@ +extends Panel +class_name ShopUI + +## Emitted when the Score button is pressed. +signal score_button_pressed + +## Emitted when the Delete button is pressed. +signal delete_button_pressed + +## Emitted when the Back button is presesd. +signal back_button_pressed + +## Emitted when any purchase has started. +signal purchase_begin(what: PurchasableItem) + +## Emitted when any purchase is cancelled. +signal purchase_cancel(what: PurchasableItem) + +## Emitted when any purchase is completed. +## +## Emitted by complete_purchase(). +signal purchase_success(what: PurchasableItem) + +## Array of all PurchasableItems that this ShopUI should control. +@onready var purchasable_items: Array[Node] = find_children("*", "PurchasableItem") as Array[Node] + + +func _ready(): + for item in purchasable_items: + item.purchase_begin.connect(_on_any_purchase_begin.bind(item)) + item.purchase_cancel.connect(_on_any_purchase_cancel.bind(item)) + item.purchase_success.connect(_on_any_purchase_success.bind(item)) + +func _on_any_purchase_begin(what: Node): + if not what is PurchasableItem: + push_error("Purchase began outside a PurchasableItem") + return + purchase_begin.emit(what) + for item in purchasable_items: + if item == what: + continue + item.can_buy = false + +func _on_any_purchase_cancel(what: Node): + if not what is PurchasableItem: + push_error("Purchase cancelled outside a PurchasableItem") + return + purchase_cancel.emit(what) + for item in purchasable_items: + if item == what: + continue + item.can_buy = true + +func _on_any_purchase_success(what: Node): + if not what is PurchasableItem: + push_error("Purchase succeeded outside a PurchasableItem") + return + purchase_success.emit(what) + for item in purchasable_items: + if item == what: + continue + item.can_buy = true + +func _on_score_button_pressed(): + score_button_pressed.emit() + +func _on_delete_button_pressed(): + delete_button_pressed.emit() + +func _on_back_button_pressed(): + back_button_pressed.emit() diff --git a/interface/shop_ui.tscn b/interface/shop_ui.tscn new file mode 100644 index 0000000..279e6f3 --- /dev/null +++ b/interface/shop_ui.tscn @@ -0,0 +1,181 @@ +[gd_scene load_steps=5 format=3 uid="uid://cklkdygv61bny"] + +[ext_resource type="Theme" uid="uid://ba5utvfhnxa5i" path="res://interface/interface_theme.tres" id="1_qdf0y"] +[ext_resource type="PackedScene" uid="uid://dul1fpyh733t7" path="res://interface/purchasable_item.tscn" id="2_2dtc0"] +[ext_resource type="Script" path="res://interface/shop_ui.gd" id="2_iyr7m"] +[ext_resource type="PackedScene" uid="uid://wodgj6rp2ewm" path="res://interface/purchasable_item_padding.tscn" id="3_4feaj"] + +[node name="ShopUI" type="Panel"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme = ExtResource("1_qdf0y") +script = ExtResource("2_iyr7m") + +[node name="Rows" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="UpperButtons" type="HBoxContainer" parent="Rows"] +custom_minimum_size = Vector2(0, 54) +layout_mode = 2 + +[node name="ScoreButton" type="Button" parent="Rows/UpperButtons"] +custom_minimum_size = Vector2(72, 0) +layout_mode = 2 +size_flags_horizontal = 0 +text = "$0" +alignment = 0 + +[node name="UpperButtonsSpacerLeft" type="Control" parent="Rows/UpperButtons"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="DeleteButton" type="Button" parent="Rows/UpperButtons"] +custom_minimum_size = Vector2(72, 0) +layout_mode = 2 +size_flags_horizontal = 4 +text = "Del" + +[node name="UpperButtonsSpacerRight" type="Control" parent="Rows/UpperButtons"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="BackButton" type="Button" parent="Rows/UpperButtons"] +custom_minimum_size = Vector2(72, 0) +layout_mode = 2 +size_flags_horizontal = 8 +text = "Back" +alignment = 2 + +[node name="Scrollable" type="ScrollContainer" parent="Rows"] +layout_mode = 2 +size_flags_vertical = 3 +horizontal_scroll_mode = 0 +vertical_scroll_mode = 2 + +[node name="ScrollableItems" type="VBoxContainer" parent="Rows/Scrollable"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="ConvertCategory" type="VBoxContainer" parent="Rows/Scrollable/ScrollableItems"] +layout_mode = 2 + +[node name="PurchasableItemPadding5" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="EarnCoinsLabel" type="Label" parent="Rows/Scrollable/ScrollableItems/ConvertCategory"] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "Convert your coins" +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 2 +uppercase = true + +[node name="PurchasableItemPadding3" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 + +[node name="PurchasableItemPadding" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem2" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 + +[node name="PurchasableItemPadding2" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem3" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 +has_unlocked = false + +[node name="PurchasableItemPadding4" parent="Rows/Scrollable/ScrollableItems/ConvertCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="ManualCategory" type="VBoxContainer" parent="Rows/Scrollable/ScrollableItems"] +layout_mode = 2 + +[node name="PurchasableItemPadding5" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="EarnCoinsLabel" type="Label" parent="Rows/Scrollable/ScrollableItems/ManualCategory"] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "Automatic coin dropper" +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 2 +uppercase = true + +[node name="PurchasableItemPadding3" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 + +[node name="PurchasableItemPadding" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem2" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 + +[node name="PurchasableItemPadding2" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem3" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 +has_unlocked = false + +[node name="PurchasableItemPadding4" parent="Rows/Scrollable/ScrollableItems/ManualCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="AutomaticCategory" type="VBoxContainer" parent="Rows/Scrollable/ScrollableItems"] +layout_mode = 2 + +[node name="PurchasableItemPadding5" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="EarnCoinsLabel" type="Label" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory"] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "Automatic coin dropper" +horizontal_alignment = 1 +vertical_alignment = 1 +autowrap_mode = 2 +uppercase = true + +[node name="PurchasableItemPadding3" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 + +[node name="PurchasableItemPadding" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem2" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 + +[node name="PurchasableItemPadding2" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[node name="PurchasableItem3" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("2_2dtc0")] +layout_mode = 2 +has_unlocked = false + +[node name="PurchasableItemPadding4" parent="Rows/Scrollable/ScrollableItems/AutomaticCategory" instance=ExtResource("3_4feaj")] +layout_mode = 2 + +[connection signal="pressed" from="Rows/UpperButtons/ScoreButton" to="." method="_on_score_button_pressed"] +[connection signal="pressed" from="Rows/UpperButtons/DeleteButton" to="." method="_on_delete_button_pressed"] +[connection signal="pressed" from="Rows/UpperButtons/BackButton" to="." method="_on_back_button_pressed"] diff --git a/random/randomizer.gd b/random/randomizer.gd new file mode 100644 index 0000000..1446f43 --- /dev/null +++ b/random/randomizer.gd @@ -0,0 +1,3 @@ +extends Node +class_name Randomizer +static var rng : RandomNumberGenerator = RandomNumberGenerator.new() diff --git a/random/randomizer.tscn b/random/randomizer.tscn new file mode 100644 index 0000000..d199a94 --- /dev/null +++ b/random/randomizer.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://cldl3smm1c2pm"] + +[ext_resource type="Script" path="res://random/randomizer.gd" id="1_nvy1v"] + +[node name="Randomizer" type="Node"] +script = ExtResource("1_nvy1v") diff --git a/random/roller.gd b/random/roller.gd new file mode 100644 index 0000000..07587c0 --- /dev/null +++ b/random/roller.gd @@ -0,0 +1,14 @@ +extends Node2D + +@export_range(0,1) var slider : float = 0 + +signal success() + +signal failure() + +func roll(): + if Randomizer.rng.randf() < slider: + success.emit() + else: + failure.emit() + diff --git a/random/roller.tscn b/random/roller.tscn new file mode 100644 index 0000000..7c34586 --- /dev/null +++ b/random/roller.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://dvgxb0ichkoe7"] + +[ext_resource type="Script" path="res://random/roller.gd" id="1_vetpi"] + +[node name="Roller" type="Node2D"] +script = ExtResource("1_vetpi") diff --git a/root.gd b/root.gd new file mode 100644 index 0000000..9ba5ed7 --- /dev/null +++ b/root.gd @@ -0,0 +1,53 @@ +extends Node +class_name Root + + +@onready var tree: SceneTree = get_tree() +@onready var game: Game = $UI/GameContainer/Game +@onready var game_ui: GameUI = $UI/GameUI +@onready var shop_ui: ShopUI = $UI/ShopUI + + +enum UIState { + GAME, + SHOP, + SCORE, +} + +@export var ui_state: UIState: + get: + return ui_state + set(value): + match value: + UIState.GAME: + tree.paused = false + game_ui.show() + shop_ui.hide() + UIState.SHOP: + tree.paused = true + game_ui.hide() + shop_ui.show() + UIState.SCORE: + pass + + +func _on_game_ui_score_button_pressed(): + ui_state = UIState.SCORE + +func _on_shop_ui_back_button_pressed(): + ui_state = UIState.GAME + +func _on_shop_ui_delete_button_pressed(): + ui_state = UIState.GAME + +func _on_shop_ui_score_button_pressed(): + ui_state = UIState.SCORE + +func _on_game_ui_shop_button_pressed(): + ui_state = UIState.SHOP + +func _on_game_ui_spawn_button_pressed(): + game.trigger_spawn() + +func _on_shop_ui_purchase_begin(_what): + ui_state = UIState.GAME diff --git a/root.tscn b/root.tscn index 640da11..46ff088 100644 --- a/root.tscn +++ b/root.tscn @@ -1,13 +1,16 @@ -[gd_scene load_steps=5 format=3 uid="uid://cbccs6kwwf265"] +[gd_scene load_steps=6 format=3 uid="uid://cbccs6kwwf265"] -[ext_resource type="PackedScene" uid="uid://bllsprv8orpn4" path="res://bottle/bottle.tscn" id="1_4fmd3"] -[ext_resource type="PackedScene" uid="uid://c3kitncwpi42j" path="res://entity/coin_copper.tscn" id="2_dv01l"] -[ext_resource type="PackedScene" path="res://bottle/gravity_from_gyro.tscn" id="2_m7p4p"] -[ext_resource type="PackedScene" uid="uid://c67lfbk4gf1ga" path="res://spawner/spawner.tscn" id="3_pubxn"] +[ext_resource type="Script" path="res://root.gd" id="1_8jrhk"] +[ext_resource type="Theme" uid="uid://ba5utvfhnxa5i" path="res://interface/interface_theme.tres" id="1_h26ax"] +[ext_resource type="PackedScene" uid="uid://c3rxmcwa5nqng" path="res://game/game.tscn" id="3_hrdyr"] +[ext_resource type="PackedScene" uid="uid://cklkdygv61bny" path="res://interface/shop_ui.tscn" id="3_lvefk"] +[ext_resource type="PackedScene" uid="uid://bo5unrhqpoyim" path="res://interface/game_ui.tscn" id="5_2cc15"] [node name="Root" type="Node"] +script = ExtResource("1_8jrhk") [node name="UI" type="Control" parent="."] +texture_filter = 1 layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -15,53 +18,10 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 size_flags_vertical = 8 - -[node name="Rows" type="VBoxContainer" parent="UI"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="NotchSpacer" type="PanelContainer" parent="UI/Rows"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="UpperButtons" type="HBoxContainer" parent="UI/Rows"] -custom_minimum_size = Vector2(0, 54) -layout_mode = 2 -size_flags_vertical = 8 - -[node name="MoneyButton" type="Button" parent="UI/Rows/UpperButtons"] -custom_minimum_size = Vector2(54, 0) -layout_mode = 2 -size_flags_horizontal = 8 -text = "$0" -alignment = 0 - -[node name="UpperButtonsSpacerLeft" type="PanelContainer" parent="UI/Rows/UpperButtons"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="SpawnButton" type="Button" parent="UI/Rows/UpperButtons"] -custom_minimum_size = Vector2(54, 0) -layout_mode = 2 -size_flags_horizontal = 8 -text = "Drop" - -[node name="UpperButtonsSpacerRight" type="PanelContainer" parent="UI/Rows/UpperButtons"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="ShopButton" type="Button" parent="UI/Rows/UpperButtons"] -custom_minimum_size = Vector2(54, 0) -layout_mode = 2 -size_flags_horizontal = 8 -text = "Shop" -alignment = 2 +theme = ExtResource("1_h26ax") [node name="GameContainer" type="Control" parent="UI"] +process_mode = 1 layout_mode = 1 anchors_preset = 7 anchor_left = 0.5 @@ -71,14 +31,21 @@ anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 0 -[node name="Game" type="Node2D" parent="UI/GameContainer"] -texture_filter = 1 +[node name="Game" parent="UI/GameContainer" instance=ExtResource("3_hrdyr")] -[node name="Bottle" parent="UI/GameContainer/Game" instance=ExtResource("1_4fmd3")] +[node name="GameUI" parent="UI" instance=ExtResource("5_2cc15")] +process_mode = 3 +layout_mode = 1 -[node name="GravityFromGyro" parent="UI/GameContainer/Game/Bottle" instance=ExtResource("2_m7p4p")] +[node name="ShopUI" parent="UI" instance=ExtResource("3_lvefk")] +process_mode = 3 +visible = false +layout_mode = 1 -[node name="Spawner" parent="UI/GameContainer/Game" instance=ExtResource("3_pubxn")] -position = Vector2(0, -400) -scene = ExtResource("2_dv01l") -target_parent = NodePath("..") +[connection signal="score_button_pressed" from="UI/GameUI" to="." method="_on_game_ui_score_button_pressed"] +[connection signal="shop_button_pressed" from="UI/GameUI" to="." method="_on_game_ui_shop_button_pressed"] +[connection signal="spawn_button_pressed" from="UI/GameUI" to="." method="_on_game_ui_spawn_button_pressed"] +[connection signal="back_button_pressed" from="UI/ShopUI" to="." method="_on_shop_ui_back_button_pressed"] +[connection signal="delete_button_pressed" from="UI/ShopUI" to="." method="_on_shop_ui_delete_button_pressed"] +[connection signal="purchase_begin" from="UI/ShopUI" to="." method="_on_shop_ui_purchase_begin"] +[connection signal="score_button_pressed" from="UI/ShopUI" to="." method="_on_shop_ui_score_button_pressed"] diff --git a/score/scoreboard.gd b/score/scoreboard.gd new file mode 100644 index 0000000..d822fd5 --- /dev/null +++ b/score/scoreboard.gd @@ -0,0 +1,14 @@ +extends Control + +class_name ScoreBoard + +@export var score: int = 0 + +func _ready(): + $Label.text = "Score: " + str(score) + +func _process(delta): + pass + +func _on_evaluator_score_changed(total_value): + $Label.text = "Score: " + str(total_value) diff --git a/score/scoreboard.tscn b/score/scoreboard.tscn new file mode 100644 index 0000000..659e8e6 --- /dev/null +++ b/score/scoreboard.tscn @@ -0,0 +1,23 @@ +[gd_scene load_steps=2 format=3 uid="uid://bokcnc0q0qqj3"] + +[ext_resource type="Script" path="res://score/scoreboard.gd" id="1_of77n"] + +[node name="Control" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_of77n") + +[node name="Label" type="Label" parent="."] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 23.0 +text = "SCORE: " + +[node name="VSlider" type="VSlider" parent="."] +layout_mode = 0 +offset_right = 16.0 +offset_bottom = 8.0 diff --git a/spawner/spawner.gd b/spawner/spawner.gd index 1cc21d5..8e6a5f1 100644 --- a/spawner/spawner.gd +++ b/spawner/spawner.gd @@ -1,11 +1,55 @@ extends Node2D class_name Spawner + + @export var scene: PackedScene -@export var target_parent: NodePath + +var buffer: int = 0 +@export var buffer_cap: int + +@onready var area: Area2D = $Area + +@export var spawn_position_range_x: float +@export_range(0, 90) var spawn_rotation_range: float +@onready var rng: RandomNumberGenerator = RandomNumberGenerator.new() + +@export_flags_2d_physics var overlapping_bodies_collision_mask: int +@export_range(0, 16) var overlapping_body_count_limit: int + +signal spawned(what: Node2D) + func spawn(): - if len($Area2D.get_overlapping_bodies()) > 0: + buffer += 1 + if buffer > buffer_cap: + buffer = buffer_cap + +func _count_overlapping_bodies() -> int: + var overlapping_bodies = area.get_overlapping_bodies() + var overlapping_body_count = 0 + for overlapping_body in overlapping_bodies: + if overlapping_body.collision_layer & overlapping_bodies_collision_mask: + overlapping_body_count += 1 + return overlapping_body_count + + +func _select_spawn_position() -> Vector2: + return Vector2(rng.randf_range(-spawn_position_range_x, +spawn_position_range_x), 0) + +func _select_spawn_rotation() -> float: + return rng.randf_range(-spawn_rotation_range, spawn_rotation_range) + +func _do_spawn(): + if _count_overlapping_bodies() > overlapping_body_count_limit: return var scene_instant = scene.instantiate() - scene_instant.position=Vector2.ZERO + scene_instant.position = _select_spawn_position() + scene_instant.rotation_degrees = _select_spawn_rotation() add_child(scene_instant) + emit_signal("spawned", scene_instant) + buffer -= 1 + + +func _physics_process(_delta): + if buffer > 0: + _do_spawn() diff --git a/spawner/spawner.tscn b/spawner/spawner.tscn index b97d4f9..fb79f06 100644 --- a/spawner/spawner.tscn +++ b/spawner/spawner.tscn @@ -2,21 +2,14 @@ [ext_resource type="Script" path="res://spawner/spawner.gd" id="1_xqfmg"] -[sub_resource type="RectangleShape2D" id="RectangleShape2D_xnebx"] -size = Vector2(100, 20) +[sub_resource type="RectangleShape2D" id="RectangleShape2D_p13i4"] +size = Vector2(96, 96) [node name="Spawner" type="Node2D"] script = ExtResource("1_xqfmg") -[node name="Timer" type="Timer" parent="."] -wait_time = 0.1 -autostart = true - -[node name="Area2D" type="Area2D" parent="."] +[node name="Area" type="Area2D" parent="."] collision_mask = 4 -[node name="Shape" type="CollisionShape2D" parent="Area2D"] -position = Vector2(0, -15) -shape = SubResource("RectangleShape2D_xnebx") - -[connection signal="timeout" from="Timer" to="." method="spawn"] +[node name="Shape" type="CollisionShape2D" parent="Area"] +shape = SubResource("RectangleShape2D_p13i4") diff --git a/value/evaluator.gd b/value/evaluator.gd new file mode 100644 index 0000000..62040fb --- /dev/null +++ b/value/evaluator.gd @@ -0,0 +1,39 @@ +extends Area2D +class_name Evaluator +## aggiunge al totale i valori dei Valuable che ci body_enterano e sottrae quelli che ci body_exitano + + +## The current amount of value evaluated. +var total_value: int = 0 + +## The types of [Collectible]s to value. +## +## The strings will match only if exactly the same. +#@export var collecting_types: Array[StringName] + +## The collision mask to check colliding body against. +@export_flags_2d_physics var collecting_collision_mask: int + +## The evaluator has added the value of an object to the total. +signal added(what: PhysicsBody2D, total_value: int) +## The evaluator has removed the value of an object to the total. +signal removed(what: PhysicsBody2D) + +signal score_changed(total_value: int) + +func _on_body_entered(body): + if body is PhysicsBody2D: + if body.collision_layer & collecting_collision_mask: + var evaluable: Valuable = body.get_node("Valuable") + total_value += evaluable.value + evaluable.evaluate() + score_changed.emit(total_value) + +func _on_body_exited(body): + if body is PhysicsBody2D: + if body.collision_layer & collecting_collision_mask: + var evaluable: Valuable = body.get_node("Valuable") + total_value -= evaluable.value + evaluable.evaluate() + score_changed.emit(total_value) + diff --git a/value/evaluator.tscn b/value/evaluator.tscn new file mode 100644 index 0000000..e797c93 --- /dev/null +++ b/value/evaluator.tscn @@ -0,0 +1,9 @@ +[gd_scene load_steps=2 format=3 uid="uid://beg758fa6o0cs"] + +[ext_resource type="Script" path="res://value/evaluator.gd" id="1_sjx78"] + +[node name="Evaluator" type="Area2D"] +script = ExtResource("1_sjx78") + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] +[connection signal="body_exited" from="." to="." method="_on_body_exited"] diff --git a/value/valuable.gd b/value/valuable.gd new file mode 100644 index 0000000..ef50710 --- /dev/null +++ b/value/valuable.gd @@ -0,0 +1,13 @@ +extends Node +class_name Valuable + +@export var value: int + +## Emitted when this entity has been counted. +signal evaluated + +## Mark this entity as evaluated. +## +func evaluate(): + emit_signal("evaluated") + diff --git a/value/valuable.tscn b/value/valuable.tscn new file mode 100644 index 0000000..6a66261 --- /dev/null +++ b/value/valuable.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://ujpra0s1kpqi"] + +[ext_resource type="Script" path="res://value/valuable.gd" id="1_mr62g"] + +[node name="Valuable" type="Node2D"] +script = ExtResource("1_mr62g")