Add range indicator

# To do:
- Dasagne
- Easter egg
- I'm a teapot
This commit is contained in:
2024-05-02 16:55:45 +02:00
parent 42dc301df0
commit dcb1cdf2a6
9 changed files with 100 additions and 24 deletions

View File

@@ -37,6 +37,7 @@ add_executable(Poulpes_de_l_espace_La_derniere_ligne_de_defense ${sourceCode}
src/PlayerDeadException.cpp
src/PlayerDeadException.h
src/Projectile.cpp
src/Projectile.h)
src/Projectile.h
)
target_link_libraries(Poulpes_de_l_espace_La_derniere_ligne_de_defense PRIVATE Qt6::Widgets Qt6::Sql)

View File

@@ -65,7 +65,7 @@ Enemy::Enemy(Enemy::Type type, Map &gameMap, int id, Game &game)
initializeEnemy(200, 50, 20, 0, 4, "../ressources/gladius.png", 0, 0, 20, 2, id);
break;
case(Zeus):
initializeEnemy(500, 300, 30, 0, 2, "../ressources/zeus.png", 0, 0, 30, 5, id);
initializeEnemy(500, 250, 30, 0, 2, "../ressources/zeus.png", 0, 0, 30, 5, id);
break;
case(Corsair):
initializeEnemy(1000, 500, 40, 0, 2, "../ressources/corsair.png", 0, 0, 40, 10, id);

View File

