Compare commits

...

4 Commits

  1. 1
      src/Entity.cpp
  2. 5
      src/Entity.h
  3. 4
      src/Event.h
  4. 41
      src/Game.cpp
  5. 10
      src/Game.h
  6. 2
      src/Listener.cpp
  7. 1
      src/Listener.h
  8. 36
      src/Player.cpp
  9. 10
      src/Player.h
  10. 6
      src/Queue.h
  11. 12
      src/Spectator.cpp
  12. 5
      src/Spectator.h
  13. 26
      src/Wall.cpp
  14. 17
      src/Wall.h

@ -1 +0,0 @@
#include "Entity.h"

@ -1,5 +0,0 @@
#pragma once
class Entity {
};

@ -56,3 +56,7 @@ struct WallJumpEvent : GameEvent {
double wallHeight = 0; double wallHeight = 0;
Player * player = nullptr; Player * player = nullptr;
}; };
struct WallCrashEvent : GameEvent {
Player * player = nullptr;
};

@ -2,28 +2,61 @@
#include "Game.h" #include "Game.h"
#include "InputWindow.h" #include "InputWindow.h"
#include "Window.h" #include "Window.h"
#include <random>
void Game::draw(QPixmap &output) { void Game::draw(QPixmap &output) {
QPainter p(&output); QPainter p(&output);
p.drawText(50, 50, QString::fromStdString(std::to_string(int(window->currentFPS))));
for (auto & spectator : spectators) for (auto & spectator : spectators)
spectator.draw(p); spectator.draw(p);
for (auto & wall : walls)
wall.draw(p);
player.draw(p); player.draw(p);
} }
void Game::update(float dTime) { void Game::update(float dTime) {
eTime += dTime; eTime += dTime;
player.update(dTime); player.update(dTime, walls);
for (auto & wall : walls)
wall.update(dTime);
tryCreateWall();
removeWalls();
}
void Game::tryCreateWall() {
if (Game::Random(0, 1000) > 990){
walls.emplace_back();
}
}
void Game::removeWalls() {
erase_if(walls, [](const Wall& wall){
return wall.isLost();
});
} }
Game::Game() { Game::Game() {
for (auto & spectator : spectators){ constexpr size_t sCount = 10;
Game::eventQueue->registerListener(&spectator); const int w = WIDTH / sCount;
for (size_t i = 0; i < sCount; i++){
Spectator spec;
spec.pos = QPoint(int(i) * w, SPEC_Y / 2);
spectators.push_back(spec);
} }
for (auto & spec : spectators)
Game::eventQueue->registerListener(&spec);
InputWindow::inputQueue->registerListener(&player); InputWindow::inputQueue->registerListener(&player);
instance = this; instance = this;
} }
GameQueue * Game::eventQueue = new GameQueue; GameQueue * Game::eventQueue = new GameQueue;
Game * Game::instance = nullptr; Game * Game::instance = nullptr;
double Game::Random(double low, double high) {
std::random_device device;
std::mt19937 gen(device());
auto dist = std::uniform_real_distribution<double>(low, high);
return dist(gen);
}

