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.
Variables and types
Section titled “Variables and types”A variable keeps a value. In C++, you say its type:
int lives = 3; // whole numberfloat speed = 2.0f; // decimal number (the f at the end marks a float)bool canShoot = true; // true or falseauto dx = 0.0f; // auto: the compiler figures out the type (here, float)- Use
floatfor positions and speeds, andintfor counts, such as lives and points. constmarks 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.
Arithmetic
Section titled “Arithmetic”x = x + 2; // adds 2 to xx += 2; // the same, shorter--invincible; // subtracts 1++spawned; // adds 1if, else, && and ||
Section titled “if, else, && and ||”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),<,>,<=,>=.
Functions
Section titled “Functions”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").
Classes, Entity and override
Section titled “Classes, Entity and override”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::Entitymeans thatPlayeris anEntity: it gets position, sprite, speed and all of Brasa’s functions.onSpawnandonUpdateare events.Entityalready has these events, empty. Theoverridesays 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 incanShoot_.
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”.
Lambdas: code for later
Section titled “Lambdas: code for later”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 ascanShoot_andhurt().(Enemy& enemy)is what the lambda receives: inonCollide, the enemy that touched it.- The
&means you receive the enemy itself, not a copy, soenemy.destroy()really destroys the enemy.
Templates: the <Type>
Section titled “Templates: the <Type>”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, namespace and using
Section titled “#include, namespace and using”#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#includecopies the contents of another file into this one. Use quotes for your own files and< >for libraries.- A
namespaceis a “folder” of names. Brasa usesbrasa. The classes of your objects stay outside anynamespace. std::is the namespace of the C++ standard library:std::clamp,std::max,std::format.
Reading compiler errors
Section titled “Reading compiler errors”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.
To learn more
Section titled “To learn more”- 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.
