1
votes

This is my first question, the reason i signed up to the site. I'm developing a game using Qt 5.9 and I use QTimer to spawn enemies on the screen. Everytime the timer's timeout function is called, an enemy is spawned. What i try to do is if a player kills let's say 10 enemies, the timer interval decreases, so the enemies will spawn more frequently, making the game a little bit more challenging. The first time the timer interval is set, the game runs perfectly, but the second time the setInterval() method is called, when the player kills 10 enemies, the game suddenly crashes. I tried debugging it to figure out what might cause it, and it seems that it crashes when i try to set the spawnInterval. I'm fairly new to coding so any advice is appreciated! Here are the relevant source files and codes from my code:

main.cpp

#include <QApplication>
#include <game.h>

Game * game;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    game = new Game();

    game->show();

    return a.exec();
}

game.h:

#include <QGraphicsScene>
#include <QWidget>
#include <QGraphicsView>
#include "Player.h"
#include "score.h"
#include "Health.h"

class Game: public QGraphicsView{
public:
    Game(QWidget * parent=0);
    QGraphicsScene * scene;
    Player * player;
       Score * score;
       Health * health;
       void setSpawnInterval(int spawnValue);
       int getSpawnInterval();
        void setTimerInterval();
private:
       int spawnInterval = 1000;
};
#endif // GAME_H

game.cpp:

QTimer * timer1 = new QTimer();
QObject::connect(timer1,SIGNAL(timeout()),player,SLOT(spawn()));
timer1->start(getSpawnInterval());
}
void Game::setSpawnInterval(int spawnValue){

 //this is the part where it crashes
spawnInterval = spawnValue;
}

int Game::getSpawnInterval(){
    return spawnInterval;
}

score.h

#ifndef SCORE_H
#define SCORE_H

#include <QGraphicsTextItem>

class Score: public QGraphicsTextItem{
public:
    Score(QGraphicsItem * parent=0);
    void increase();
    int getScore();

private:
    int score;
};
#endif // SCORE_H

score.cpp

#include "score.h"
#include <QFont>
#include "game.h"
#include <QTimer>

void Score::increase()
{
    score++;

    if(score > 3){
    Game * game;
        game->setSpawnInterval(200);}

    //Draw the text to the display
    setPlainText(QString("Score: ") + QString::number(score));

}

int Score::getScore()
{
    return score;
}

player.h

    #ifndef PLAYER_H
#define PLAYER_H

#include <QGraphicsRectItem>
#include <QEvent>
#include <QObject>

class Player: public QObject, public QGraphicsRectItem{
    Q_OBJECT
public:
     Player(QGraphicsItem * parent=0);
   void keyPressEvent(QKeyEvent * event);
    int jumpPhaseNumber = 0;
    bool jumpRun = false;
public slots:
   void spawn();
   void jumpPhase();

};

#endif

player.cpp

void Player::spawn()
{
    Enemy * enemy = new Enemy();
    scene()->addItem(enemy);

}
2
game is not initialized. - user2672107
You mean: " Game *game = new Game()" instead of "Game *game"? I tried it, but it creates a new window and the game starts again in that window. - Bencsizy
@Bencsizy Is it possible for you to change time out without starting timer. like this : //timer1->start(getSpawnInterval()); , timer1->setInterval(getSpawnInterval()); I want to make sure changing time interval is not the problem. - Farhad
No! I mean you are not allowed to dereference an uninitialized variable. - user2672107
Tried it: if i change that line to the line you mentioned, enemies won't start to spawn. I added another line after that: "timer1->start();" and then they started to spawn, but then it crashed at score = 3 just as before. - Bencsizy

2 Answers

0
votes

Seems you are creating two instance of class game.

I suggest you to use static variables for accessing from multi classes.

add this class to your project:

.cpp

#include "settings.h"

int Settings::spawnInterval = 1000;

Settings::Settings(QObject *parent) : QObject(parent)
{

}

.h

#ifndef SETTINGS_H
#define SETTINGS_H

#include <QObject>
#include <QString>

class Settings : public QObject
{
    Q_OBJECT
public:
    explicit Settings(QObject *parent = 0);

    static int spawnInterval;
};

#endif // SETTINGS_H

now we have a static variable name spawnInterval, you can access it (set/get) from any classes that include settings class like this:

#include <settings.h>

Settings::spawnInterval = 100; // set
int value = Settings::spawnInterval; //get
0
votes

This line: Game * game; game->setSpawnInterval(200) causes your program to crash: you must initialize the game pointer; to fix this, for example, you can hold a reference (pointer) of game inside the Score class, thus letting you call setSpawnInterval; I would construct Score inside Game's constructor passing thisas a parameter; this saves you from creating a new class, as @aghilpro suggested. Actually a struct would be better since your information is public and accessible from other classes without the need to implement getters/setters.