Create a basic flappy bird clone.

Right now, theres no score but I did make a entity abstraction which is like a GameObject from Unity where you have a position and scale (but no rotation) and the entity has a draw function and an update function.
This commit is contained in:
Fries 2024-03-16 22:18:15 -07:00
parent 00fdd89b88
commit c651dcd038
30 changed files with 551 additions and 131 deletions

24
.vscode/launch.json vendored
View file

@ -48,6 +48,30 @@
}
]
},
{
"name": "(gdb, Linux) Launch flappyBird.elf",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/src/flappyBird.elf",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/build",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
},
{
"name": "(gdb) Launch gl.elf",
"type": "cppdbg",

View file

@ -84,7 +84,7 @@ void Cube::model() {
// glNormal3f(nx, ny, nz);
// drawCalls += 1;
} else {
normals.push_back(Engine::Vector3::zero());
normals.push_back(Vector3::zero);
}
// Check if `texcoord_index` is zero or positive. negative = no
@ -99,7 +99,7 @@ void Cube::model() {
// glTexCoord2f(tx, ty);
// drawCalls += 1;
} else {
textureCoords.push_back(Vector3::zero());
textureCoords.push_back(Vector3::zero);
}
}
index_offset += fv;

View file

@ -1,5 +1,4 @@
sources = []
incdirs = include_directories('.')
if host_machine.system() == 'dreamcast'
sources += 'dreamcastController.cc'

View file

