diff --git a/godot/Event.gdns b/godot/Event.gdns new file mode 100644 index 0000000..5668ff6 --- /dev/null +++ b/godot/Event.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://gdnative/alai.tres" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "Event" +class_name = "Event" +library = ExtResource( 1 ) diff --git a/godot/GUI/GameOver.tscn b/godot/GUI/GameOver.tscn new file mode 100644 index 0000000..401d521 --- /dev/null +++ b/godot/GUI/GameOver.tscn @@ -0,0 +1,48 @@ +[gd_scene load_steps=7 format=2] + +[ext_resource path="res://assets/fonts/ttf/PixelOperator8.ttf" type="DynamicFontData" id=1] +[ext_resource path="res://assets/fonts/ttf/PixelOperatorHB8.ttf" type="DynamicFontData" id=2] +[ext_resource path="res://GUI/botonreiniciar.gdns" type="Script" id=3] + +[sub_resource type="DynamicFont" id=1] +size = 50 +font_data = ExtResource( 1 ) + +[sub_resource type="DynamicFont" id=2] +font_data = ExtResource( 2 ) + +[sub_resource type="StyleBoxFlat" id=3] +bg_color = Color( 0.0705882, 0.917647, 0, 1 ) + +[node name="GameOver" type="CanvasLayer"] +script = ExtResource( 3 ) + +[node name="Control" type="Control" parent="."] +margin_right = 40.0 +margin_bottom = 40.0 + +[node name="ColorRect" type="ColorRect" parent="Control"] +margin_right = 512.0 +margin_bottom = 288.0 +rect_min_size = Vector2( 512, 288 ) +color = Color( 0, 0, 0, 1 ) + +[node name="Label" type="Label" parent="Control"] +margin_left = 66.0 +margin_top = 17.0 +margin_right = 456.0 +margin_bottom = 71.0 +custom_fonts/font = SubResource( 1 ) +text = "GAME OVER" +align = 1 + +[node name="botonreiniciar" type="Button" parent="Control"] +margin_left = 194.0 +margin_top = 150.0 +margin_right = 338.0 +margin_bottom = 180.0 +custom_fonts/font = SubResource( 2 ) +custom_styles/hover = SubResource( 3 ) +text = "REINICIAR" + +[connection signal="pressed" from="Control/botonreiniciar" to="." method="_on_botonreiniciar_pressed"] diff --git a/godot/GUI/botonreiniciar.gdns b/godot/GUI/botonreiniciar.gdns new file mode 100644 index 0000000..750e9bf --- /dev/null +++ b/godot/GUI/botonreiniciar.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://gdnative/alai.tres" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "GameOverScreen" +class_name = "GameOverScreen" +library = ExtResource( 1 ) diff --git a/godot/Main.tscn b/godot/Main.tscn index 06271a1..5babece 100644 --- a/godot/Main.tscn +++ b/godot/Main.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 format=2] [ext_resource path="res://Main.gdns" type="Script" id=1] -[ext_resource path="res://levels/Level2.tscn" type="PackedScene" id=2] +[ext_resource path="res://levels/Prototype.tscn" type="PackedScene" id=2] +[ext_resource path="res://GUI/GameOver.tscn" type="PackedScene" id=3] [node name="Main" type="Node"] pause_mode = 2 @@ -10,3 +11,6 @@ level = ExtResource( 2 ) [node name="Level" type="Node" parent="."] pause_mode = 1 + +[node name="GameOver" parent="." instance=ExtResource( 3 )] +visible = false diff --git a/godot/collectables/coin/Coin.tscn b/godot/collectables/coin/Coin.tscn new file mode 100644 index 0000000..6d52bb0 --- /dev/null +++ b/godot/collectables/coin/Coin.tscn @@ -0,0 +1,71 @@ +[gd_scene load_steps=10 format=2] + +[ext_resource path="res://assets/coin.png" type="Texture" id=1] +[ext_resource path="res://state_machine/StateMachine.gdns" type="Script" id=2] +[ext_resource path="res://collectables/coin/states/CoinNotCollected.gdns" type="Script" id=3] +[ext_resource path="res://collectables/coin/states/CoinCollected.gdns" type="Script" id=4] + +[sub_resource type="CircleShape2D" id=1] +radius = 6.0 + +[sub_resource type="AtlasTexture" id=2] +atlas = ExtResource( 1 ) +region = Rect2( 0, 0, 18, 18 ) + +[sub_resource type="AtlasTexture" id=3] +atlas = ExtResource( 1 ) +region = Rect2( 18, 0, 18, 18 ) + +[sub_resource type="SpriteFrames" id=4] +animations = [ { +"frames": [ SubResource( 2 ), SubResource( 3 ) ], +"loop": true, +"name": "spin", +"speed": 5.0 +} ] + +[sub_resource type="Animation" id=5] +resource_name = "jump" +length = 0.4 +tracks/0/type = "value" +tracks/0/path = NodePath("AnimatedSprite:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.2, 0.4 ), +"transitions": PoolRealArray( 1, 1, 1 ), +"update": 0, +"values": [ Vector2( 0, 0 ), Vector2( 0, -20 ), Vector2( 0, 0 ) ] +} + +[node name="Coin" type="Area2D"] +collision_layer = 4 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2( 9, 9 ) +shape = SubResource( 1 ) + +[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +frames = SubResource( 4 ) +animation = "spin" +frame = 1 +playing = true +centered = false + +[node name="StateMachine" type="Node" parent="."] +script = ExtResource( 2 ) +default_state = "CoinNotCollected" + +[node name="CoinNotCollected" type="Node" parent="StateMachine"] +script = ExtResource( 3 ) + +[node name="CoinCollected" type="Node" parent="StateMachine"] +script = ExtResource( 4 ) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +anims/jump = SubResource( 5 ) + +[connection signal="body_entered" from="." to="StateMachine/CoinNotCollected" method="_on_body_entered" flags=6] +[connection signal="animation_finished" from="AnimationPlayer" to="StateMachine/CoinCollected" method="_on_animation_finished" flags=6] diff --git a/godot/collectables/coin/states/CoinCollected.gdns b/godot/collectables/coin/states/CoinCollected.gdns new file mode 100644 index 0000000..4465239 --- /dev/null +++ b/godot/collectables/coin/states/CoinCollected.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://gdnative/alai.tres" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "CoinCollected" +class_name = "CoinCollected" +library = ExtResource( 1 ) diff --git a/godot/collectables/coin/states/CoinNotCollected.gdns b/godot/collectables/coin/states/CoinNotCollected.gdns new file mode 100644 index 0000000..acc55d8 --- /dev/null +++ b/godot/collectables/coin/states/CoinNotCollected.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://gdnative/alai.tres" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "CoinNotCollected" +class_name = "CoinNotCollected" +library = ExtResource( 1 ) diff --git a/godot/goal/Goal.tscn b/godot/goal/Goal.tscn new file mode 100644 index 0000000..ee70903 --- /dev/null +++ b/godot/goal/Goal.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=9 format=2] + +[ext_resource path="res://assets/flag.png" type="Texture" id=1] +[ext_resource path="res://goal/GoalNotReached.gdns" type="Script" id=2] +[ext_resource path="res://goal/GoalReached.gdns" type="Script" id=3] +[ext_resource path="res://state_machine/StateMachine.gdns" type="Script" id=4] + +[sub_resource type="RectangleShape2D" id=5] +extents = Vector2( 10, 18 ) + +[sub_resource type="AtlasTexture" id=6] +atlas = ExtResource( 1 ) +region = Rect2( 0, 0, 18, 36 ) + +[sub_resource type="AtlasTexture" id=7] +atlas = ExtResource( 1 ) +region = Rect2( 18, 0, 18, 36 ) + +[sub_resource type="SpriteFrames" id=8] +animations = [ { +"frames": [ SubResource( 6 ), SubResource( 7 ) ], +"loop": true, +"name": "flagmove", +"speed": 5.0 +} ] + +[node name="Goal" type="Area2D"] +position = Vector2( 324, 378 ) +collision_layer = 32 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2( 18, 18 ) +shape = SubResource( 5 ) + +[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +position = Vector2( 18, 18 ) +frames = SubResource( 8 ) +animation = "flagmove" +playing = true + +[node name="StateMachine" type="Node" parent="."] +script = ExtResource( 4 ) +default_state = "GoalNotReached" + +[node name="GoalReached" type="Node" parent="StateMachine"] +script = ExtResource( 3 ) + +[node name="GoalNotReached" type="Node" parent="StateMachine"] +script = ExtResource( 2 ) + +[connection signal="body_entered" from="." to="StateMachine/GoalNotReached" method="_on_Goal_body_entered"] diff --git a/godot/goal/GoalNotReached.gdns b/godot/goal/GoalNotReached.gdns new file mode 100644 index 0000000..1e3a1aa --- /dev/null +++ b/godot/goal/GoalNotReached.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://gdnative/alai.tres" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "GoalNotReached" +class_name = "GoalNotReached" +library = ExtResource( 1 ) diff --git a/godot/goal/GoalReached.gdns b/godot/goal/GoalReached.gdns new file mode 100644 index 0000000..eaa25ba --- /dev/null +++ b/godot/goal/GoalReached.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://gdnative/alai.tres" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "GoalReached" +class_name = "GoalReached" +library = ExtResource( 1 ) diff --git a/godot/hud/CoinHUD.gd b/godot/hud/CoinHUD.gd new file mode 100644 index 0000000..bd8f7b1 --- /dev/null +++ b/godot/hud/CoinHUD.gd @@ -0,0 +1,8 @@ +extends CanvasLayer + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _physics_process(_delta): + if get_tree().paused: + visible = false + else: + visible = true diff --git a/godot/hud/CoinHUD.tscn b/godot/hud/CoinHUD.tscn new file mode 100644 index 0000000..512a8cd --- /dev/null +++ b/godot/hud/CoinHUD.tscn @@ -0,0 +1,58 @@ +[gd_scene load_steps=8 format=2] + +[ext_resource path="res://assets/coin.png" type="Texture" id=1] +[ext_resource path="res://hud/coin/Counter.gdns" type="Script" id=2] +[ext_resource path="res://hud/CoinHUD.gd" type="Script" id=3] + +[sub_resource type="StyleBoxFlat" id=1] +bg_color = Color( 0, 0, 0, 0.541176 ) + +[sub_resource type="AtlasTexture" id=2] +atlas = ExtResource( 1 ) +region = Rect2( 0, 0, 18, 18 ) + +[sub_resource type="AtlasTexture" id=3] +atlas = ExtResource( 1 ) +region = Rect2( 18, 0, 18, 18 ) + +[sub_resource type="SpriteFrames" id=4] +animations = [ { +"frames": [ SubResource( 2 ), SubResource( 3 ) ], +"loop": true, +"name": "spin", +"speed": 5.0 +} ] + +[node name="CoinHUD" type="CanvasLayer"] +pause_mode = 2 +script = ExtResource( 3 ) + +[node name="Panel" type="Panel" parent="."] +margin_left = 144.0 +margin_top = 18.0 +margin_right = 288.0 +margin_bottom = 54.0 +custom_styles/panel = SubResource( 1 ) + +[node name="Label" type="Label" parent="."] +margin_left = 180.0 +margin_top = 18.0 +margin_right = 220.0 +margin_bottom = 36.0 +text = "X" + +[node name="Coins" type="Label" parent="."] +margin_left = 198.0 +margin_top = 18.0 +margin_right = 238.0 +margin_bottom = 32.0 +text = "##" +script = ExtResource( 2 ) + +[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +position = Vector2( 162, 18 ) +frames = SubResource( 4 ) +animation = "spin" +frame = 1 +playing = true +centered = false diff --git a/godot/hud/coin/Counter.gdns b/godot/hud/coin/Counter.gdns new file mode 100644 index 0000000..622052d --- /dev/null +++ b/godot/hud/coin/Counter.gdns @@ -0,0 +1,8 @@ +[gd_resource type="NativeScript" load_steps=2 format=2] + +[ext_resource path="res://gdnative/alai.tres" type="GDNativeLibrary" id=1] + +[resource] +resource_name = "CoinCounter" +class_name = "CoinCounter" +library = ExtResource( 1 ) diff --git a/godot/levels/Prototype.tscn b/godot/levels/Prototype.tscn index b18e1ae..b71e0c7 100644 --- a/godot/levels/Prototype.tscn +++ b/godot/levels/Prototype.tscn @@ -1,13 +1,17 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=8 format=2] [ext_resource path="res://CameraLimit.gdns" type="Script" id=1] [ext_resource path="res://characters/player/Player.tscn" type="PackedScene" id=2] [ext_resource path="res://levels/Prototype.tmx" type="PackedScene" id=3] [ext_resource path="res://assets/backgrounds/mountains.png" type="Texture" id=4] +[ext_resource path="res://collectables/coin/Coin.tscn" type="PackedScene" id=5] +[ext_resource path="res://hud/CoinHUD.tscn" type="PackedScene" id=6] +[ext_resource path="res://goal/Goal.tscn" type="PackedScene" id=8] [node name="Prototype" type="Node2D"] [node name="Player" parent="." instance=ExtResource( 2 )] +collision_layer = 5 [node name="Camera2D" type="Camera2D" parent="Player"] current = true @@ -39,3 +43,17 @@ centered = false [node name="Prototype" parent="Map" instance=ExtResource( 3 )] script = ExtResource( 1 ) + +[node name="CoinHUD" parent="." instance=ExtResource( 6 )] + +[node name="Coins" type="Node" parent="."] + +[node name="coin" parent="Coins" instance=ExtResource( 5 )] +position = Vector2( 72, 450 ) + +[node name="coin2" parent="Coins" instance=ExtResource( 5 )] +position = Vector2( 234, 450 ) + +[node name="Goal" parent="." instance=ExtResource( 8 )] + +[editable path="Coins/coin"] diff --git a/godot/monitor/Monitor.gd b/godot/monitor/Monitor.gd index 004c1f9..80ada27 100644 --- a/godot/monitor/Monitor.gd +++ b/godot/monitor/Monitor.gd @@ -50,6 +50,10 @@ var game: Dictionary = {} func _ready() -> void: + Event.connect("object_created", self, "_object_created") + Event.connect("object_updated", self, "_object_updated") + Event.connect("object_removed", self, "_object_removed") + Event.connect("coin_collected", self, "_on_coin_update") game_version = get_parent().game_version player["rut"] = "" diff --git a/godot/monitor/Monitor.tscn b/godot/monitor/Monitor.tscn index 58f135d..b987a56 100644 --- a/godot/monitor/Monitor.tscn +++ b/godot/monitor/Monitor.tscn @@ -6,6 +6,7 @@ [node name="Monitor" type="Node"] pause_mode = 2 script = ExtResource( 1 ) +monitor_enabled = true [node name="MonitorGUI" parent="." instance=ExtResource( 3 )] visible = false diff --git a/godot/project.godot b/godot/project.godot index b01c12e..527612e 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -15,6 +15,10 @@ config/description="This game is for testing an Artificial Intelligence." run/main_scene="res://Main.tscn" config/icon="res://icon.png" +[autoload] + +Event="*res://Event.gdns" + [display] window/size/width=512 @@ -100,8 +104,10 @@ Send={ 2d_physics/layer_1="Player" 2d_physics/layer_2="Tiles" +2d_physics/layer_3="Collectables" 2d_physics/layer_4="Enemies" 2d_physics/layer_5="Platforms" +2d_physics/layer_6="End Level" [physics] diff --git a/src/Event.cpp b/src/Event.cpp new file mode 100644 index 0000000..6561979 --- /dev/null +++ b/src/Event.cpp @@ -0,0 +1,23 @@ +#include "Event.h" + +void alai::Event::_register_methods() +{ + godot::register_signal("object_created", "name", GODOT_VARIANT_TYPE_STRING, "state", GODOT_VARIANT_TYPE_STRING, "position", GODOT_VARIANT_TYPE_VECTOR2, "velocity", GODOT_VARIANT_TYPE_VECTOR2); + godot::register_signal("object_updated", "name", GODOT_VARIANT_TYPE_STRING, "state", GODOT_VARIANT_TYPE_STRING, "position", GODOT_VARIANT_TYPE_VECTOR2, "velocity", GODOT_VARIANT_TYPE_VECTOR2); + godot::register_signal("object_removed", "name", GODOT_VARIANT_TYPE_STRING); + godot::register_signal("coin_collected", "amount", GODOT_VARIANT_TYPE_INT); + godot::register_signal("player_died"); + +} + +alai::Event::Event() +{ +} + +alai::Event::~Event() +{ +} + +void alai::Event::_init() +{ +} diff --git a/src/Event.h b/src/Event.h new file mode 100644 index 0000000..87607c6 --- /dev/null +++ b/src/Event.h @@ -0,0 +1,47 @@ +#ifndef ALAI_EVENT_H +#define ALAI_EVENT_H + +#include +#include + +namespace alai +{ + /** + * @brief This class provides an event bus for the project. + * + * @details This class should be an auto-loaded singleton for the project. + * To use this use Event.connect() and Event.emit_signal() to have global signals. + */ + class Event : public godot::Node + { + GODOT_CLASS(Event, godot::Node) + public: + /** + * @brief This method registers classes with Godot. + * + * @details This method registers methods, properties, and signals with the Godot engine. + */ + static void _register_methods(); + + /** + * @brief Construct a new Event object. + * + */ + Event(); + + /** + * @brief Destroy the Event object. + * + */ + ~Event(); + + /** + * @brief Initialize the class from Godot. + * + * @details This method is called just once when the Godot engine connects to the instance of the class. + */ + void _init(); + }; +} + +#endif diff --git a/src/coin/CoinCollected.cpp b/src/coin/CoinCollected.cpp new file mode 100644 index 0000000..22a65b8 --- /dev/null +++ b/src/coin/CoinCollected.cpp @@ -0,0 +1,55 @@ +#include "coin/CoinCollected.h" +#include +#include "Event.h" + +using namespace godot; + +void CoinCollected::_register_methods() +{ + register_method("_state_enter", &CoinCollected::_state_enter); + register_method("_state_exit", &CoinCollected::_state_exit); + register_method("_on_animation_finished", &CoinCollected::_on_animation_finished); +} + +CoinCollected::CoinCollected() +{ +} + +CoinCollected::~CoinCollected() +{ +} + +void CoinCollected::_init() +{ + +} + +void CoinCollected::_state_enter() +{ + auto node = get_parent()->find_node("AnimationPlayer"); + + if (node != nullptr) + { + auto animation_player = Object::cast_to(node); + animation_player->play("jump"); + } + +} + +void CoinCollected::_state_exit() +{ + +} + +void CoinCollected::_on_animation_finished(String anim_name) +{ + auto event = get_node("/root/Event"); + event->emit_signal("coin_collected", 1); + this->get_parent()->queue_free(); + + + // get_state_machine()->change("CoinCounter"); + +} + + diff --git a/src/coin/CoinCollected.h b/src/coin/CoinCollected.h new file mode 100644 index 0000000..0e8f359 --- /dev/null +++ b/src/coin/CoinCollected.h @@ -0,0 +1,75 @@ +#ifndef ALAI_COIN_COLLECTED +#define ALAI_COIN_COLLECTED + +#include "state_machine/State.h" + +#include +#include +#include + +namespace godot +{ + /** + * @brief This class controls what happens when the Coin is in the collected state. + * + */ + class CoinCollected : public State + { + GODOT_CLASS(CoinCollected, State) + + private: + /** + * @brief The animated sprite of the Coin. + * + */ + AnimatedSprite *animated_sprite; + + public: + /** + * @brief This method registers classes with Godot. + * + * @details This method registers methods, properties, and signals with the Godot engine. + */ + static void _register_methods(); + + /** + * @brief Construct a new CoinCollected object. + * + */ + CoinCollected(); + + /** + * @brief Destroy the CoinCollected object. + * + */ + ~CoinCollected(); + + /** + * @brief Initialize the class from Godot. + * + * @details This method is called just once when the Godot engine connects to the instance of the class. + */ + void _init(); + + /** + * @brief Called when the collected state of the coin is entered. + * + */ + void _state_enter(); + + /** + * @brief Called when the collected state of the coin is exited. + * + */ + void _state_exit(); + + /** + * @brief Called when the animation of the collected coin has finished. + * + */ + void _on_animation_finished(String anim_name); + }; + +} + +#endif diff --git a/src/coin/CoinCounter.cpp b/src/coin/CoinCounter.cpp new file mode 100644 index 0000000..7bcdbf0 --- /dev/null +++ b/src/coin/CoinCounter.cpp @@ -0,0 +1,43 @@ +#include "coin/CoinCounter.h" +#include +#include "coin/CoinCollected.h" +#include "Event.h" +using namespace godot; + +void CoinCounter::_register_methods() +{ + register_method("_on_coin_collected", &CoinCounter::_on_coin_collected); + register_method("_ready", &CoinCounter::_ready); +} + +CoinCounter::CoinCounter() +{ +} + +CoinCounter::~CoinCounter() +{ +} + +void CoinCounter::_init() +{ + +} + +void CoinCounter::_on_CoinHUD_ready() +{ + + +} +void CoinCounter::_on_coin_collected(int amount) +{ + coins = coins + amount; + set_text(String::num(coins)); +} +void CoinCounter::_ready() +{ + set_text("0"); + auto event = get_node("/root/Event"); + event->connect("coin_collected", this, "_on_coin_collected"); + + +} diff --git a/src/coin/CoinCounter.h b/src/coin/CoinCounter.h new file mode 100644 index 0000000..006aa93 --- /dev/null +++ b/src/coin/CoinCounter.h @@ -0,0 +1,63 @@ +#ifndef ALAI_COIN_COUNTER +#define ALAI_COIN_COUNTER + + +#include +#include +#include + +namespace godot +{ + /** + * @brief This class controls what happens when the Coin is in the collected . + * + */ + class CoinCounter : public Label + { + GODOT_CLASS(CoinCounter, Label) + + private: + int coins = 0; + + + public: + /** + * @brief This method registers classes with Godot. + * + * @details This method registers methods, properties, and signals with the Godot engine. + */ + static void _register_methods(); + + /** + * @brief Construct a new CoinCounter object. + * + */ + CoinCounter(); + + /** + * @brief Destroy the CoinCounter object. + * + */ + ~CoinCounter(); + + /** + * @brief Initialize the class from Godot. + * + * @details This method is called just once when the Godot engine connects to the instance of the class. + */ + void _init(); + + /** + * @brief Called when the collected of the coin is entered. + * + */ + + void _on_CoinHUD_ready(); + void _on_coin_collected(int amount); + void _ready(); + + }; + +} + +#endif diff --git a/src/coin/CoinNotCollected.cpp b/src/coin/CoinNotCollected.cpp new file mode 100644 index 0000000..cb7487b --- /dev/null +++ b/src/coin/CoinNotCollected.cpp @@ -0,0 +1,56 @@ +#include "coin/CoinNotCollected.h" +#include + +using namespace godot; + + +void CoinNotCollected::_register_methods() +{ + register_method("_state_enter", &CoinNotCollected::_state_enter); + register_method("_state_exit", &CoinNotCollected::_state_exit); + register_method("_on_body_entered", &CoinNotCollected::_on_body_entered); +} + +CoinNotCollected::CoinNotCollected() +{ +} + +CoinNotCollected::~CoinNotCollected() +{ +} + +void CoinNotCollected::_init() +{ + +} + +void CoinNotCollected::_state_enter() +{ + animated_sprite = get_parent()->get_node("AnimatedSprite"); + animated_sprite->set_animation("spin"); + animated_sprite->play(); +} + +void CoinNotCollected::_state_exit() +{ + +} + +void CoinNotCollected::_on_body_entered(Node *node) +{ + Godot::print("Coin touched"); + auto parent_node = get_parent(); + + if (parent_node != nullptr) + { + auto coin = Object::cast_to(parent_node); + coin->set_collision_mask_bit(0, false); + } + + get_state_machine()->change("CoinCollected"); + + +} + + + diff --git a/src/coin/CoinNotCollected.h b/src/coin/CoinNotCollected.h new file mode 100644 index 0000000..4739cf0 --- /dev/null +++ b/src/coin/CoinNotCollected.h @@ -0,0 +1,76 @@ +#ifndef ALAI_COIN_NOT_COLLECTED +#define ALAI_COIN_NOT_COLLECTED + +#include "state_machine/State.h" + +#include +#include +#include + +namespace godot +{ + /** + * @brief This class controls what happens when the Coin is in the not collected state. + * + */ + class CoinNotCollected : public State + { + GODOT_CLASS(CoinNotCollected, State) + + private: + /** + * @brief The animated sprite of the Coin. + * + */ + AnimatedSprite *animated_sprite; + + public: + /** + * @brief This method registers classes with Godot. + * + * @details This method registers methods, properties, and signals with the Godot engine. + */ + static void _register_methods(); + + /** + * @brief Construct a new CoinNotCollected object. + * + */ + CoinNotCollected(); + + /** + * @brief Destroy the CoinNotCollected object. + * + */ + ~CoinNotCollected(); + + /** + * @brief Initialize the class from Godot. + * + * @details This method is called just once when the Godot engine connects to the instance of the class. + */ + void _init(); + + /** + * @brief Called when the not collected state of the coin is entered. + * + */ + void _state_enter(); + + /** + * @brief Called when the not collected state of the coin is exited. + * + */ + void _state_exit(); + + /** + * @brief Method called on body entered. + * + * @param[in] node Node interacting with whoever + */ + void _on_body_entered(Node *node); + }; + +} + +#endif diff --git a/src/goal/GoalNotReached.cpp b/src/goal/GoalNotReached.cpp new file mode 100644 index 0000000..4248066 --- /dev/null +++ b/src/goal/GoalNotReached.cpp @@ -0,0 +1,55 @@ +#include "goal/GoalNotReached.h" +#include + +using namespace godot; + + +void GoalNotReached::_register_methods() +{ + register_method("_state_enter", &GoalNotReached::_state_enter); + register_method("_state_exit", &GoalNotReached::_state_exit); + register_method("_on_Goal_body_entered", &GoalNotReached::_on_Goal_body_entered); +} + +GoalNotReached::GoalNotReached() +{ +} + +GoalNotReached::~GoalNotReached() +{ +} + +void GoalNotReached::_init() +{ + +} + +void GoalNotReached::_state_enter() +{ + animated_sprite = get_parent()->get_node("AnimatedSprite"); + animated_sprite->set_animation("flagmove"); + animated_sprite->play(); +} + +void GoalNotReached::_state_exit() +{ + +} + +void GoalNotReached::_on_Goal_body_entered(Node *node) +{ + auto parent_node = get_parent(); + + if (parent_node != nullptr) + { + auto goal = Object::cast_to(parent_node); + goal->set_collision_mask_bit(0, false); + } + + get_state_machine()->change("GoalReached"); + + +} + + + diff --git a/src/goal/GoalNotReached.h b/src/goal/GoalNotReached.h new file mode 100644 index 0000000..82c9628 --- /dev/null +++ b/src/goal/GoalNotReached.h @@ -0,0 +1,76 @@ +#ifndef ALAI_GOAL_NOT_REACHED +#define ALAI_GOAL_NOT_REACHED + +#include "state_machine/State.h" + +#include +#include +#include + +namespace godot +{ + /** + * @brief This class controls what happens when the Coin is in the not collected state. + * + */ + class GoalNotReached : public State + { + GODOT_CLASS(GoalNotReached, State) + + private: + /** + * @brief The animated sprite of the Coin. + * + */ + AnimatedSprite *animated_sprite; + + public: + /** + * @brief This method registers classes with Godot. + * + * @details This method registers methods, properties, and signals with the Godot engine. + */ + static void _register_methods(); + + /** + * @brief Construct a new GoalNotReached object. + * + */ + GoalNotReached(); + + /** + * @brief Destroy the GoalNotReached object. + * + */ + ~GoalNotReached(); + + /** + * @brief Initialize the class from Godot. + * + * @details This method is called just once when the Godot engine connects to the instance of the class. + */ + void _init(); + + /** + * @brief Called when the not collected state of the coin is entered. + * + */ + void _state_enter(); + + /** + * @brief Called when the not collected state of the coin is exited. + * + */ + void _state_exit(); + + /** + * @brief Method called on body entered. + * + * @param[in] node Node interacting with whoever + */ + void _on_Goal_body_entered(Node *node); + }; + +} + +#endif diff --git a/src/goal/GoalReached.cpp b/src/goal/GoalReached.cpp new file mode 100644 index 0000000..239f1e4 --- /dev/null +++ b/src/goal/GoalReached.cpp @@ -0,0 +1,36 @@ +#include "goal/GoalReached.h" +#include + +using namespace godot; + +void GoalReached::_register_methods() +{ + register_method("_state_enter", &GoalReached::_state_enter); + register_method("_state_exit", &GoalReached::_state_exit); +} + +GoalReached::GoalReached() +{ +} + +GoalReached::~GoalReached() +{ +} + +void GoalReached::_init() +{ + +} + +void GoalReached::_state_enter() +{ + Godot::print("Flag touched"); + + +} + +void GoalReached::_state_exit() +{ + +} + diff --git a/src/goal/GoalReached.h b/src/goal/GoalReached.h new file mode 100644 index 0000000..2c854bb --- /dev/null +++ b/src/goal/GoalReached.h @@ -0,0 +1,74 @@ +#ifndef ALAI_GOAL_REACHED +#define ALAI_GOAL_REACHED + +#include "state_machine/State.h" + +#include +#include +#include + +namespace godot +{ + /** + * @brief This class controls what happens when the goal flag is in the reached state. + * + */ + class GoalReached : public State + { + GODOT_CLASS(GoalReached, State) + + private: + /** + * @brief The animated sprite of the Coin. + * + */ + AnimatedSprite *animated_sprite; + + public: + /** + * @brief This method registers classes with Godot. + * + * @details This method registers methods, properties, and signals with the Godot engine. + */ + static void _register_methods(); + + /** + * @brief Construct a new GoalReached object. + * + */ + GoalReached(); + + /** + * @brief Destroy the GoalReached object. + * + */ + ~GoalReached(); + + /** + * @brief Initialize the class from Godot. + * + * @details This method is called just once when the Godot engine connects to the instance of the class. + */ + void _init(); + + /** + * @brief Called when the collected state of the coin is entered. + * + */ + void _state_enter(); + + /** + * @brief Called when the collected state of the coin is exited. + * + */ + void _state_exit(); + + /** + * @brief Called when the animation of the collected coin has finished. + * + */ + }; + +} + +#endif diff --git a/src/godot.cpp b/src/godot.cpp index f83b9d3..ca4934b 100644 --- a/src/godot.cpp +++ b/src/godot.cpp @@ -1,14 +1,21 @@ #include -#include "CameraLimit.h" -#include "Main.h" -#include "state_machine/State.h" +#include "Event.h" #include "state_machine/StateMachine.h" +#include "state_machine/State.h" +#include "Main.h" +#include "CameraLimit.h" #include "player/Player.h" #include "player/states/PlayerIdle.h" #include "player/states/PlayerMove.h" #include "player/states/PlayerJump.h" #include "player/states/PlayerFall.h" +#include "coin/CoinNotCollected.h" +#include "coin/CoinCollected.h" +#include "coin/CoinCounter.h" +#include "goal/GoalReached.h" +#include "goal/GoalNotReached.h" +#include "gui/game_over/GameOverScreen.h" /** * @brief This function connects the gdnative init function. @@ -39,6 +46,7 @@ extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) { godot::Godot::nativescript_init(handle); + godot::register_class(); godot::register_class(); godot::register_class(); godot::register_class(); @@ -48,4 +56,10 @@ extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) godot::register_class(); godot::register_class(); godot::register_class(); + godot::register_class(); + godot::register_class(); + godot::register_class(); + godot::register_class(); + godot::register_class(); + godot::register_class(); } diff --git a/src/gui/game_over/GameOverScreen.cpp b/src/gui/game_over/GameOverScreen.cpp new file mode 100644 index 0000000..203558e --- /dev/null +++ b/src/gui/game_over/GameOverScreen.cpp @@ -0,0 +1,98 @@ +#include "gui/game_over/GameOverScreen.h" +#include "Event.h" + +#include +#include +#include +#include +#include +#include + + +using namespace godot; + +void GameOverScreen::_register_methods() +{ + register_method("_on_botonreiniciar_pressed", &GameOverScreen::_on_botonreiniciar_pressed); + register_method("_ready", &GameOverScreen::_ready); + register_method("connect_signal", &GameOverScreen::connect_signal); + register_method("_on_player_died", &GameOverScreen::_on_player_died); +} + +GameOverScreen::GameOverScreen() +{ +} + +GameOverScreen::~GameOverScreen() +{ +} + +void GameOverScreen::_init() +{ + _resource_loader = ResourceLoader::get_singleton(); + +} + +void GameOverScreen::_ready() +{ + connect_signal(); +} + +void GameOverScreen::_on_botonreiniciar_pressed() +{ + if (_resource_loader->exists("res://levels/Prototype.tscn")) //CAMBIAR A DINAMICO + { + Ref level_scene = _resource_loader->load("res://levels/Prototype.tscn"); + auto level = level_scene->instance(); + auto level_node = get_tree()->get_root()->get_node("Main")->find_node("Level"); + + if (level_node != nullptr) + { + + level_node->add_child(level); + set_visible(false); + call_deferred("connect_signal"); + } + else + { + WARN_PRINT("Node level not found!"); + } + + } + +} + +void GameOverScreen::_on_player_died() //eliminar nivel +{ + auto event = get_node("/root/Event"); + event->disconnect("player_died", this, "_on_player_died"); + Godot::print("player ded"); + set_visible(true); + auto level_node = get_tree()->get_root()->get_node("Main")->find_node("Level"); + if (level_node != nullptr) + { + auto child = level_node->get_child(0); + if (child != nullptr) + { + child->queue_free(); + } + else + { + WARN_PRINT("Child not found!"); + } + } + else + { + WARN_PRINT("Node level not found!"); + } + +} + +void GameOverScreen::connect_signal() +{ + auto event = get_node("/root/Event"); + event->connect("player_died", this, "_on_player_died"); +} + + + diff --git a/src/gui/game_over/GameOverScreen.h b/src/gui/game_over/GameOverScreen.h new file mode 100644 index 0000000..79c5ad9 --- /dev/null +++ b/src/gui/game_over/GameOverScreen.h @@ -0,0 +1,62 @@ +#ifndef ALAI_GAME_OVER_SCREEN_H +#define ALAI_GAME_OVER_SCREEN_H + +#include +#include +#include + + +namespace godot +{ + /** + * @brief This class controls what happens when the Coin is in the collected . + * + */ + class GameOverScreen : public CanvasLayer + { + GODOT_CLASS(GameOverScreen, CanvasLayer) + + private: + ResourceLoader *_resource_loader; + + public: + /** + * @brief This method registers classes with Godot. + * + * @details This method registers methods, properties, and signals with the Godot engine. + */ + static void _register_methods(); + + /** + * @brief Construct a new GameOverScreen object. + * + */ + GameOverScreen(); + + /** + * @brief Destroy the GameOverScreen object. + * + */ + ~GameOverScreen(); + + /** + * @brief Initialize the class from Godot. + * + * @details This method is called just once when the Godot engine connects to the instance of the class. + */ + void _init(); + + /** + * @brief Called when the collected of the coin is entered. + * + */ + void _ready(); + void _on_player_died(); + void _on_botonreiniciar_pressed(); + void connect_signal(); + + }; + +} + +#endif \ No newline at end of file diff --git a/src/player/Player.cpp b/src/player/Player.cpp index 38348a2..f3abf4f 100644 --- a/src/player/Player.cpp +++ b/src/player/Player.cpp @@ -1,5 +1,7 @@ #include "player/Player.h" +#include "Event.h" + #include #include #include @@ -24,9 +26,6 @@ void alai::player::Player::_register_methods() godot::register_property("gravity", &Player::set_gravity, &Player::get_gravity, player::gravity); godot::register_property("run_speed", &Player::set_run_speed, &Player::get_run_speed, player::run_speed); godot::register_property("double_jump", &Player::set_double_jump, &Player::get_double_jump, player::double_jump); - godot::register_signal("object_created", "name", GODOT_VARIANT_TYPE_STRING, "state", GODOT_VARIANT_TYPE_STRING, "position", GODOT_VARIANT_TYPE_VECTOR2, "velocity", GODOT_VARIANT_TYPE_VECTOR2); - godot::register_signal("object_updated", "name", GODOT_VARIANT_TYPE_STRING, "state", GODOT_VARIANT_TYPE_STRING, "position", GODOT_VARIANT_TYPE_VECTOR2, "velocity", GODOT_VARIANT_TYPE_VECTOR2); - godot::register_signal("object_removed", "name", GODOT_VARIANT_TYPE_STRING); } alai::player::Player::Player() @@ -78,28 +77,16 @@ void alai::player::Player::_ready() } void alai::player::Player::_on_monitor_loaded() { - auto object_node = get_tree()->get_root()->find_node("Monitor", true, false); - if (object_node != nullptr) + auto state = get_node("StateMachine")->get_child(0); + if (state != nullptr) { - auto state = get_node("StateMachine")->get_child(0); - if (state != nullptr) - { - connect("object_created", object_node, "_object_created"); - connect("object_updated", object_node, "_object_updated"); - connect("object_removed", object_node, "_object_removed"); - emit_signal("object_created", this->get_name(), state->get_name(), get_global_position(), velocity); - } - else - { - WARN_PRINT("State not found!"); - } + auto event = get_node("/root/Event"); + event->emit_signal("object_created", this->get_name(), state->get_name(), get_global_position(), velocity); } -#ifndef NDEBUG else { - WARN_PRINT("Monitor not found!"); + WARN_PRINT("State not found!"); } -#endif } void alai::player::Player::_physics_process(float delta) @@ -176,21 +163,24 @@ void alai::player::Player::_physics_process(float delta) { if (!notifier->is_on_screen()) { - if (get_parent()->get_class() == "TileMap") + auto event = get_node("/root/Event"); + event->emit_signal("player_died"); + /*if (get_parent()->get_class() == "TileMap") { auto error = get_tree()->change_scene("res://Main.tscn"); if (error != godot::Error::OK) { ERR_PRINT(godot::String().num((int) error) + " Could not load scene!"); } - } + }*/ } } auto state = get_node("StateMachine")->get_child(0); if (state != nullptr) { - emit_signal("object_updated", this->get_name(), state->get_name(), get_global_position(), velocity); + auto event = get_node("/root/Event"); + event->emit_signal("object_updated", this->get_name(), state->get_name(), get_global_position(), velocity); } else {