diff --git a/project.godot b/project.godot index e4b5410..b0a597c 100644 --- a/project.godot +++ b/project.godot @@ -24,6 +24,16 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/components/Health_Component.gd" }, { +"base": "Area2D", +"class": "Interactable", +"language": "GDScript", +"path": "res://src/components/Interactable_Component.gd" +}, { +"base": "Node2D", +"class": "Interactable_Receiver", +"language": "GDScript", +"path": "res://src/components/Interactable_Receiver.gd" +}, { "base": "Node", "class": "MovementComponent", "language": "GDScript", @@ -63,6 +73,8 @@ _global_script_class_icons={ "Actor": "", "FrameSoundEffects": "", "HealthComponent": "", +"Interactable": "", +"Interactable_Receiver": "", "MovementComponent": "", "State": "", "StateAnimatedActor": "", diff --git a/src/Levels/Level.tscn b/src/Levels/Level.tscn index ccd3dfb..ca075d7 100644 --- a/src/Levels/Level.tscn +++ b/src/Levels/Level.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://src/templates/Actor/ActorTemplate.tscn" type="PackedScene" id=1] [ext_resource path="res://assets/Tiles/Assets/Demo TileSet.tres" type="TileSet" id=2] [ext_resource path="res://assets/Backgrounds/bgmuck.png" type="Texture" id=3] +[ext_resource path="res://src/components/Interactable_Component.tscn" type="PackedScene" id=4] [ext_resource path="res://assets/Music/platformer_level03_loop.ogg" type="AudioStream" id=6] [ext_resource path="res://src/enemyC/EnemyC.tscn" type="PackedScene" id=7] @@ -71,3 +72,6 @@ __meta__ = { "_edit_lock_": true } actor_type = "NPC" + +[node name="Interactable_Component" parent="." instance=ExtResource( 4 )] +position = Vector2( 186, 144 ) diff --git a/src/components/Interactable_Component.gd b/src/components/Interactable_Component.gd new file mode 100644 index 0000000..a1bfe18 --- /dev/null +++ b/src/components/Interactable_Component.gd @@ -0,0 +1,48 @@ +class_name Interactable +extends Area2D + +## I'm not quite sure what to do with this yet but the idea is having an +# area2d that detects not just a body entering a certain zone but triggering an +# interract status. For a player this would probably be pressing a button. +# the component can perhaps have a prompt of some sort to indicate what they're +# supposed to do. Additionaly the interraction could perhaps trigger some +# sort of animation when the action is performed. + +# This may have to be implemented as a bi-directional mediator pattern where +# the player node is given some sort of call back upon entering the region and +# when it happens it fires off that call back. +# This means that whatever entity that is supposed to interract with these +# objects should also have a receiver function of some kind. + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" +export (NodePath) var sprite_node + +onready var sprite: Sprite = get_node(sprite_node) + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + +func trigger_interaction(): + # This is something that should maybe be extended for every differant interactible. + # They could inherit from this base class and implement this function. + pass + +# Called every frame. 'delta' is the elapsed time since the previous frame. +#func _process(delta): +# pass + +# When a body enters this area +# We want to give that body (a player I assume) a callback or a reference to this +# Node. +func _on_Interactable_Component_body_entered(body): + var colliding_node = body + if colliding_node.has_node("Interactable_Receiver"): + colliding_node.get_node("Interactable_Receiver").register_interactable(self) + +func _on_Interactable_Component_body_exited(body): + var colliding_node = body + if colliding_node.has_node("Interactable_Receiver"): + colliding_node.get_node("Interactable_Receiver").register_interactable(self) diff --git a/src/components/Interactable_Component.tscn b/src/components/Interactable_Component.tscn new file mode 100644 index 0000000..9d31783 --- /dev/null +++ b/src/components/Interactable_Component.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://assets/High Forest/Assets/Interior-01.png" type="Texture" id=1] +[ext_resource path="res://src/components/Interactable_Component.gd" type="Script" id=2] + +[sub_resource type="RectangleShape2D" id=1] + +[node name="Interactable_Component" type="Area2D"] +script = ExtResource( 2 ) +sprite_node = NodePath("Sprite") + +[node name="Sprite" type="Sprite" parent="."] +texture = ExtResource( 1 ) +vframes = 2 +region_enabled = true +region_rect = Rect2( 49, 80, 30, 64 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +modulate = Color( 0.290196, 1, 0, 1 ) +position = Vector2( -1, 3 ) +shape = SubResource( 1 ) + +[connection signal="body_entered" from="." to="." method="_on_Interactable_Component_body_entered"] +[connection signal="body_exited" from="." to="." method="_on_Interactable_Component_body_exited"] diff --git a/src/components/Interactable_Receiver.gd b/src/components/Interactable_Receiver.gd new file mode 100644 index 0000000..50eaa63 --- /dev/null +++ b/src/components/Interactable_Receiver.gd @@ -0,0 +1,45 @@ +class_name Interactable_Receiver +extends Node2D + +# This may be stupid but we're going to have two kinds of callbacks here. +# It's going to be up to the parent/actor/kinematicbody2d/whatever to know +# what conditions have to be met before being able to call that interactible's +# function. +# This is a nice and generic interface that I might be able to use for +# things like opening doors in a level, opening chests/flipping switches etc. + +# This node can keep an array of various interactibles within a level +# and provide several helper functions for managing them perhaps. + +export(String) var interactable_parent_callback = "" + +var call_function: FuncRef + +var interactable_function_callables = [] + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" + + +# Called when the node enters the scene tree for the first time. +func _ready(): + if interactable_parent_callback: + call_function = funcref(owner, interactable_parent_callback) + else: + print("Warning: No interactable receiver function defined on ", owner.name) + +# Switching to a new model that starts with Hitbox +func register_interactable(sender): + print("Interactable Registered " + sender.name) + if interactable_parent_callback: + call_function.call_func() + interactable_function_callables.append(sender) + +func remove_interactable(sender): + print("Interactable Removal " + sender.name) + if interactable_function_callables.has(sender): + var sender_index = interactable_function_callables.rfind(sender) + if sender_index != -1: + interactable_function_callables.remove(sender_index) + diff --git a/src/playerD/Player.tscn b/src/playerD/Player.tscn index a805e65..3bfe9f8 100644 --- a/src/playerD/Player.tscn +++ b/src/playerD/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=126 format=2] +[gd_scene load_steps=127 format=2] [ext_resource path="res://src/templates/Actor/ActorTemplate.tscn" type="PackedScene" id=1] [ext_resource path="res://src/playerD/movement_component.gd" type="Script" id=2] @@ -15,6 +15,7 @@ [ext_resource path="res://src/Gun.gd" type="Script" id=13] [ext_resource path="res://src/playerD/states/roll.gd" type="Script" id=14] [ext_resource path="res://src/state_animated_actor.gd" type="Script" id=15] +[ext_resource path="res://src/components/Interactable_Receiver.gd" type="Script" id=16] [sub_resource type="StreamTexture" id=90] load_path = "res://.import/Mega.png-93dfe0790902b932f7b46f7b23c5d4e7.stex" @@ -678,6 +679,9 @@ points = PoolVector2Array( -5, 0, 1.25483, 0, 5, 0 ) width = 2.0 default_color = Color( 1, 0.607843, 0, 1 ) +[node name="Interactable_Receiver" type="Node2D" parent="." index="8"] +script = ExtResource( 16 ) + [connection signal="do_attack" from="movement_state_machine/attack" to="." method="_on_attack_do_attack"] [connection signal="frame_reached" from="movement_state_machine/roll" to="." method="_on_roll_frame_reached"] [connection signal="state_exited" from="movement_state_machine/roll" to="." method="_on_roll_state_exited"]