diff --git a/src/Coin.cpp b/src/Coin.cpp new file mode 100644 index 0000000..c01cde7 --- /dev/null +++ b/src/Coin.cpp @@ -0,0 +1,28 @@ +#include "Coin.h" +#include "Game.h" + +void Coin::draw(QPainter &painter) const { + painter.save(); + + painter.translate(pos); + painter.setBrush(QBrush(Qt::yellow, Qt::SolidPattern)); + painter.drawEllipse(QPoint(), radius, radius); + + painter.drawText(QRect(-radius, -radius, radius * 2, radius * 2), Qt::AlignCenter, QString::fromStdString(std::to_string(value))); + + painter.restore(); +} + +bool Coin::isLost() const { + return pos.x() < -100; +} + +Coin::Coin() { + int y = int(Game::Random(SPEC_Y, GROUND_Y)); + pos = {WIDTH, y}; + value = int(Game::Random(30, 37)); +} + +void Coin::update(float dTime) { + pos.setX(float(pos.x()) - velocity * dTime); +} diff --git a/src/Coin.h b/src/Coin.h new file mode 100644 index 0000000..d387740 --- /dev/null +++ b/src/Coin.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +class Coin { +public: + explicit Coin(); + bool collected = false; + QPoint pos; + float velocity = 150; + int value; + int radius = 15; + bool isLost() const; + void draw(QPainter &painter) const; + void update(float dTime); +}; diff --git a/src/Event.h b/src/Event.h index cbe4205..3ecbdff 100644 --- a/src/Event.h +++ b/src/Event.h @@ -59,4 +59,9 @@ struct WallJumpEvent : GameEvent { struct WallCrashEvent : GameEvent { Player * player = nullptr; +}; + +struct CoinCollectEvent : GameEvent { + Player * player = nullptr; + int value = 0; }; \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index 8815837..c61ad92 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -12,22 +12,38 @@ void Game::draw(QPixmap &output) { spectator.draw(p); for (auto & wall : walls) wall.draw(p); + for (auto & coin : coins) + coin.draw(p); player.draw(p); } void Game::update(float dTime) { eTime += dTime; - player.update(dTime, walls); + player.update(dTime, walls, coins); for (auto & wall : walls) wall.update(dTime); + for (auto & coin : coins) + coin.update(dTime); + tryCreateCoin(); + removeCoins(); tryCreateWall(); removeWalls(); } +void Game::tryCreateCoin() { + if (Game::Random(0, 1000) > 995) + coins.emplace_back(); +} + +void Game::removeCoins() { + erase_if(coins, [](const Coin& coin){ + return coin.isLost() || coin.collected; + }); +} + void Game::tryCreateWall() { - if (Game::Random(0, 1000) > 990){ + if (Game::Random(0, 1000) > 990) walls.emplace_back(); - } } void Game::removeWalls() { diff --git a/src/Game.h b/src/Game.h index 6658ee3..c35420a 100644 --- a/src/Game.h +++ b/src/Game.h @@ -4,6 +4,7 @@ #include "Player.h" #include "Spectator.h" #include "Wall.h" +#include "Coin.h" #define WIDTH 1000 #define HEIGHT 500 @@ -15,6 +16,9 @@ class Game { Player player; std::vector spectators; std::vector walls; + std::vector coins; + void tryCreateCoin(); + void removeCoins(); void tryCreateWall(); void removeWalls(); public: diff --git a/src/Listener.cpp b/src/Listener.cpp index 01a563c..2181dcf 100644 --- a/src/Listener.cpp +++ b/src/Listener.cpp @@ -5,6 +5,8 @@ void GameListener::accept(GameEvent *event) { OnWallJumped(wallJumpEvent); if (auto wallCrashEvent = dynamic_cast(event)) OnWallCrashed(wallCrashEvent); + if (auto coinCollectEvent = dynamic_cast(event)) + OnCoinCollected(coinCollectEvent); } void InputListener::accept(InputEvent *event) { diff --git a/src/Listener.h b/src/Listener.h index aae05e9..4474ced 100644 --- a/src/Listener.h +++ b/src/Listener.h @@ -28,4 +28,5 @@ public: protected: virtual void OnWallJumped(WallJumpEvent * event) {}; virtual void OnWallCrashed(WallCrashEvent * event) {}; + virtual void OnCoinCollected(CoinCollectEvent * event) {}; }; \ No newline at end of file diff --git a/src/Player.cpp b/src/Player.cpp index d050620..5994ca3 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -12,12 +12,12 @@ void Player::draw(QPainter &painter) const { painter.save(); painter.translate(pos.toPoint()); - painter.fillRect(-5, -10, 10, 10, Qt::black); + painter.fillRect(-5, -10, 10, 10, Qt::darkGreen); painter.restore(); } -void Player::update(float dTime, std::vector &walls) { +void Player::update(float dTime, std::vector &walls, std::vector& coins) { pos += vel * dTime; vel += acc * dTime; @@ -47,6 +47,18 @@ void Player::update(float dTime, std::vector &walls) { } } } + for (auto &coin : coins){ + if (coin.collected) + continue; + if (pos.distanceToPoint(QVector2D(coin.pos.x(), coin.pos.y())) <= coin.radius){ + coin.collected = true; + auto e = new CoinCollectEvent; + e->time = Game::instance->eTime; + e->player = this; + e->value = coin.value; + Game::eventQueue->submitEvent(e); + } + } } void Player::jump() { diff --git a/src/Player.h b/src/Player.h index e0304f8..fed1b07 100644 --- a/src/Player.h +++ b/src/Player.h @@ -3,6 +3,7 @@ #include "Listener.h" #include "Event.h" #include "Wall.h" +#include "Coin.h" #include class Player : public InputListener { @@ -15,7 +16,7 @@ class Player : public InputListener { void jump(); public: void draw(QPainter &painter) const; - void update(float dTime, std::vector&); + void update(float dTime, std::vector&, std::vector&); protected: void mousePressed(MouseEvent *) override; diff --git a/src/Spectator.cpp b/src/Spectator.cpp index df597cb..e309a99 100644 --- a/src/Spectator.cpp +++ b/src/Spectator.cpp @@ -6,11 +6,11 @@ void Spectator::OnWallJumped(WallJumpEvent *event) { float timeDiff = Game::instance->eTime - event->time; if (timeDiff > 2){ - currentMessage = "Ignored event"; + currentMessage = "Ignored jump"; return; } - currentMessage = "Calculating prime..."; + currentMessage = "Calculating Prime..."; int prime = getHighPrime(); currentMessage = std::to_string(prime); } @@ -19,6 +19,14 @@ void Spectator::OnWallCrashed(WallCrashEvent *event) { currentMessage = "Crash!"; } +void Spectator::OnCoinCollected(CoinCollectEvent *event) { + int value = event->value; + + currentMessage = "Calculating Fibo(" + std::to_string(value) + ")"; + int fib = getHighFibonacci(value); + currentMessage = std::to_string(fib); +} + void Spectator::draw(QPainter &painter) const { painter.save(); @@ -67,4 +75,13 @@ int Spectator::getHighPrime() { return 2; } +int Spectator::getHighFibonacci(int val) { + std::function fib = [&fib](int n){ + if (n == 1 || n == 2) + return n; + return fib(n - 1) + fib(n - 2); + }; + return fib(val); +} + diff --git a/src/Spectator.h b/src/Spectator.h index 5d480de..9c1f167 100644 --- a/src/Spectator.h +++ b/src/Spectator.h @@ -6,8 +6,10 @@ class Spectator : public GameListener { protected: void OnWallJumped(WallJumpEvent * event) override; void OnWallCrashed(WallCrashEvent * event) override; + void OnCoinCollected(CoinCollectEvent * event) override; std::string currentMessage; static int getHighPrime(); + static int getHighFibonacci(int val); public: QPoint pos; QSize size; diff --git a/src/Wall.cpp b/src/Wall.cpp index 270331d..6aa09cb 100644 --- a/src/Wall.cpp +++ b/src/Wall.cpp @@ -7,7 +7,7 @@ void Wall::draw(QPainter &painter) const { int w = size.width(); int h = size.height(); painter.translate(pos.toPoint()); - painter.fillRect(w / 2, -h, w, h, Qt::black); + painter.fillRect(w / 2, -h, w, h, Qt::red); painter.restore(); }