QT: не может установить положение объекта в главном окне даже после static_cast

Я делаю небольшую игру, и я хочу, чтобы мой враг в игре одновременно двигался и порождал пулю.

Пока что мой враг может перемещаться и вызывать пули автоматически, но проблема в том, что

моя пуля не может следить за движением врага и появляться на
Начальная точка противника.

Чтобы быть более конкретным,

Я хочу поймать само положение врага каждый раз, когда враг порождает пулю. Однако я не могу выставить свою пулю динамически.

Сейчас я разрабатываю функцию перемещения врагов (enemyMove ()) и функция нереста-пули (MakeBall ()) по отдельности. И я установил свой таймер для каждой функции в своем конструкторе главного окна, чтобы вызывать функцию автоматически каждый раз в окне.

Мои попытки и мысли пока:

  • Мой враг — объект класса Enemy, но у меня есть статическое приведение
    этот объект в QGraphicsPixmapItem в конструкторе главного окна, поэтому я
    думал, что он должен быть в состоянии использовать противника в качестве QGraphicsPixmapItem.
    Тем не менее, как я пытаюсь сделать такие вещи, как enemy-> х () в моем MakeBall ()
    функции, компилятор принудительно завершился.
  • Я посылаю позицию противника в качестве аргумента функции MakeBall, чтобы
    пуля может устанавливать Pos в самом положении противника. Тем не мение,
    компилятор говорит, что это неверная инициализация неконстантной
    ссылка типа int&’из значения типа’ int ‘.
  • Я посылаю враг QGraphicsPixmapItem * в качестве аргумента функции MakeBall
    и использовать врага-> х (), чтобы поймать свою позицию, однако, это в конечном итоге даже не
    порождает любую пулю, что означает, что функция MakeBall никогда не вызывается
    успешно.

Любой обмен или совет будет выше благодарности. Огромное спасибо.

главное окно.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent):
QMainWindow(parent),
ui(new Ui::MainWindow),
enemyMoveTimer(new QTimer),
balldrop(new QTimer),
makeballtimer(new QTimer)
{
ui->setupUi(this);
//scene
scene = new QGraphicsScene(0, 0, 1050, 600);
//view
view = new QGraphicsView;
view ->setScene(scene);
setCentralWidget(view);

//enemy
Enemy * enemy = new Enemy();
enemy->setPixmap(QPixmap(QPixmap(":/img/ghost.gif").scaled(100,100)));
enemy->setPos(0,0);
scene->addItem(static_cast<QGraphicsPixmapItem*>(enemy));

enemyMoveTimer->start(100);
enemy->connect(enemyMoveTimer, SIGNAL(timeout()), enemy, SLOT(enemyMove()));

//enemy's bullet
makeballtimer->start(1000);
//int & x=enemy->x();
//connect(makeballtimer, SIGNAL(timeout()), this, SLOT(MakeBall(int & x)));
connect(makeballtimer, SIGNAL(timeout()), this, SLOT(MakeBall(QGraphicsPixmapItem * enemy)));

}void MainWindow::MakeBall(QGraphicsPixmapItem * enemy)
{
EnemyBullet * ball = new EnemyBullet();
ball->setPixmap(QPixmap(":/img/yellowblankball.png").scaled(50, 30));

ball->setPos(enemy->x()+50, 100);//the problem is here

balldrop->start(100);
ball->connect(balldrop, SIGNAL(timeout()), ball, SLOT(fall()));
scene->addItem(static_cast<QGraphicsPixmapItem*>(ball));
}

MainWindow::~MainWindow()
{
delete ui;
}

главное окно

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QTimer>
#include <QKeyEvent>
#include <QtGui>

#include "enemy.h"#include "ball.h"#include "enemybullet.h"
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

public slots:
//virtual void MakeBall(int &x);
virtual void MakeBall( QGraphicsPixmapItem * enemy);
//virtual void MakeBall();

private:
Ui::MainWindow *ui;
QGraphicsScene *scene;
QTimer *enemyMoveTimer;
QTimer *balldrop;
QTimer *makeballtimer;
QGraphicsItem *enemy;

QGraphicsView * view;

};

#endif // MAINWINDOW_H

enemybullet.cpp

#include "enemybullet.h"#include <QTimer>
#include <QGraphicsScene>
#include <QList>

EnemyBullet::EnemyBullet()
{

}

void EnemyBullet::fall()
{
setPos(x(), y() +10 );
}

enemybullet.h

#ifndef ENEMYBULLET_H
#define ENEMYBULLET_H

#include <QObject>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>

class EnemyBullet: public QObject, public QGraphicsPixmapItem
{
Q_OBJECT

public:
EnemyBullet();

public slots:
void fall();
};#endif// ENEMYBULLET_H

врага.cpp (обрезается до существенного. он может фактически перемещаться по прямой линии слева направо и справа налево несколько раз. Поэтому мы не можем подсчитать конкретное время для появления пули, потому что каждая позиция будет пересматриваться снова и снова.)

#include "enemy.h"#include "enemybullet.h"#include <QDebug>

Enemy::Enemy()
{

}

void Enemy::enemyMove()
{
setPos(x() + 10,y());
}

enemy.h

#ifndef ENEMY_H
#define ENEMY_H

#include <QObject>
#include <QGraphicsPixmapItem>
#include <QTimer>class Enemy:  public QObject,public QGraphicsPixmapItem
{
Q_OBJECT

public:
Enemy();

public slots:
void enemyMove();
};

#endif // ENEMY_H

-1

Решение

Как правило, вы хотите избежать смешивания кода пользовательского интерфейса со структурами данных, это значительно упрощает масштабирование, поэтому в вашем случае я бы действительно предложил создать резервные классы данных, которые будут содержать только данные, а затем пользовательский интерфейс.

Однако ваша проблема в том, что вы смешиваете сигнал и слот — вы подключаете QTimer :: тайм-аут () сигнал в ваш слот, который принимает параметр типа QGraphicsPixmapItem *, Хотя это компилируется, я думаю, что по крайней мере в режиме отладки вы получите сообщение о том, что что-то вроде сигнала и слоты несовместимы. Гораздо лучше использовать современный стиль соединения следующим образом:

 connect(makeballtimer, &QTimer::timeout, this, &MainWindow::MakeBall);

Так как эта запись не удастся уже во время компиляции.

Я предлагаю вам сделать следующее: создать классы моделей (или структуры, это действительно ваше дело), ​​которые будут содержать только данные, связанные с каждым элементом; например:

struct Enemy {
QPoint position;
};

struct BulletModel {
std::shared_ptr<Enemy> enemy;
QPoint position;
};

Ваш список врагов будет сохранен как вектор std::shared_ptr чтобы убедиться, что их жизни управляются:

std::vector<std::shared_ptr<Enemy>> m_enemies;

Тогда вы можете создать врага и пулю:

auto enemy = std::make_shared<EnemyModel>();
auto bullet = std::make_shared<BulletModel>();
bullet->enemy = enemy;

Затем вы можете создавать виджеты, которые будут использовать модели для рисования элементов на своих местах.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]