Skip to content
Download

C++ for Brasa

C++ has a reputation for being hard, but to make games in Brasa you use a small part of it. This page explains that part, with examples taken from the tutorial.

When you press Play, Brasa compiles your code: it turns the text of the .cpp files into a program. If something is written wrong, the compiler warns you in the Saída (Output) before the game opens.

A variable keeps a value. In C++, you say its type:

int lives = 3; // whole number
float speed = 2.0f; // decimal number (the f at the end marks a float)
bool canShoot = true; // true or false
auto dx = 0.0f; // auto: the compiler figures out the type (here, float)
  • Use float for positions and speeds, and int for counts, such as lives and points.
  • const marks something that doesn’t change after it is created: const float margin = 16.0f;.

The instances already come with several variables ready, such as x, y, hspeed and vspeed. See Objects and events.

x = x + 2; // adds 2 to x
x += 2; // the same, shorter
--invincible; // subtracts 1
++spawned; // adds 1
if (held(Key::Space) && canShoot_) {
// space is down AND it can shoot
}
if (state().lives <= 0) {
goTo("GameOver");
} else {
invincible_ = 90;
}
  • && is and, || is or, ! is not.
  • To compare: == (equal), != (different), <, >, <=, >=.

A function is a block of code with a name. It can receive values and return a result:

float centeredX(std::string_view text, float screenWidth) {
return (screenWidth - text.size() * 8.0f) / 2.0f;
}

Most of the time, you call Brasa’s functions: spawn<Bullet>(x, y, "Instancias"), random(0.8f, 1.6f), Audio::play("tiro").

Each object of the game is a class that inherits from brasa::Entity:

class Player : public brasa::Entity {
public:
void onSpawn() override;
void onUpdate() override;
private:
bool canShoot_ = true;
};
  • : public brasa::Entity means that Player is an Entity: it gets position, sprite, speed and all of Brasa’s functions.
  • onSpawn and onUpdate are events. Entity already has these events, empty. The override says you are replacing their behavior.
  • What goes under private: is used only by the class itself. It’s common to end those names with _, as in canShoot_.

The code of each function goes in the .cpp, with the name of the class in front:

void Player::onUpdate() {
// runs on every step
}

The Player:: says “this is the function onUpdate of Player”.

Some of Brasa’s functions receive a piece of code to run later. That piece is a lambda:

after(10, [this] { canShoot_ = true; });
onCollide<Enemy>([this](Enemy& enemy) {
if (hurt()) enemy.destroy();
});
  • [this] lets the lambda use the instance’s things, such as canShoot_ and hurt().
  • (Enemy& enemy) is what the lambda receives: in onCollide, the enemy that touched it.
  • The & means you receive the enemy itself, not a copy, so enemy.destroy() really destroys the enemy.

In spawn<Bullet>(x, y, "Instancias"), count<Enemy>() and onCollide<Enemy>(...), what goes between < > is which object. That is how Brasa knows what to create, count or detect.

#include "Player.hpp" // brings in the class of this object
#include "src/game.hpp" // brings in what belongs to the whole game (score and lives)
#include <algorithm> // brings in std::clamp and std::max from the standard library
using namespace brasa; // lets you write Audio::play instead of brasa::Audio::play
  • #include copies the contents of another file into this one. Use quotes for your own files and < > for libraries.
  • A namespace is a “folder” of names. Brasa uses brasa. The classes of your objects stay outside any namespace.
  • std:: is the namespace of the C++ standard library: std::clamp, std::max, std::format.

When Play fails, the Saída shows the error with the file and the line, for example:

Player.cpp(23,5): error C2143: syntax error: missing ';' before 'if'

This means: in Player.cpp, line 23, column 5, a ; is missing. Click the error and your code editor opens on that line. The most common errors (the compiler writes them in the language of your Visual Studio Build Tools):

Message (similar to) What it usually is
missing ';' The ; is missing at the end of the previous line.
undeclared identifier A misspelled name, or a missing #include (for example src/game.hpp).
cannot convert Different types, such as int and float. A static_cast<float>(...) solves it.
'}' expected A brace { was left unclosed.

See also Play and errors.

  • Microsoft’s C++ documentation: the reference for the language and the standard library.
  • The Primeiro Jogo template: all the code has comments (in Portuguese) explaining what each line does.