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:
parent
00fdd89b88
commit
c651dcd038
30 changed files with 551 additions and 131 deletions
24
.vscode/launch.json
vendored
24
.vscode/launch.json
vendored
|
@ -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",
|
"name": "(gdb) Launch gl.elf",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
|
|
|
@ -84,7 +84,7 @@ void Cube::model() {
|
||||||
// glNormal3f(nx, ny, nz);
|
// glNormal3f(nx, ny, nz);
|
||||||
// drawCalls += 1;
|
// drawCalls += 1;
|
||||||
} else {
|
} else {
|
||||||
normals.push_back(Engine::Vector3::zero());
|
normals.push_back(Vector3::zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if `texcoord_index` is zero or positive. negative = no
|
// Check if `texcoord_index` is zero or positive. negative = no
|
||||||
|
@ -99,7 +99,7 @@ void Cube::model() {
|
||||||
// glTexCoord2f(tx, ty);
|
// glTexCoord2f(tx, ty);
|
||||||
// drawCalls += 1;
|
// drawCalls += 1;
|
||||||
} else {
|
} else {
|
||||||
textureCoords.push_back(Vector3::zero());
|
textureCoords.push_back(Vector3::zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
index_offset += fv;
|
index_offset += fv;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
sources = []
|
sources = []
|
||||||
incdirs = include_directories('.')
|
|
||||||
|
|
||||||
if host_machine.system() == 'dreamcast'
|
if host_machine.system() == 'dreamcast'
|
||||||
sources += 'dreamcastController.cc'
|
sources += 'dreamcastController.cc'
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
|
|
||||||
#ifdef _arch_dreamcast
|
#ifdef _arch_dreamcast
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
|
||||||
#include "dreamcastEngine.hh"
|
#include "dreamcastEngine.hh"
|
||||||
#else
|
#else
|
||||||
#include "linuxEngine.hh"
|
#include "linuxEngine.hh"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
void Engine::initializeEngine() {
|
void Engine::initializeEngine() {
|
||||||
|
@ -26,26 +28,21 @@ void Engine::initializeController() {
|
||||||
engine->initializeController();
|
engine->initializeController();
|
||||||
controller = engine->controller;
|
controller = engine->controller;
|
||||||
}
|
}
|
||||||
void Engine::SwapBuffers() {
|
void Engine::SwapBuffers() const { engine->SwapBuffers(); }
|
||||||
engine->SwapBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Engine::ShouldWindowClose() {
|
bool Engine::ShouldWindowClose() const { return engine->ShouldWindowClose(); }
|
||||||
return engine->ShouldWindowClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Engine::~Engine() {
|
Engine::~Engine() { delete engine; }
|
||||||
delete engine;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::initScreen() {
|
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);
|
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() {
|
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 (controller->IsButtonPressed(button)) {
|
||||||
if (!(buttonsPressed & button)) {
|
if (!(buttonsPressed & button)) {
|
||||||
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) {
|
const Engine::Vector3 Engine::Vector3::zero = {0, 0, 0};
|
||||||
constexpr int xSize = 640, ySize = 480;
|
|
||||||
|
|
||||||
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; }
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
#include "controller/controller.hh"
|
#include "controller/controller.hh"
|
||||||
#include "nativeEngine.hh"
|
#include "nativeEngine.hh"
|
||||||
|
|
||||||
|
#ifdef _arch_dreamcast
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#else
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
protected:
|
protected:
|
||||||
static constexpr float microSecond = 0.000001f;
|
static constexpr float microSecond = 0.000001f;
|
||||||
|
@ -19,33 +25,36 @@ class Engine {
|
||||||
bool thirtyfps;
|
bool thirtyfps;
|
||||||
unsigned int buttonsPressed;
|
unsigned int buttonsPressed;
|
||||||
|
|
||||||
Controller* controller = nullptr;
|
|
||||||
|
|
||||||
virtual void initScreen();
|
virtual void initScreen();
|
||||||
virtual void gameLoop(){};
|
virtual void gameLoop(){};
|
||||||
void printSystemInformation();
|
void printSystemInformation();
|
||||||
void pressButton(Controller::Button button, std::function<void()> callback);
|
void SwapBuffers() const;
|
||||||
void glVertex3fNormalized(float x, float y, float z);
|
bool ShouldWindowClose() const;
|
||||||
void SwapBuffers();
|
|
||||||
bool ShouldWindowClose();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
NativeEngine* engine = nullptr;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void deltaTimeLoop(T&& callback, struct timeval& beginningOfFrame,
|
void deltaTimeLoop(T&& callback, struct timeval& beginningOfFrame,
|
||||||
struct timeval& endOfFrame);
|
struct timeval& endOfFrame);
|
||||||
NativeEngine* engine = nullptr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void initializeController();
|
void initializeController();
|
||||||
void initializeEngine();
|
void initializeEngine();
|
||||||
void initializeGameLoop();
|
void initializeGameLoop();
|
||||||
void cleanupEngine();
|
void cleanupEngine();
|
||||||
|
float getDeltaTime() const;
|
||||||
|
void pressButton(Controller::Button button, std::function<void()> callback);
|
||||||
virtual ~Engine();
|
virtual ~Engine();
|
||||||
|
Controller* controller = nullptr;
|
||||||
struct Vector3 {
|
struct Vector3 {
|
||||||
static Vector3 zero();
|
Vector3 operator/(float amount);
|
||||||
|
void operator/=(float amount);
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
float z;
|
float z;
|
||||||
|
static const Vector3 zero;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
56
src/engine/entity.cc
Normal file
56
src/engine/entity.cc
Normal 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
27
src/engine/entity.hh
Normal 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
|
|
@ -1,4 +1,3 @@
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
#include "linuxEngine.hh"
|
#include "linuxEngine.hh"
|
||||||
|
@ -6,7 +5,7 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "linuxController.hh"
|
#include "controller/linuxController.hh"
|
||||||
|
|
||||||
void LinuxEngine::initializeEngine() {
|
void LinuxEngine::initializeEngine() {
|
||||||
glfwInit();
|
glfwInit();
|
||||||
|
|
|
@ -10,5 +10,5 @@ endif
|
||||||
|
|
||||||
subdir('controller')
|
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)
|
engine_dep = declare_dependency(link_with: [engine, controller], include_directories: incdirs)
|
||||||
|
|
9
src/flappyBird.cc
Normal file
9
src/flappyBird.cc
Normal 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
33
src/flappyBird/Bird.cc
Normal 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
16
src/flappyBird/Bird.hh
Normal 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
|
56
src/flappyBird/FlappyBird.cc
Normal file
56
src/flappyBird/FlappyBird.cc
Normal 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;
|
||||||
|
}
|
22
src/flappyBird/FlappyBird.hh
Normal file
22
src/flappyBird/FlappyBird.hh
Normal 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
54
src/flappyBird/Pipes.cc
Normal 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
26
src/flappyBird/Pipes.hh
Normal 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
|
8
src/flappyBird/meson.build
Normal file
8
src/flappyBird/meson.build
Normal 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)
|
70
src/gl.cc
70
src/gl.cc
|
@ -1,75 +1,9 @@
|
||||||
#ifdef _arch_dreamcast
|
#include "gl/Gl.hh"
|
||||||
#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());
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Glcc* engine = new Glcc;
|
Glcc* engine = new Glcc;
|
||||||
engine->initializeEngine();
|
engine->initializeEngine();
|
||||||
engine->initializeController();
|
engine->initializeController();
|
||||||
engine->initializeGameLoop();
|
engine->initializeGameLoop();
|
||||||
|
delete engine;
|
||||||
}
|
}
|
||||||
|
|
15
src/gl/Gl.cc
Normal file
15
src/gl/Gl.cc
Normal 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
14
src/gl/Gl.hh
Normal 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
52
src/gl/GlEntity.cc
Normal 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
15
src/gl/GlEntity.hh
Normal 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
9
src/gl/meson.build
Normal 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)
|
||||||
|
|
||||||
|
|
26
src/hello.cc
26
src/hello.cc
|
@ -3,32 +3,8 @@
|
||||||
#else
|
#else
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#endif
|
#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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
Hello* engine = new Hello;
|
Hello* engine = new Hello;
|
||||||
|
|
11
src/hello/Hello.cc
Normal file
11
src/hello/Hello.cc
Normal 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
12
src/hello/Hello.hh
Normal 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
16
src/hello/HelloEntity.cc
Normal 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
9
src/hello/HelloEntity.hh
Normal 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
8
src/hello/meson.build
Normal 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)
|
||||||
|
|
|
@ -40,6 +40,7 @@ endif
|
||||||
subdir('engine')
|
subdir('engine')
|
||||||
|
|
||||||
deps += [engine_dep]
|
deps += [engine_dep]
|
||||||
|
srcinc = include_directories('./')
|
||||||
|
|
||||||
cube_sources = [
|
cube_sources = [
|
||||||
'cube.cc'
|
'cube.cc'
|
||||||
|
@ -49,6 +50,13 @@ if host_machine.system() == 'dreamcast'
|
||||||
cube_sources += romdsk_o
|
cube_sources += romdsk_o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
executable('hello.elf', ['hello.cc'], dependencies: deps, include_directories: incdirs)
|
incdirs += [srcinc]
|
||||||
executable('gl.elf', ['gl.cc'], dependencies: deps, include_directories: incdirs)
|
|
||||||
|
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('cube.elf', cube_sources, dependencies: deps, include_directories: incdirs)
|
||||||
|
executable('flappyBird.elf', ['flappyBird.cc'], dependencies: [deps] + [flappy_dep], include_directories: incdirs)
|
||||||
|
|
Loading…
Reference in a new issue