From 6c564841bfaf88089ccbefd6227283ebd45582ca Mon Sep 17 00:00:00 2001 From: Georg Spar Date: Sat, 8 Oct 2022 20:05:34 +0200 Subject: [PATCH] Tut 12 --- CMakeLists.txt | 1 + enemy.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ enemy.h | 25 ++++++++++++++++++++++++ enemy.png | Bin 0 -> 3107 bytes game.cpp | 5 +++++ res.qrc | 1 + tower.cpp | 37 +++++++++++++++++++++++++++++++++-- tower.h | 6 +++++- 8 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 enemy.cpp create mode 100644 enemy.h create mode 100644 enemy.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d71df8..ba68acc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ set(PROJECT_SOURCES game.h game.cpp res.qrc bullet.h bullet.cpp + enemy.h enemy.cpp ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) diff --git a/enemy.cpp b/enemy.cpp new file mode 100644 index 0000000..d7e511d --- /dev/null +++ b/enemy.cpp @@ -0,0 +1,51 @@ +#include "enemy.h" +#include + + +Enemy::Enemy(QGraphicsItem *parent) { + //set graphics + setPixmap(QPixmap(":/images/enemy.png")); + + //set points + points << QPointF(200,200) << QPointF(400,200); + point_index = 0; + dest = points[0]; + rotateToPoint(dest); + + QTimer * timer = new QTimer(); + connect(timer, SIGNAL(timeout()), this, SLOT(move_forward())); + timer->start(150); + + +} + +void Enemy::rotateToPoint(QPointF p) { + QLineF ln(pos(), p); + setRotation((-1 * ln.angle())); + +} + +void Enemy::move_forward() { + //if close to dest, rotate to next dest + QLineF ln(pos(), dest); + if (ln.length() < 5) { + point_index++; + if (point_index >= points.size()) { + return; + } + dest = points[point_index]; + rotateToPoint(dest); + } + + int STEP_SIZE = 5; + int theta = rotation(); // degrees + double dy = STEP_SIZE * qSin(qDegreesToRadians(theta)); + double dx = STEP_SIZE * qCos(qDegreesToRadians(theta)); + + setPos(x()+dx, y()+dy); +} + + + + + diff --git a/enemy.h b/enemy.h new file mode 100644 index 0000000..1d1863f --- /dev/null +++ b/enemy.h @@ -0,0 +1,25 @@ +#ifndef ENEMY_H +#define ENEMY_H +#include +#include +#include +#include + + + +class Enemy: public QObject, public QGraphicsPixmapItem { + Q_OBJECT +public: + Enemy(QGraphicsItem *parent=0); + void rotateToPoint(QPointF p); +public slots: + void move_forward(); + +private: + QList points; + QPointF dest; + int point_index; + +}; + +#endif // ENEMY_H diff --git a/enemy.png b/enemy.png new file mode 100644 index 0000000000000000000000000000000000000000..717e9ccc9af3a99360bddb617131ddf6a7827e28 GIT binary patch literal 3107 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 literal 0 HcmV?d00001 diff --git a/game.cpp b/game.cpp index d8db7e8..03c6e3a 100644 --- a/game.cpp +++ b/game.cpp @@ -2,6 +2,7 @@ #include #include "tower.h" #include "bullet.h" +#include "enemy.h" Game::Game(): QGraphicsView() { scene = new QGraphicsScene(this); @@ -18,6 +19,10 @@ Game::Game(): QGraphicsView() { setFixedSize(800,600); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + // create enemy + Enemy *enemy = new Enemy(); + scene->addItem(enemy); } void Game::mousePressEvent(QMouseEvent *event) { diff --git a/res.qrc b/res.qrc index 6ead141..a987762 100644 --- a/res.qrc +++ b/res.qrc @@ -2,6 +2,7 @@ tower.png missile.png + enemy.png diff --git a/tower.cpp b/tower.cpp index d853291..96a394b 100644 --- a/tower.cpp +++ b/tower.cpp @@ -5,6 +5,7 @@ #include "bullet.h" #include #include "game.h" +#include "enemy.h" extern Game *game; @@ -37,13 +38,19 @@ Tower::Tower(QGraphicsItem *parent): QObject(), QGraphicsPixmapItem(parent) { // connect timer to attack target QTimer *timer = new QTimer(); - connect(timer, SIGNAL(timeout()), this,SLOT(attack_target())); + connect(timer, SIGNAL(timeout()), this,SLOT(aquire_target())); timer->start(1000); attack_dest = QPointF(800,0); } -void Tower::attack_target() { +double Tower::distanceTo(QGraphicsItem *item) { + + QLineF ln(pos(), item->pos()); + return ln.length(); +} + +void Tower::fire(){ Bullet *bullet = new Bullet(); bullet->setPos(x()+34, y()+64); @@ -53,3 +60,29 @@ void Tower::attack_target() { bullet->setRotation(angle); game->scene->addItem(bullet); } + +void Tower::aquire_target() { + + QList colliding_items = attack_area->collidingItems(); + + if (colliding_items.size() == 1) { + has_target = false; + return; + } + double closest_dist = 300; + QPointF closest_pt = QPointF(0,0); + for (size_t i = 0, n = colliding_items.size(); i(colliding_items[i]); + if (enemy) { + double this_dist = distanceTo(enemy); + if (this_dist < closest_dist) { + closest_dist = this_dist; + closest_pt = colliding_items[i]->pos(); + has_target = true; + } + } + } + + attack_dest = closest_pt; + fire(); +} diff --git a/tower.h b/tower.h index 9642e74..649a89b 100644 --- a/tower.h +++ b/tower.h @@ -10,11 +10,15 @@ class Tower : public QObject, public QGraphicsPixmapItem { Q_OBJECT public: Tower(QGraphicsItem *parent=0); + double distanceTo(QGraphicsItem *item); + void fire(); public slots: - void attack_target(); + + void aquire_target(); private: QGraphicsPolygonItem *attack_area; QPointF attack_dest; + bool has_target; }; #endif // TOWER_H