@ -4,20 +4,22 @@
#ifdef _arch_dreamcast
#include <GL/gl.h>
#include "dreamcastEngine.hh"
#else
#include "linuxEngine.hh"
#endif
#include <cstdio>
#include <cstring>
#include <functional>
void Engine::initializeEngine() {
#ifdef _arch_dreamcast
#ifdef _arch_dreamcast
engine = new DreamcastEngine;
#else
#else
engine = new LinuxEngine;
#endif
#endif
engine->initializeEngine();
initScreen();
}
@ -26,26 +28,21 @@ void Engine::initializeController() {
engine->initializeController();
controller = engine->controller;
}
void Engine::SwapBuffers() {
engine->SwapBuffers();
}
void Engine::SwapBuffers() const { engine->SwapBuffers(); }
bool Engine::ShouldWindowClose() {
return engine->ShouldWindowClose();
}
bool Engine::ShouldWindowClose() const { return engine->ShouldWindowClose(); }
Engine::~Engine() {
delete engine;
}
Engine::~Engine() { delete engine; }
void Engine::initScreen() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, 640, 480);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0, 640, 0, 480, -100, 100);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glViewport(0, 0, 640, 480);
// glMatrixMode(GL_MODELVIEW);
// glLoadIdentity();
// glOrtho(0, 640, 0, 480, -100, 100);
// glMatrixMode(GL_PROJECTION);
// glLoadIdentity();
}
void Engine::printSystemInformation() {
@ -76,7 +73,8 @@ void Engine::initializeGameLoop() {
}
}
void Engine::pressButton(Controller::Button button, std::function<void()> callback) {
void Engine::pressButton(Controller::Button button,
std::function<void()> callback) {
if (controller->IsButtonPressed(button)) {
if (!(buttonsPressed & button)) {
buttonsPressed |= button;
@ -89,10 +87,15 @@ void Engine::pressButton(Controller::Button button, std::function<void()> callba
}
}
void Engine::glVertex3fNormalized(float x, float y, float z) {
constexpr int xSize = 640, ySize = 480;
const Engine::Vector3 Engine::Vector3::zero = {0, 0, 0};
glVertex3f(x * xSize, y * ySize, z);
Engine::Vector3 Engine::Vector3::operator/(float amount) {
return {this->x / amount, this->y / amount, this->z / amount};
}
Engine::Vector3 Engine::Vector3::zero() { return {0, 0, 0}; }
void Engine::Vector3::operator/=(float amount) {
Vector3 vec = *this / amount;
std::memcpy(this, &vec, sizeof(vec));
}
float Engine::getDeltaTime() const { return deltaTime; }

View file

@ -8,6 +8,12 @@
#include "controller/controller.hh"
#include "nativeEngine.hh"
#ifdef _arch_dreamcast
#include <GL/gl.h>
#else
#include <GLFW/glfw3.h>
#endif
class Engine {
protected:
static constexpr float microSecond = 0.000001f;
@ -19,33 +25,36 @@ class Engine {
bool thirtyfps;
unsigned int buttonsPressed;
Controller* controller = nullptr;
virtual void initScreen();
virtual void gameLoop(){};
void printSystemInformation();
void pressButton(Controller::Button button, std::function<void()> callback);
void glVertex3fNormalized(float x, float y, float z);
void SwapBuffers();
bool ShouldWindowClose();
void SwapBuffers() const;
bool ShouldWindowClose() const;
private:
NativeEngine* engine = nullptr;
template <typename T>
void deltaTimeLoop(T&& callback, struct timeval& beginningOfFrame,
struct timeval& endOfFrame);
NativeEngine* engine = nullptr;
public:
void initializeController();
void initializeEngine();
void initializeGameLoop();
void cleanupEngine();
float getDeltaTime() const;
void pressButton(Controller::Button button, std::function<void()> callback);
virtual ~Engine();
Controller* controller = nullptr;
struct Vector3 {
static Vector3 zero();
Vector3 operator/(float amount);
void operator/=(float amount);
float x;
float y;
float z;
static const Vector3 zero;
};
};
#endif

56
src/engine/entity.cc Normal file
View file

@ -0,0 +1,56 @@
#include "entity.hh"
#include <cstdio>
void Entity::DestroyChildren() {
for (Entity* childEntity : children) {
delete childEntity;
}
}
Entity::~Entity() {
DestroyChildren();
}
void Entity::drawEntity(Entity* entity) {
glPushMatrix();
glTranslatef(entity->position.x, entity->position.y, entity->position.z);
glScalef(entity->scale.x, entity->scale.y, entity->scale.z);
entity->draw();
glPopMatrix();
if (entity->children.size() > 0) {
drawChildrenEntity(entity);
}
}
void Entity::updateEntity(Entity* entity) {
entity->update();
if (entity->children.size() > 0) {
updateChildrenEntity(entity);
}
}
void Entity::drawChildrenEntity(Entity* entity) {
for (Entity* childEntity : entity->children) {
glPushMatrix();
if (childEntity->parent == nullptr) {
printf("Error: Entity parent is nullptr.\n");
} else {
glTranslatef(
childEntity->parent->position.x + childEntity->position.x,
childEntity->parent->position.y + childEntity->position.y,
+childEntity->parent->position.z + childEntity->position.z);
}
glScalef(childEntity->scale.x, childEntity->scale.y,
childEntity->scale.z);
childEntity->draw();
glPopMatrix();
drawChildrenEntity(childEntity);
}
}
void Entity::updateChildrenEntity(Entity* entity) {
for (Entity* childEntity : entity->children) {
childEntity->update();
updateChildrenEntity(childEntity);
}
}

27
src/engine/entity.hh Normal file
View file

@ -0,0 +1,27 @@
#ifndef ENTITY_HH
#define ENTITY_HH
#include "engine.hh"
class Entity {
public:
Entity(Engine* engie, Entity* parent) {
engine = engie;
this->parent = parent;
};
virtual ~Entity();
Engine* engine;
Engine::Vector3 position = {0, 0, 0};
Engine::Vector3 scale = {1, 1, 1};
Entity* parent = nullptr;
std::vector<Entity*> children = {};
virtual void draw(){};
virtual void update(){};
bool destroyed = false;
static void drawEntity(Entity* entity);
static void updateEntity(Entity* entity);
private:
void DestroyChildren();
static void drawChildrenEntity(Entity* entity);
static void updateChildrenEntity(Entity* entity);
};
#endif

View file

@ -1,4 +1,3 @@
#include <GLFW/glfw3.h>
#ifdef __linux__
#include "linuxEngine.hh"
@ -6,7 +5,7 @@
#include <iostream>
#include <stdexcept>
#include "linuxController.hh"
#include "controller/linuxController.hh"
void LinuxEngine::initializeEngine() {
glfwInit();

View file

@ -10,5 +10,5 @@ endif
subdir('controller')
engine = static_library('engine', ['dreamcastEngine.cc', 'linuxEngine.cc', 'engine.cc'], dependencies: engine_deps, include_directories: incdirs)
engine = static_library('engine', ['dreamcastEngine.cc', 'linuxEngine.cc', 'entity.cc', 'engine.cc'], dependencies: engine_deps, include_directories: incdirs)
engine_dep = declare_dependency(link_with: [engine, controller], include_directories: incdirs)

9
src/flappyBird.cc Normal file
View file

@ -0,0 +1,9 @@
#include "flappyBird/FlappyBird.hh"
int main() {
FlappyBird* engine = new FlappyBird;
engine->initializeEngine();
engine->initializeController();
engine->initializeGameLoop();
delete engine;
}

33
src/flappyBird/Bird.cc Normal file
View file

@ -0,0 +1,33 @@
#include "Bird.hh"
void Bird::draw() {
Engine::Vector3 one = {-1.0, -1.0, 0.0};
Engine::Vector3 two = {0.0, 1.0, 0.0};
Engine::Vector3 three = {1.0, -1.0, 0.0f};
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3fv((float*)&(one));
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3fv((float*)&two);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3fv((float*)&three);
glEnd();
}
void Bird::update() {
float deltaTime = engine->getDeltaTime();
engine->pressButton(Controller::A, [&]() {
if (verticalSpeed < 0) {
verticalSpeed = JUMP_CONST;
return;
}
verticalSpeed = std::clamp(verticalSpeed + JUMP_CONST, 0.0f, 1.0f);
});
position.y =
std::clamp(position.y + (verticalSpeed * deltaTime), -1.0f, 1.0f);
verticalSpeed -= FALLING_CONST * deltaTime;
}

16
src/flappyBird/Bird.hh Normal file
View file

@ -0,0 +1,16 @@
#ifndef BIRD_HH
#define BIRD_HH
#include <engine/entity.hh>
class Bird : public Entity {
public:
void draw() override;
void update() override;
Bird(Engine* engie, Entity* parent) : Entity(engie, parent) {}
private:
static constexpr float FALLING_CONST = 0.65;
static constexpr float JUMP_CONST = 0.5;
float verticalSpeed = JUMP_CONST;
};
#endif

View file

@ -0,0 +1,56 @@
#include "FlappyBird.hh"
#include <thread>
void FlappyBird::gameLoop() {
if (!thread) {
thread = new std::thread(&FlappyBird::spawnPipes, this);
}
for (size_t i = 0; i < pipesContainer->children.size(); i++) {
if (pipesContainer->children[i]->destroyed) {
delete pipesContainer->children[i];
pipesContainer->children.erase(pipesContainer->children.begin() + i);
}
}
if (addNewPipe) {
pipesContainer->children.push_back(
Pipes::CreatePipes(this, pipesContainer));
addNewPipe = false;
}
glClear(GL_COLOR_BUFFER_BIT);
controller->PollController();
Entity::updateEntity(this->bird);
Entity::updateEntity(this->pipesContainer);
Entity::drawEntity(this->bird);
Entity::drawEntity(this->pipesContainer);
SwapBuffers();
}
void FlappyBird::spawnPipes() {
threadRunning = true;
while (threadRunning) {
addNewPipe = true;
while (addNewPipe) {
if (!threadRunning) {
return;
}
std::this_thread::yield();
}
std::this_thread::sleep_for(std::chrono::seconds(2));
}
}
FlappyBird::FlappyBird() {
bird = new Bird(this, nullptr);
bird->scale.x = 0.1;
bird->scale.y = 0.1;
bird->position.x = -0.75;
pipesContainer = new PipesContainer(this, nullptr);
}
FlappyBird::~FlappyBird() {
threadRunning = false;
delete bird;
delete pipesContainer;
thread->detach();
delete thread;
}

View file

@ -0,0 +1,22 @@
#ifndef FLAPPY_BIRD_HH
#define FLAPPY_BIRD_HH
#include <thread>
#include <engine/engine.hh>
#include <engine/entity.hh>
#include "Bird.hh"
#include "Pipes.hh"
class FlappyBird : public Engine {
void gameLoop() override;
void spawnPipes();
public:
Bird* bird;
PipesContainer* pipesContainer;
std::thread* thread = nullptr;
bool threadRunning;
bool addNewPipe;
FlappyBird();
~FlappyBird();
};
#endif

54
src/flappyBird/Pipes.cc Normal file
View file

@ -0,0 +1,54 @@
#include "Pipes.hh"
#include <random>
#include "engine/entity.hh"
void Pipe::draw() { glRectf(-1.0f, pipeLength, 1.0f, -pipeLength); }
Pipes::Pipes(Engine* engie, Entity* parent) : Entity(engie, parent) {
std::random_device r;
std::default_random_engine generator(r());
std::uniform_int_distribution<int> upOrDownGenerator(0, 2);
int upOrDown = upOrDownGenerator(generator);
std::uniform_real_distribution<float> offsetGenerator(0.35f, 0.8f);
if (upOrDown) {
pipeOffset = -offsetGenerator(generator);
} else {
pipeOffset = offsetGenerator(generator);
}
Pipe* pipe1 = new Pipe(engine, this);
Pipe* pipe2 = new Pipe(engine, this);
pipe1->scale.x = 0.1;
pipe1->position.y = 1.0f;
pipe1->pipeLength = pipeLength + pipeOffset;
pipe2->scale.x = 0.1;
pipe2->position.y = -1.0f;
pipe2->pipeLength = pipeLength - pipeOffset;
children.push_back(pipe1);
children.push_back(pipe2);
// position.x -= 0.1f;
}
void Pipes::update() {
position.x -= 0.5f * engine->getDeltaTime();
if (position.x < -2) {
destroyed = true;
}
}
Pipes* Pipes::CreatePipes(Engine* engie, Entity* parent) {
Pipes* pipes = new Pipes(engie, parent);
pipes->scale.x = 0.1f;
pipes->scale.y = 0.1f;
pipes->position.x = 1.25f;
return pipes;
}

26
src/flappyBird/Pipes.hh Normal file
View file

@ -0,0 +1,26 @@
#ifndef PIPES_HH
#define PIPES_HH
#include <engine/entity.hh>
class Pipes : public Entity {
public:
Pipes(Engine* engie, Entity* parent);
void update() override;
float pipeLength = 0.7f;
float pipeOffset = 0.35f;
static Pipes* CreatePipes(Engine* engie, Entity* parent);
};
class Pipe : public Entity {
void draw() override;
public:
Pipe(Engine* engie, Entity* parent) : Entity(engie, parent) {}
float pipeLength = 1.0f;
};
class PipesContainer : public Entity {
public:
PipesContainer(Engine* engie, Entity* parent) : Entity(engie, parent) {}
};
#endif

View file

@ -0,0 +1,8 @@
flappy_sources = [
'Bird.cc',
'FlappyBird.cc',
'Pipes.cc'
]
flappy_bird = static_library('flappyBird', flappy_sources, dependencies: deps, include_directories: incdirs)
flappy_dep = declare_dependency(link_with: [flappy_bird], include_directories: incdirs)

View file

@ -1,75 +1,9 @@
#ifdef _arch_dreamcast
#include <GL/gl.h>
#include <GL/glkos.h>
#include <kos.h>
#else
#include <GLFW/glfw3.h>
#endif
#include <algorithm>
#include <cstdio>
#include "engine/engine.hh"
class Glcc : public Engine {
void process_input();
void displayStuff();
void gameLoop() override {
process_input();
displayStuff();
}
};
void Glcc::displayStuff() {
glClear(GL_COLOR_BUFFER_BIT);
// clang-format off
glPushMatrix();
glRotatef(angle, 0, 0, 1);
glColor3f(0.5f, 0.0f, 1.0f);
glBegin(GL_POLYGON);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3fNormalized(0.25f, 0.25f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3fNormalized(0.75f, 0.25f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3fNormalized(0.75f, 0.75f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3fNormalized(0.25f, 0.75f, 0.0f);
glEnd();
glPopMatrix();
// clang-format on
#ifdef _arch_dreamcast
if (thirtyfps) {
vid_waitvbl();
vid_waitvbl();
}
#endif
SwapBuffers();
}
void Glcc::process_input() {
controller->PollController();
pressButton(Controller::Button::DPAD_LEFT, [&]() { speed -= 1.0f; });
pressButton(Controller::Button::DPAD_RIGHT, [&]() { speed += 1.0f; });
pressButton(Controller::Button::A, [&]() { thirtyfps = !thirtyfps; });
speed = std::clamp(speed, 1.0f, 10.0f);
angle += controller->GetLeftJoystickXAxis() * deltaTime * speed;
printf("%f\n", speed);
// printf("%f\n", controller->GetLeftJoystickXAxis());
}
#include "gl/Gl.hh"
int main() {
Glcc* engine = new Glcc;
engine->initializeEngine();
engine->initializeController();
engine->initializeGameLoop();
delete engine;
}

15
src/gl/Gl.cc Normal file
View file

@ -0,0 +1,15 @@
#include "Gl.hh"
#include <engine/entity.hh>
#include "GlEntity.hh"
Glcc::Glcc() {
entity = new GlEntity(this, nullptr);
}
void Glcc::gameLoop() {
glClear(GL_COLOR_BUFFER_BIT);
controller->PollController();
Entity::updateEntity(entity);
Entity::drawEntity(entity);
SwapBuffers();
}

14
src/gl/Gl.hh Normal file
View file

@ -0,0 +1,14 @@
#ifndef GL_HH
#define GL_HH
#include <engine/engine.hh>
#include "GlEntity.hh"
class Glcc : public Engine {
public:
Glcc();
private:
void gameLoop() override;
GlEntity* entity;
};
#endif

52
src/gl/GlEntity.cc Normal file
View file

@ -0,0 +1,52 @@
#include "GlEntity.hh"
#include <cstdio>
#ifdef _arch_dreamcast
#include <kos.h>
#endif
GlEntity::GlEntity(Engine* engie, Entity* parent) : Entity(engie, parent) {}
void GlEntity::update() {
engine->pressButton(Controller::Button::DPAD_LEFT,
[&]() { speed -= 1.0f; });
engine->pressButton(Controller::Button::DPAD_RIGHT,
[&]() { speed += 1.0f; });
engine->pressButton(Controller::Button::A,
[&]() { thirtyFps = !thirtyFps; });
speed = std::clamp(speed, 1.0f, 10.0f);
angle += engine->controller->GetLeftJoystickXAxis() *
engine->getDeltaTime() * speed;
printf("%f\n", speed);
}
void GlEntity::draw() {
// clang-format off
glPushMatrix();
glRotatef(angle, 0, 0, 1);
glColor3f(0.5f, 0.0f, 1.0f);
glBegin(GL_POLYGON);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.25f, 0.25f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.75f, 0.25f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.75f, 0.75f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.25f, 0.75f, 0.0f);
glEnd();
glPopMatrix();
// clang-format on
#ifdef _arch_dreamcast
if (thirtyFps) {
vid_waitvbl();
vid_waitvbl();
}
#endif
}

15
src/gl/GlEntity.hh Normal file
View file

@ -0,0 +1,15 @@
#ifndef GL_ENTITY_HH
#define GL_ENTITY_HH
#include <engine/entity.hh>
class GlEntity : public Entity {
public:
GlEntity(Engine* engie, Entity* parent);
private:
void update() override;
void draw() override;
bool thirtyFps;
float angle = 0;
float speed = 5.0f;
};
#endif

9
src/gl/meson.build Normal file
View file

@ -0,0 +1,9 @@
glcc_sources = [
'Gl.cc',
'GlEntity.cc'
]
glcc = static_library('glcc', glcc_sources, dependencies: deps, include_directories: incdirs)
glcc_dep = declare_dependency(link_with: [glcc], include_directories: incdirs)

View file

@ -3,32 +3,8 @@
#else
#include <GLFW/glfw3.h>
#endif
#include "engine/engine.hh"
class Hello : public Engine {
void triangle();
void gameLoop() override {
triangle();
SwapBuffers();
}
};
void Hello::triangle() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3fNormalized(-1.0f, -1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3fNormalized(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3fNormalized(1.0f, -1.0f, 0.0f);
glEnd();
}
#include "hello/Hello.hh"
int main(int argc, char *argv[]) {
Hello* engine = new Hello;

11
src/hello/Hello.cc Normal file
View file

@ -0,0 +1,11 @@
#include "Hello.hh"
Hello::Hello() {
entity = new HelloEntity(this, nullptr);
}
void Hello::gameLoop() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Entity::drawEntity(entity);
SwapBuffers();
}

12
src/hello/Hello.hh Normal file
View file

@ -0,0 +1,12 @@
#ifndef HELLO_HH
#define HELLO_HH
#include <engine/engine.hh>
#include "HelloEntity.hh"
class Hello : public Engine {
public:
HelloEntity* entity;
void gameLoop() override;
Hello();
};
#endif

16
src/hello/HelloEntity.cc Normal file
View file

@ -0,0 +1,16 @@
#include "HelloEntity.hh"
void HelloEntity::draw() {
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glEnd();
}
HelloEntity::HelloEntity(Engine* engie, Entity* parent) : Entity(engie, parent) {}

9
src/hello/HelloEntity.hh Normal file
View file

@ -0,0 +1,9 @@
#ifndef HELLO_ENTITY_HH
#define HELLO_ENTITY_HH
#include <engine/entity.hh>
class HelloEntity : public Entity {
void draw() override;
public:
HelloEntity(Engine* engine, Entity* parent);
};
#endif

8
src/hello/meson.build Normal file
View file

@ -0,0 +1,8 @@
hello_sources = [
'Hello.cc',
'HelloEntity.cc'
]
hello = static_library('hello', hello_sources, dependencies: deps, include_directories: incdirs)
hello_dep = declare_dependency(link_with: [hello], include_directories: incdirs)

View file

@ -40,6 +40,7 @@ endif
subdir('engine')
deps += [engine_dep]
srcinc = include_directories('./')
cube_sources = [
'cube.cc'
@ -49,6 +50,13 @@ if host_machine.system() == 'dreamcast'
cube_sources += romdsk_o
endif
executable('hello.elf', ['hello.cc'], dependencies: deps, include_directories: incdirs)
executable('gl.elf', ['gl.cc'], dependencies: deps, include_directories: incdirs)
incdirs += [srcinc]
subdir('hello')
subdir('gl')
subdir('flappyBird')
executable('hello.elf', ['hello.cc'], dependencies: [deps] + [hello_dep], include_directories: incdirs)
executable('gl.elf', ['gl.cc'], dependencies: [deps] + [glcc_dep], include_directories: incdirs)
executable('cube.elf', cube_sources, dependencies: deps, include_directories: incdirs)
executable('flappyBird.elf', ['flappyBird.cc'], dependencies: [deps] + [flappy_dep], include_directories: incdirs)