Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove outdated C++ tutorial in "Your first 2D game" #8473

Merged
merged 1 commit into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 0 additions & 124 deletions getting_started/first_2d_game/03.coding_the_player.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,43 +45,6 @@ Start by declaring the member variables this object will need:
public Vector2 ScreenSize; // Size of the game window.
}

.. code-tab:: cpp

// A `player.gdns` file has already been created for you. Attach it to the Player node.

// Create two files `player.cpp` and `player.hpp` next to `entry.cpp` in `src`.
// This code goes in `player.hpp`. We also define the methods we'll be using here.
#ifndef PLAYER_H
#define PLAYER_H

#include <AnimatedSprite2D.hpp>
#include <Area2D.hpp>
#include <CollisionShape2D.hpp>
#include <Godot.hpp>
#include <Input.hpp>

class Player : public godot::Area2D {
GODOT_CLASS(Player, godot::Area2D)

godot::AnimatedSprite2D *_animated_sprite;
godot::CollisionShape2D *_collision_shape;
godot::Input *_input;
godot::Vector2 _screen_size; // Size of the game window.

public:
real_t speed = 400; // How fast the player will move (pixels/sec).

void _init() {}
void _ready();
void _process(const double p_delta);
void start(const godot::Vector2 p_position);
void _on_body_entered(godot::Node2D *_body);

static void _register_methods();
};

#endif // PLAYER_H

Using the ``export`` keyword on the first variable ``speed`` allows us to set
its value in the Inspector. This can be handy for values that you want to be
able to adjust just like a node's built-in properties. Click on the ``Player``
Expand Down Expand Up @@ -121,18 +84,6 @@ a good time to find the size of the game window:
ScreenSize = GetViewportRect().Size;
}

.. code-tab:: cpp

// This code goes in `player.cpp`.
#include "player.hpp"

void Player::_ready() {
_animated_sprite = get_node<godot::AnimatedSprite2D>("AnimatedSprite2D");
_collision_shape = get_node<godot::CollisionShape2D>("CollisionShape2D");
_input = godot::Input::get_singleton();
_screen_size = get_viewport_rect().size;
}

Now we can use the ``_process()`` function to define what the player will do.
``_process()`` is called every frame, so we'll use it to update elements of our
game, which we expect will change often. For the player, we need to do the
Expand Down Expand Up @@ -245,23 +196,6 @@ which returns ``true`` if it's pressed or ``false`` if it isn't.
}
}

.. code-tab:: cpp

// This code goes in `player.cpp`.
void Player::_process(const double p_delta) {
godot::Vector2 velocity(0, 0);

velocity.x = _input->get_action_strength("move_right") - _input->get_action_strength("move_left");
velocity.y = _input->get_action_strength("move_down") - _input->get_action_strength("move_up");

if (velocity.length() > 0) {
velocity = velocity.normalized() * speed;
_animated_sprite->play();
} else {
_animated_sprite->stop();
}
}

We start by setting the ``velocity`` to ``(0, 0)`` - by default, the player
should not be moving. Then we check each input and add/subtract from the
``velocity`` to obtain a total direction. For example, if you hold ``right`` and
Expand Down Expand Up @@ -308,14 +242,6 @@ the ``_process`` function (make sure it's not indented under the `else`):
y: Mathf.Clamp(Position.Y, 0, ScreenSize.Y)
);

.. code-tab:: cpp

godot::Vector2 position = get_position();
position += velocity * (real_t)p_delta;
position.x = godot::Math::clamp(position.x, (real_t)0.0, _screen_size.x);
position.y = godot::Math::clamp(position.y, (real_t)0.0, _screen_size.y);
set_position(position);

.. tip:: The `delta` parameter in the `_process()` function refers to the *frame
length* - the amount of time that the previous frame took to complete.
Using this value ensures that your movement will remain consistent even
Expand Down Expand Up @@ -370,18 +296,6 @@ movement. Let's place this code at the end of the ``_process()`` function:
animatedSprite2D.FlipV = velocity.Y > 0;
}

.. code-tab:: cpp

if (velocity.x != 0) {
_animated_sprite->set_animation("walk");
_animated_sprite->set_flip_v(false);
// See the note below about boolean assignment.
_animated_sprite->set_flip_h(velocity.x < 0);
} else if (velocity.y != 0) {
_animated_sprite->set_animation("up");
_animated_sprite->set_flip_v(velocity.y > 0);
}

.. Note:: The boolean assignments in the code above are a common shorthand for
programmers. Since we're doing a comparison test (boolean) and also
*assigning* a boolean value, we can do both at the same time. Consider
Expand Down Expand Up @@ -426,10 +340,6 @@ When you're sure the movement is working correctly, add this line to

