Qgraphics item getting slow

144 Views Asked by At

I started few months ago studying QT with c++ and how i could develop a game for college purposes. I have a space shooter game where the player is a Qgraphics item that constantly play animations (moving, idle, change weapon...) as well the enemies.

The movement system is ok, player move around the map with no problems, and the controls are smooth and respond how they should.

Shooting system also ok! Player can create other objects that go straight and disappear(deleted from the scene) with the object they collide if they do, or just disappear when reach the scene border, enemies can also shoot as well.

When a key is pressed, player respond any commands with no delay, the problem is the enemies.

The player have a periodically function that creates enemies in the upper border of the map and they go straight down towards the lower border of the map, if they were not shoot down they just disappear like the bullets.

But after some time they just slow down a lot, that when i turn off the function that allow they to shoot, if they do it gets even worse and the game starts to lag VERY MUCH, what was not supposed to happen because for me is "just a bunch of 2d pictures moving in a screen". here is what i believe is the problematic code, can someone help me? This is getting really annoying, for 2 or 3 months i was not able to fix it or know why this is happening.

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);
}
0

There are 0 best solutions below