0

几个月前,我开始使用 c++ 学习 QT,以及如何为大学目的开发游戏。我有一个太空射击游戏,其中玩家是一个 Qgraphics 项目,它不断播放动画(移动、空闲、更换武器......)以及敌人。

移动系统没问题,玩家在地图上移动没有问题,并且控制很流畅,可以做出应有的反应。

射击系统也ok!玩家可以创建其他物体直线移动并与它们碰撞的物体消失(从场景中删除),或者在到达场景边界时消失,敌人也可以射击。

当一个键被按下时,玩家响应任何命令都没有延迟,问题是敌人。

玩家有一个周期性的功能,在地图的上边界创造敌人,他们直接朝地图的下边界向下移动,如果他们没有被击落,他们就会像子弹一样消失。

但是过了一段时间他们就慢了很多,当我关闭允许他们射击的功能时,如果他们这样做会变得更糟并且游戏开始非常滞后,不应该发生的事情因为对我来说是“只是一堆在屏幕上移动的二维图片”。这是我认为有问题的代码,有人可以帮助我吗?这真的很烦人,有 2 或 3 个月我无法修复它或知道为什么会这样。

Enemy.h
#define ENEMY_H

#include <QObject>
#include <QGraphicsPixmapItem>
#include <QGraphicsItem>
#include <QTimer>
#include <QPixmap>
#include <QMediaPlayer>
#include <QPainter>

//works similiar to player controlled entity, but this one is controlled by algorithms
class Enemy: public QObject, public QGraphicsItem
{
    Q_OBJECT
public:
    explicit Enemy(QObject *parent=0);
    void move();
    void shoot();

private slots:
    void nextFrame();
    void enemiesInrange();//peiodically checks if there is any enemies in it's front, if there is it will shoot periodically

private:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QRectF boundingRect() const;

    QTimer *timer;//for load the next frame of the animation
    QTimer *timer2;//for move
    QTimer *timer3;//for look for enemies
    QTimer *timer4;//for shoot in enemies
    QPixmap *spriteImage;
    int currentFrame;
    int currentSequence;
    QMediaPlayer *bullet_sound;
};

#endif // ENEMY_H
enemy.c
#include "enemy.h"
#include "player.h"
#include <QBitmap>
#include "bullet.h"
#include "game.h"
#include "stdlib.h"


extern Game *game;

using namespace std;

Enemy::Enemy(QObject *parent):
    QObject(parent), QGraphicsItem()
{
    spriteImage = new QPixmap(":/images/img/hizack spritesheet.png");

    int random_number = rand()% 1200;
    setPos(random_number,0);

    currentFrame=0;
    currentSequence=210;
    timer = new QTimer();
    connect(timer, &QTimer::timeout, this, &Enemy::nextFrame);
    timer->start(100);

    timer2 = new QTimer();
    connect(timer2, &QTimer::timeout, this, &Enemy::move);

    timer2->start(1);

    timer3 = new QTimer();
    connect(timer3, &QTimer::timeout, this, &Enemy::enemiesInrange);
    timer3->start(1000);
}

void Enemy::move()
{

        currentSequence = 210;
        setPos(x(),y()+0.25);

    if(pos().y() + spriteImage->height() < 0 || pos().y() >= 800)
    {
        game->scene->removeItem(this);
        delete this;
        return;
    }

    if(pos().x() >= 600 || pos().x() == 0)
    {
        game->scene->removeItem(this);
        delete this;
        return;
    }
}

void Enemy::shoot()
{
    if(currentSequence == 210)
    {
        Bullet * bullet = new Bullet(0,currentSequence,20,2);
        bullet->setPos(this->pos().x()-20,this->pos().y()+50);
        scene()->addItem(bullet);
    }
    else if(currentSequence == 70)
    {
         Bullet * bullet = new Bullet(0,currentSequence,30,2);
         bullet->setPos(this->pos().x()-20,this->pos().y()-80);
         scene()->addItem(bullet);
    }
    else if(currentSequence == 140)
    {
         Bullet * bullet = new Bullet(0,currentSequence,30,2);
         bullet->setPos(this->pos().x()+20 ,this->pos().y()-50 );
         scene()->addItem(bullet);
    }
    else if(currentSequence == 0)
    {
        Bullet * bullet = new Bullet(0,currentSequence,30,2);
        bullet->setPos(this->pos().x()-50 ,this->pos().y()-50 );
        scene()->addItem(bullet);
    }
}


void Enemy::enemiesInrange()//fires player if him is at range
{
    qInfo() << "Items in scene: " << scene()->items().size();

    if(game->player1->pos().y() <= this->pos().y()+300 )
    {
        if(game->player1->pos().x() <= this->pos().x()+100 && game->player1->pos().x()>= this->pos().x()-100)
            shoot();
    }

}


void Enemy::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->drawPixmap(-35,-35, *spriteImage, currentFrame, currentSequence, 70,70);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

QRectF Enemy::boundingRect() const
{
    return QRectF(-35,-35,70,70);
}

void Enemy::nextFrame()
{
    currentFrame += 70;
    if (currentFrame >= 210)
        currentFrame = 0;
    this->update(-35,-35,70,70);
}
4

0 回答 0