Hide();

.. code-tab:: cpp

hide();

Preparing for collisions
~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -452,21 +362,6 @@ Add the following at the top of the script. If you're using GDScript, add it aft
[Signal]
public delegate void HitEventHandler();

.. code-tab:: cpp

// This code goes in `player.cpp`.
// We need to register the signal here, and while we're here, we can also
// register the other methods and register the speed property.
void Player::_register_methods() {
godot::register_method("_ready", &Player::_ready);
godot::register_method("_process", &Player::_process);
godot::register_method("start", &Player::start);
godot::register_method("_on_body_entered", &Player::_on_body_entered);
godot::register_property("speed", &Player::speed, (real_t)400.0);
// This below line is the signal.
godot::register_signal<Player>("hit", godot::Dictionary());
}

This defines a custom signal called "hit" that we will have our player emit
(send out) when it collides with an enemy. We will use ``Area2D`` to detect the
collision. Select the ``Player`` node and click the "Node" tab next to the
Expand Down Expand Up @@ -505,16 +400,6 @@ this code to the function:
GetNode<CollisionShape2D>("CollisionShape2D").SetDeferred(CollisionShape2D.PropertyName.Disabled, true);
}

.. code-tab:: cpp

// This code goes in `player.cpp`.
void Player::_on_body_entered(godot::Node2D *_body) {
hide(); // Player disappears after being hit.
emit_signal("hit");
// Must be deferred as we can't change physics properties on a physics callback.
_collision_shape->set_deferred("disabled", true);
}

Each time an enemy hits the player, the signal is going to be emitted. We need
to disable the player's collision so that we don't trigger the ``hit`` signal
more than once.
Expand Down Expand Up @@ -544,13 +429,4 @@ starting a new game.
GetNode<CollisionShape2D>("CollisionShape2D").Disabled = false;
}

.. code-tab:: cpp

// This code goes in `player.cpp`.
void Player::start(const godot::Vector2 p_position) {
set_position(p_position);
show();
_collision_shape->set_disabled(false);
}

With the player working, we'll work on the enemy in the next lesson.
52 changes: 0 additions & 52 deletions getting_started/first_2d_game/04.creating_the_enemy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,35 +78,6 @@ Add a script to the ``Mob`` like this:
// Don't forget to rebuild the project.
}

.. code-tab:: cpp

// Copy `player.gdns` to `mob.gdns` and replace `Player` with `Mob`.
// Attach the `mob.gdns` file to the Mob node.

// Create two files `mob.cpp` and `mob.hpp` next to `entry.cpp` in `src`.
// This code goes in `mob.hpp`. We also define the methods we'll be using here.
#ifndef MOB_H
#define MOB_H

#include <AnimatedSprite2D.hpp>
#include <Godot.hpp>
#include <RigidBody2D.hpp>

class Mob : public godot::RigidBody2D {
GODOT_CLASS(Mob, godot::RigidBody2D)

godot::AnimatedSprite2D *_animated_sprite;

public:
void _init() {}
void _ready();
void _on_visible_on_screen_notifier_2d_screen_exited();

static void _register_methods();
};

#endif // MOB_H

Now let's look at the rest of the script. In ``_ready()`` we play the animation
and randomly choose one of the three animation types:

Expand All @@ -126,22 +97,6 @@ and randomly choose one of the three animation types:
animatedSprite2D.Play(mobTypes[GD.Randi() % mobTypes.Length]);
}

.. code-tab:: cpp

// This code goes in `mob.cpp`.
#include "mob.hpp"

#include <RandomNumberGenerator.hpp>
#include <SpriteFrames.hpp>

void Mob::_ready() {
godot::Ref<godot::RandomNumberGenerator> random = godot::RandomNumberGenerator::_new();
_animated_sprite = get_node<godot::AnimatedSprite2D>("AnimatedSprite2D");
_animated_sprite->set_playing(true);
godot::PoolStringArray mob_types = _animated_sprite->get_sprite_frames()->get_animation_names();
_animated_sprite->set_animation(mob_types[random->randi() % mob_types.size()]);
}

First, we get the list of animation names from the AnimatedSprite2D's ``sprite_frames``
property. This returns an Array containing all three animation names: ``["walk",
"swim", "fly"]``.
Expand All @@ -167,13 +122,6 @@ to the ``Mob`` and add this code:
QueueFree();
}

.. code-tab:: cpp

// This code goes in `mob.cpp`.
void Mob::_on_visible_on_screen_notifier_2d_screen_exited() {
queue_free();
}

This completes the `Mob` scene.

With the player and enemies ready, in the next part, we'll bring them together
Expand Down
Loading