mirror of
https://github.com/BreizhHardware/Poulpes-de-l-Espace-La-derniere-ligne-de-Defense.git
synced 2026-03-18 21:30:36 +01:00
Add range indicator
# To do: - Dasagne - Easter egg - I'm a teapot
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
43
src/Game.cpp
43
src/Game.cpp
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -42,4 +42,8 @@ void Projectile::move() {
|
||||
scene()->removeItem(this);
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsRectItem* Projectile::getGraphics() {
|
||||
return this;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ class Projectile : public QObject, public QGraphicsRectItem
|
||||
Q_OBJECT
|
||||
public:
|
||||
Projectile(QPointF start, QPointF end);
|
||||
QGraphicsRectItem* getGraphics();
|
||||
|
||||
public slots:
|
||||
void move();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
45
src/Tower.h
45
src/Tower.h
@@ -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)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user