@@ -18,7 +18,7 @@ Game::Game(Menu* menu) : menu(menu)
this->setFocusPolicy(Qt::StrongFocus);
// Create the player object
player = new Player(100, 0, 10, 10, 1, "../ressources/player.png", 0, 0, gameMap, *this);
player = new Player(150, 0, 10, 10, 1, "../ressources/player.png", 0, 0, gameMap, *this);
// Create the text items for the health, gold and wave number
healthDisplay = new QGraphicsTextItem();
@@ -53,9 +53,9 @@ Game::Game(Menu* menu) : menu(menu)
}
void Game::start() {
// Heal the player to full health (100)
// Heal the player to full health (150)
int preiousHealth = player->getHealth();
player->heal(100 - preiousHealth);
player->heal(150 - preiousHealth);
// Create the map
gameMap.generateMap(25, 14);
@@ -301,7 +301,7 @@ void Game::upgradeTower(Tower* tower, QMouseEvent* event) {
// Create a menu to upgrade the tower
QMenu upgradeMenu;
// Check if the user has enough gold to upgrade the tower
if(userGold < 50) {
if(userGold < 25) {
QAction* notEnoughGold = upgradeMenu.addAction("Not enough gold to upgrade");
QAction* selectedAction = upgradeMenu.exec(event->globalPosition().toPoint());
}
@@ -327,15 +327,15 @@ void Game::upgradeTower(Tower* tower, QMouseEvent* event) {
}
}
else{
QAction* upgradeDamage = upgradeMenu.addAction("Upgrade Damage - 50 gold");
QAction* upgradeDamage = upgradeMenu.addAction("Upgrade Damage - 25 gold");
QAction* upgradeFireRate = upgradeMenu.addAction("Upgrade Fire Rate - 50 gold");
// Display the menu and wait for the user to select an action
QAction* selectedAction = upgradeMenu.exec(event->globalPosition().toPoint());
// Perform the selected upgrade
if (selectedAction == upgradeDamage && userGold >= 50) {
userGold -= 50;
if (selectedAction == upgradeDamage && userGold >= 25) {
userGold -= 25;
tower->upgradeDamage();
} else if (selectedAction == upgradeFireRate && userGold >= 50) {
userGold -= 50;
@@ -380,9 +380,26 @@ void Game::placeTower(int gridX, int gridY, QMouseEvent* event) {
if(event == nullptr || towerMenu.actions().isEmpty()) {
return;
}
auto isEmpty = towerMenu.actions().isEmpty();
auto point = event->globalPosition().toPoint();
QPoint point = event->globalPosition().toPoint();
// Check the validity of towerMenu
if (towerMenu.isEmpty()) {
qDebug() << "towerMenu is not valid";
} else {
qDebug() << "towerMenu is valid";
}
// Check the validity of each QAction
foreach (QAction* action, towerMenu.actions()) {
if (action == nullptr) {
qDebug() << "A QAction in towerMenu is not valid";
}
}
// Print out the QPoint object
qDebug() << "QPoint: " << point;
// Call exec()
QAction* selectedAction = towerMenu.exec(point);
// Check if selectedAction is nullptr before using it
@@ -419,7 +436,7 @@ void Game::mousePressEvent(QMouseEvent* event) {
placeTower(event);
}
void Game::endRound() const {
void Game::endRound() {
if(player->getHealth() == player->getPreviousHealth()) {
player->heal(5);
}
@@ -428,9 +445,13 @@ void Game::endRound() const {
void Game::clearTowers() {
for (auto* tower : towers) {
if (tower != nullptr && tower->getGraphics() != nullptr && tower->getGraphics()->scene() == &gameMap) {
if (tower->getGraphics() != nullptr && tower->getGraphics()->scene() == &gameMap) {
gameMap.removeItem(tower->getGraphics());
}
// Remove the rangeIndicator from the scene
if (tower->getRangeIndicator() != nullptr && tower->getRangeIndicator()->scene() == &gameMap) {
gameMap.removeItem(tower->getRangeIndicator());
}
delete tower;
}
// Clear the list of towers after deleting them

View File

@@ -19,6 +19,7 @@
#include "Menu.h"
#include "Gameover.h"
#include "Tower.h"
#include "Projectile.h"
class Player;
@@ -45,7 +46,7 @@ public:
void gameOver();
void resetGame();
void placeTower(QMouseEvent* event);
void endRound() const;
void endRound();
void clearTowers();
void upgradeTower(Tower* tower, QMouseEvent* event);
void placeTower(int gridX, int gridY, QMouseEvent* event);

View File

@@ -23,7 +23,7 @@ Leaderboard::Leaderboard(QWidget *parent) : QGraphicsScene(parent) {
leaderboardModel = new QSqlTableModel(this, db);
leaderboardModel->setTable("leaderboard");
// Sort by number of waves completed in descending order
leaderboardModel->setSort(2, Qt::DescendingOrder);
leaderboardModel->setSort(1, Qt::DescendingOrder);
leaderboardModel->select();
leaderboardTable->setModel(leaderboardModel);

View File

@@ -42,4 +42,8 @@ void Projectile::move() {
scene()->removeItem(this);
delete this;
}
}
QGraphicsRectItem* Projectile::getGraphics() {
return this;
}

View File

@@ -16,6 +16,7 @@ class Projectile : public QObject, public QGraphicsRectItem
Q_OBJECT
public:
Projectile(QPointF start, QPointF end);
QGraphicsRectItem* getGraphics();
public slots:
void move();

View File

@@ -18,6 +18,18 @@ Tower::Tower(int damage, double fireRate, int range, int level, int cost, QPoint
fireTimer = new QTimer();
connect(fireTimer, &QTimer::timeout, this, &Tower::fire);
fireTimer->start(fireRate * 1000);
int xTile = position.x() * 50;
int yTile = position.y() * 50;
rangeIndicator = new QGraphicsEllipseItem(xTile - range * 10, yTile - range * 10, range * 25, range * 25, this);
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(QColor(0, 0, 255, 25)); // Opacité de 10%
rangeIndicator->setBrush(brush);
rangeIndicator->setZValue(5);
QGraphicsScene* scene = game.scene();
if(scene != nullptr) {
scene->addItem(rangeIndicator);
}
}
void Tower::fireAtClosest(Enemy* target) const {
@@ -55,6 +67,7 @@ void Tower::fire() {
return;
}
auto* projectile = new Projectile(position, target->getPosition());
projectiles.push_back(projectile);
game.scene()->addItem(projectile);
fireAtClosest(target);
}
@@ -114,7 +127,7 @@ BalisticTower::BalisticTower(QPointF position, Game& game) : Tower(150, 2, 6, 1,
QPixmap scaledPixmap = pixmap.scaled(50, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); // Scale the pixmap to 50x50 pixels
graphics->setPixmap(scaledPixmap);
graphics->setPos(x * 50, y * 50);
graphics->setZValue(1);
graphics->setZValue(2);
}
}
@@ -131,7 +144,7 @@ DistorionTower::DistorionTower(QPointF position, Game& game) : Tower(100, 1, 7,
QPixmap scaledPixmap = pixmap.scaled(50, 50, Qt::KeepAspectRatio, Qt::SmoothTransformation); // Scale the pixmap to 50x50 pixels
graphics->setPixmap(scaledPixmap);
graphics->setPos(x * 50, y * 50);
graphics->setZValue(1);
graphics->setZValue(2);
}
}
@@ -141,4 +154,8 @@ int Tower::getDamageUpgrades() const {
int Tower::getFireRateUpgrades() const {
return fireRateUpgrades;
}
QGraphicsEllipseItem* Tower::getRangeIndicator() {
return rangeIndicator;
}

View File

@@ -9,15 +9,16 @@
#include <QVector>
#include <QGraphicsPixmapItem>
#include <QTimer>
#include <QGraphicsItem>
#include "Enemy.h"
#include "Game.h"
#include "Projectile.h"
class Projectile;
class Enemy;
class Game;
class Tower : public QObject
class Tower : public QObject, public QGraphicsItem
{
QOBJECT_H
protected:
@@ -28,22 +29,25 @@ protected:
int cost;
QPointF position;
std::string avatarPath;
QGraphicsPixmapItem* graphics{};
QGraphicsPixmapItem* graphics;
QTimer* fireTimer;
int damageUpgrades = 0;
int fireRateUpgrades = 0;
public:
Tower(int damage, double fireRate, int range, int level, int cost, QPointF position, std::string avatarPath, Game& game);
virtual ~Tower() = default;
~Tower() override = default;
QGraphicsPixmapItem* getGraphics();
void fireAtClosest(Enemy* target = nullptr) const;
Enemy* getClosestEnemyInRange(const QVector<Enemy*>& enemies);
Game& game;
void upgradeDamage();
void upgradeFireRate();
int getDamageUpgrades() const;
int getFireRateUpgrades() const;
[[nodiscard]] int getDamageUpgrades() const;
[[nodiscard]] int getFireRateUpgrades() const;
QVector<Projectile*> projectiles;
QGraphicsEllipseItem* rangeIndicator = nullptr;
QGraphicsEllipseItem* getRangeIndicator();
public slots:
void fire();
@@ -52,16 +56,43 @@ public slots:
class LaserTower : public Tower {
public:
explicit LaserTower(QPointF position, Game& game);
QRectF boundingRect() const override {
// Return the bounding rectangle of the tower
return QRectF(0, 0, 50, 50);
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override {
// Draw the tower
painter->drawPixmap(0, 0, 50, 50, QPixmap(QString::fromStdString(avatarPath)));
}
};
class BalisticTower : public Tower {
public:
explicit BalisticTower(QPointF position, Game& game);
QRectF boundingRect() const override {
// Return the bounding rectangle of the tower
return QRectF(0, 0, 50, 50);
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override {
// Draw the tower
painter->drawPixmap(0, 0, 50, 50, QPixmap(QString::fromStdString(avatarPath)));
}
};
class DistorionTower : public Tower {
public:
explicit DistorionTower(QPointF position, Game& game);
QRectF boundingRect() const override {
// Return the bounding rectangle of the tower
return QRectF(0, 0, 50, 50);
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override {
// Draw the tower
painter->drawPixmap(0, 0, 50, 50, QPixmap(QString::fromStdString(avatarPath)));
}
};