Add enemy spawn (not auto launch of the next wave) (no animation), movement of the enemy and kill by the player (need to handle player don't have any health remaining)

This commit is contained in:
2024-04-29 11:30:39 +02:00
parent 7f3ac60953
commit 086e13ba37
13 changed files with 191 additions and 19 deletions

BIN
ressources/enemy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -4,8 +4,57 @@
#include "Enemy.h"
Enemy::Enemy(int health, int shield, int damage, float regenerationRate, int speed, std::string avatarPath, int x, int y, int coinDrop, int weight)
: Mob(health, shield, damage, regenerationRate, speed, avatarPath, x, y) {
Enemy::Enemy(int health, int shield, int damage, float regenerationRate, int speed, std::string avatarPath, int x, int y, int coinDrop, int weight, Map& gameMap)
: Mob(health, shield, damage, regenerationRate, speed, avatarPath, x, y), gameMap(gameMap) {
this->coinDrop = coinDrop;
this->weight = weight;
moveTimer = new QTimer();
QPixmap pixmap(QString::fromStdString(avatarPath));
if (pixmap.isNull()) {
} else {
graphics = new QGraphicsPixmapItem();
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); // Set the Z-value to 1 to draw the enemy on top of the map tiles
}
connect(moveTimer, SIGNAL(timeout()), this, SLOT(onMoveTimerTimeout()));
moveTimer->start(1000 / speed);
}
int Enemy::getWeight() {
return weight;
}
int Enemy::getCoinDrop() {
return coinDrop;
}
QGraphicsPixmapItem* Enemy::getGraphics() {
return graphics;
}
Tile* Enemy::getNextPathTile() {
// Check all the tiles around the enemy and return the one who is a path tile
Tile* nextTile = nullptr;
if (gameMap.getTile(x + 1, y)->isPath()) {
nextTile = gameMap.getTile(x + 1, y);
} else if (gameMap.getTile(x, y - 1)->isPath()) {
nextTile = gameMap.getTile(x, y - 1);
}
return nextTile;
}
void Enemy::moveEnemy() {
// Move the enemy to the next path tile
nextStep = getNextPathTile();
if (nextStep != nullptr) {
x = nextStep->gridX();
y = nextStep->gridY();
graphics->setPos(x * 50, y * 50);
}
}
void Enemy::onMoveTimerTimeout() {
moveEnemy();
}

View File

@@ -4,14 +4,32 @@
#ifndef POULPES_DE_L_ESPACE_LA_DERNIERE_LIGNE_DE_DEFENSE_ENEMY_H
#define POULPES_DE_L_ESPACE_LA_DERNIERE_LIGNE_DE_DEFENSE_ENEMY_H
#include <QGraphicsPixmapItem>
#include <QTimer>
#include "Mob.h"
#include "Map.h"
class Enemy : public Mob
{
Q_OBJECT
public:
Enemy(int health, int shield, int damage, float regenerationRate, int speed, std::string avatarPath, int x, int y, int coinDrop, int weight);
Enemy(int health, int shield, int damage, float regenerationRate, int speed, std::string avatarPath, int x, int y, int coinDrop, int weight, Map& gameMap);
int getWeight();
int getCoinDrop();
QGraphicsPixmapItem* getGraphics();
void moveEnemy();
Tile* getNextPathTile();
private slots:
void onMoveTimerTimeout();
private:
int coinDrop;
int weight;
Map& gameMap;
QGraphicsPixmapItem* graphics;
QTimer* moveTimer;
Tile* nextStep;
};

View File

@@ -3,6 +3,7 @@
//
#include "Game.h"
#include "Player.h"
#include <QGraphicsView>
#include <iostream>
#include <QDebug>
@@ -16,7 +17,7 @@ Game::Game(){
this->setFocusPolicy(Qt::StrongFocus);
// Create the player object
player = new Player(100, 0, 10, 10, 1, "../ressources/player.png", 0, 0, gameMap);
player = new Player(100, 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();
@@ -70,6 +71,9 @@ void Game::start() {
// Set focus to the QGraphicsView
this->setFocus();
// Spawn the enemies
spawnEnemies(waveNumber);
}
void Game::keyPressEvent(QKeyEvent *event) {
@@ -95,4 +99,25 @@ void Game::updateDisplay() {
healthDisplay->setPlainText("Health: " + QString::number(player->getHealth()));
goldDisplay->setPlainText("Gold: " + QString::number(userGold));
waveDisplay->setPlainText("Wave: " + QString::number(waveNumber));
}
void Game::spawnEnemies(int waveNumber) {
int totalWeight = 0;
int targetWeight = waveNumber * waveNumber;
// Get the start tile of the map
Tile* startTile = gameMap.getStartTile();
// Get start tile coordinates
int x = startTile->gridX();
int y = startTile->gridY();
while (totalWeight < targetWeight){
// Create a new enemy on the start tile
Enemy* enemy = new Enemy(10, 0, 5, 0, 1, "../ressources/enemy.png", x, y, 1, 1, gameMap);
totalWeight += enemy->getWeight();
currentEnemies.push_back(enemy);
gameMap.addItem(enemy->getGraphics());
// Wait for 1 second before spawning the next enemy
QThread::sleep(1);
}
}

View File

@@ -8,8 +8,12 @@
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QKeyEvent>
#include <QThread>
#include "Map.h"
#include "Player.h"
#include "Enemy.h"
class Player;
class Game : public QGraphicsView
{
@@ -18,9 +22,11 @@ public:
void start();
Map gameMap;
void updateDisplay();
void spawnEnemies(int waveNumber);
int userGold;
std::vector<Enemy*> currentEnemies;
private:
int userGold;
QTimer gameTimer;
int waveNumber;
Player* player;

View File

@@ -114,4 +114,11 @@ int Map::getWidth() {
int Map::getHeight() {
return height;
}
Tile* Map::getTile(int x, int y) {
if (x >= 0 && x < width && y >= 0 && y < height){
return tiles[y][x];
}
return nullptr;
}

View File

@@ -11,18 +11,14 @@ class Map : public QGraphicsScene
{
public:
Map(QObject* parent = nullptr);
void generateMap(int width, int height);
void show();
Tile* getEndTile();
Tile* getStartTile();
QGraphicsScene scene;
int getWidth();
int getHeight();
Tile* getTile(int x, int y);
private:
QVector<QVector<Tile*>> tiles;

View File

@@ -17,4 +17,28 @@ Mob::Mob(int health, int shield, int damage, float regenerationRate, int speed,
int Mob::getHealth() {
return health;
}
int Mob::getShield() {
return shield;
}
int Mob::getDamage() {
return damage;
}
float Mob::getRegenerationRate() {
return regenerationRate;
}
int Mob::getSpeed() {
return speed;
}
int Mob::getX() {
return x;
}
int Mob::getY() {
return y;
}

View File

@@ -5,8 +5,11 @@
#ifndef POULPES_DE_L_ESPACE_LA_DERNIERE_LIGNE_DE_DEFENSE_MOB_H
#define POULPES_DE_L_ESPACE_LA_DERNIERE_LIGNE_DE_DEFENSE_MOB_H
#include <string>
#include <QObject>
class Mob {
class Mob : public QObject
{
Q_OBJECT
protected:
int health;
int shield;
@@ -20,6 +23,12 @@ protected:
public:
Mob(int health, int shield, int damage, float regenerationRate, int speed, std::string avatarPath, int x, int y);
int getHealth();
int getShield();
int getDamage();
float getRegenerationRate();
int getSpeed();
int getX();
int getY();
};

View File

@@ -5,8 +5,8 @@
#include "Player.h"
#include <iostream>
Player::Player(int health, int shield, int damage, float regenerationRate, int speed, const std::string& avatarPath, int x, int y, Map& gameMap)
: Mob(health, shield, damage, regenerationRate, speed, avatarPath, x, y), gameMap(gameMap) {
Player::Player(int health, int shield, int damage, float regenerationRate, int speed, const std::string& avatarPath, int x, int y, Map& gameMap, Game& game)
: Mob(health, shield, damage, regenerationRate, speed, avatarPath, x, y), gameMap(gameMap), game(game) {
this->x = x;
this->y = y;
QPixmap pixmap(QString::fromStdString(avatarPath));
@@ -24,12 +24,25 @@ Player::Player(int health, int shield, int damage, float regenerationRate, int s
void Player::setPosition(Tile* tile) {
this->x = tile->gridX();
this->y = tile->gridY();
graphics->setPos(x * 50, y * 50);
for (Enemy* enemy : game.currentEnemies) {
if (enemy->getX() == x && enemy->getY() == y) {
// If there is an enemy, call the touchEnemy method
touchEnemy(enemy);
break;
}
}
}
void Player::setPosition(int x, int y) {
int mapWidth = gameMap.getWidth();
int mapHeight = gameMap.getHeight();
for (Enemy* enemy : game.currentEnemies) {
if (enemy->getX() == x && enemy->getY() == y) {
// If there is an enemy, call the touchEnemy method
touchEnemy(enemy);
break;
}
}
if (x >= 0 && x < mapWidth && y >= 0 && y < mapHeight) {
this->x = x;
this->y = y;
@@ -51,4 +64,21 @@ int Player::getX() {
int Player::getY() {
return y;
}
}
void Player::touchEnemy(Enemy* enemy) {
// Subtract the enemy's damage from the player's health
health -= enemy->getDamage();
// Add the enemy's coin drop to the player's gold
game.userGold += enemy->getCoinDrop();
// Remove the enemy from the game
gameMap.removeItem(enemy->getGraphics());
auto it = std::find(game.currentEnemies.begin(), game.currentEnemies.end(), enemy);
if (it != game.currentEnemies.end()) {
game.currentEnemies.erase(it);
}
delete enemy;
}

View File

@@ -7,20 +7,26 @@
#include "Mob.h"
#include "Tile.h"
#include "Map.h"
#include "Enemy.h"
#include "Game.h"
#include <QGraphicsEllipseItem>
#include <QGraphicsPixmapItem>
#include <QBrush>
class Game;
class Player : public Mob
{
Game& game;
public:
Player(int health, int shield, int damage, float regenerationRate, int speed, const std::string& avatarPath, int x, int y, Map& gameMap);
Player(int health, int shield, int damage, float regenerationRate, int speed, const std::string& avatarPath, int x, int y, Map& gameMap, Game& game);
void setPosition(Tile* tile);
void setPosition(int x, int y);
void getPlayerPosition();
int getX();
int getY();
QGraphicsPixmapItem* getGraphics();
void touchEnemy(Enemy* enemy);
private:
QGraphicsPixmapItem* graphics;

View File

@@ -35,4 +35,8 @@ int Tile::gridX() {
int Tile::gridY() {
return rect().y() / 50;
}
bool Tile::isPath() {
return type == Road || type == Start || type == End;
}

View File

@@ -10,13 +10,11 @@ class Tile : public QGraphicsRectItem
{
public:
enum Type { Road, Start, End, Tower, Other };
Tile(Type type, QGraphicsItem* parent = nullptr);
Type getType() const;
int gridX();
int gridY();
bool isPath();
private:
Type type;