@ -3,6 +3,7 @@
#include "Queue.h" #include "Queue.h"
#include "Player.h" #include "Player.h"
#include "Spectator.h" #include "Spectator.h"
#include "Wall.h"
#define WIDTH 1000 #define WIDTH 1000
#define HEIGHT 500 #define HEIGHT 500
@ -12,9 +13,14 @@
class Window; class Window;
class Game { class Game {
Player player; Player player;
std::vector<Spectator> spectators {5}; std::vector<Spectator> spectators;
std::vector<Wall> walls;
void tryCreateWall();
void removeWalls();
public: public:
Window * window; static double Random(double low, double high);
Window * window = nullptr;
// seconds
float eTime = 0; float eTime = 0;
static Game * instance; static Game * instance;
static GameQueue * eventQueue; static GameQueue * eventQueue;

@ -3,6 +3,8 @@
void GameListener::accept(GameEvent *event) { void GameListener::accept(GameEvent *event) {
if (auto wallJumpEvent = dynamic_cast<WallJumpEvent *>(event)) if (auto wallJumpEvent = dynamic_cast<WallJumpEvent *>(event))
OnWallJumped(wallJumpEvent); OnWallJumped(wallJumpEvent);
if (auto wallCrashEvent = dynamic_cast<WallCrashEvent *>(event))
OnWallCrashed(wallCrashEvent);
} }
void InputListener::accept(InputEvent *event) { void InputListener::accept(InputEvent *event) {

@ -27,4 +27,5 @@ public:
void accept(GameEvent * event) override; void accept(GameEvent * event) override;
protected: protected:
virtual void OnWallJumped(WallJumpEvent * event) {}; virtual void OnWallJumped(WallJumpEvent * event) {};
virtual void OnWallCrashed(WallCrashEvent * event) {};
}; };

@ -4,26 +4,20 @@
#include "Game.h" #include "Game.h"
void Player::mousePressed(MouseEvent *event) { void Player::mousePressed(MouseEvent *event) {
if (pos.y() == GROUND_Y && event->button == Qt::MouseButton::LeftButton){ if (pos.y() == GROUND_Y && event->button == Qt::MouseButton::LeftButton)
jump(); jump();
auto e = new WallJumpEvent;
e->time = Game::instance->eTime;
e->player = this;
e->wallHeight = 100;
Game::eventQueue->submitEvent(e);
}
} }
void Player::draw(QPainter &painter) const { void Player::draw(QPainter &painter) const {
painter.save(); painter.save();
painter.translate(pos.toPoint()); painter.translate(pos.toPoint());
painter.fillRect(-5, -5, 10, 10, Qt::black); painter.fillRect(-5, -10, 10, 10, Qt::black);
painter.restore(); painter.restore();
} }
void Player::update(float dTime) { void Player::update(float dTime, std::vector<Wall> &walls) {
pos += vel * dTime; pos += vel * dTime;
vel += acc * dTime; vel += acc * dTime;
@ -31,9 +25,31 @@ void Player::update(float dTime) {
pos.setY(GROUND_Y); pos.setY(GROUND_Y);
vel = {}; vel = {};
} }
for (auto &wall : walls){
if (!wall.jumped && !wall.failed){
if (pos.x() > wall.pos.x() - wall.size.width() / 2
&& pos.x() < wall.pos.x() + wall.size.width() / 2){
if (pos.y() < wall.pos.y() - wall.size.height()){
wall.jumped = true;
auto e = new WallJumpEvent;
e->time = Game::instance->eTime;
e->player = this;
e->wallHeight = wall.size.height();
Game::eventQueue->submitEvent(e);
} else {
wall.failed = true;
auto e = new WallCrashEvent;
e->time = Game::instance->eTime;
e->player = this;
Game::eventQueue->submitEvent(e);
}
}
}
}
} }
void Player::jump() { void Player::jump() {
vel += {0, -300}; vel += {0, -jumpPower};
Audio::playSound(1, SOUND_JUMP); Audio::playSound(1, SOUND_JUMP);
} }

@ -2,18 +2,20 @@
#include "Listener.h" #include "Listener.h"
#include "Event.h" #include "Event.h"
#include "Entity.h" #include "Wall.h"
#include <QPainter> #include <QPainter>
class Player : public Entity, public InputListener { class Player : public InputListener {
QVector2D pos {50, 50}; QVector2D pos {100, 50};
QVector2D vel {}; QVector2D vel {};
QVector2D acc {0, 9.81 * 30}; QVector2D acc {0, 9.81 * 30};
static constexpr float jumpPower = 400;
void jump(); void jump();
public: public:
void draw(QPainter &painter) const; void draw(QPainter &painter) const;
void update(float dTime); void update(float dTime, std::vector<Wall>&);
protected: protected:
void mousePressed(MouseEvent *) override; void mousePressed(MouseEvent *) override;

@ -9,7 +9,7 @@
#include <mutex> #include <mutex>
#include <unordered_set> #include <unordered_set>
#define MAX_QUEUE_SIZE 10 #define MAX_QUEUE_SIZE 100
template<typename T> template<typename T>
class Queue { class Queue {
@ -36,7 +36,9 @@ protected:
return tail == head; return tail == head;
} }
size_t size() const { size_t size() const {
return container.size(); if (tail > head)
return tail - head;
return MAX_QUEUE_SIZE - head + tail;
} }
T * pop(){ T * pop(){
mutex.lock(); mutex.lock();

@ -7,6 +7,18 @@ void Spectator::OnWallJumped(WallJumpEvent *event) {
std::cout << "Wall jump at " << event->time << std::endl; std::cout << "Wall jump at " << event->time << std::endl;
} }
void Spectator::OnWallCrashed(WallCrashEvent *event) {
std::cout << "Wall crash at " << event->time << std::endl;
}
void Spectator::draw(QPainter &painter) const { void Spectator::draw(QPainter &painter) const {
painter.save();
painter.translate(pos);
painter.drawText(0, 0, QString("Hello"));
painter.restore();
} }

@ -1,11 +1,12 @@
#pragma once #pragma once
#include "Entity.h"
#include "Listener.h" #include "Listener.h"
class Spectator : public Entity, public GameListener { class Spectator : public GameListener {
protected: protected:
void OnWallJumped(WallJumpEvent * event) override; void OnWallJumped(WallJumpEvent * event) override;
void OnWallCrashed(WallCrashEvent * event) override;
public: public:
QPoint pos;
void draw(QPainter &painter) const; void draw(QPainter &painter) const;
}; };

@ -0,0 +1,26 @@
#include "Wall.h"
#include "Game.h"
void Wall::draw(QPainter &painter) const {
painter.save();
int w = size.width();
int h = size.height();
painter.translate(pos.toPoint());
painter.fillRect(w / 2, -h, w, h, Qt::black);
painter.restore();
}
void Wall::update(float dTime) {
pos.setX(pos.x() - dTime * velocity);
}
Wall::Wall() {
pos = {WIDTH, GROUND_Y};
size = QSize(int(Game::Random(30, 60)), int(Game::Random(30, 150)));
}
bool Wall::isLost() const {
return pos.x() < -100;
}

@ -0,0 +1,17 @@
#pragma once
#include <QPainter>
#include <QVector2D>
class Wall {
float velocity = 300;
public:
bool jumped = false;
bool failed = false;
QVector2D pos;
QSize size;
bool isLost() const;
explicit Wall();
void draw(QPainter &painter) const;
void update(float dTime);
};
Loading…
Cancel
Save