Help with making a 'Simon' game on Qt?



  • So, this game is pretty simple. There is a QLabel in the middle of the window, and every 3 seconds, the QLabel changes text to a different color. The first round, it does this 3 times. Second one, 4 times. Third, 5 times. And so on. I have three buttons under it labeled "Green", "Blue", and "Red".The color the QLabel changes to are one of those three. On round 1, after the colors are done changing, you click the buttons in the order the colors came on the QLabel. Here are the methods that I am using, so correct me if I should use something else (method meaning technique):
    *In a for loop, I am changing the label with setText() every 50 loops, or my estimated three seconds.
    *Setting a rand() from <cstdlib> to make sure the colors are random (and I did generate the random seed with srand(time(NULL)))

    So, anything you guys can help me with? This forum has so far proven to be very helpful.



  • I think it's better to use a QTimer instead of a for loop. A for loop has disadvantages that while you're in it, no other code is executed. Also you have guess the number of iterations you need to get 3 seconds and this can depend on how fast or slow the computer you're running it on.



  • Yeah, using a loop is probably the most inefficient and unreliable method to emulate a "sleep" command. I remember that I used this exactly same method back when I started coding on my old C64, because I didn't know better back at that time. If you need to wait for a certain amount of time, just use Sleep() on Windows or msleep() on Linux. This is much more reliable and it won't keep the CPU busy. But even that method will still block your thread and make your GUI "freeze". So you better use an event driven approach. As t3685 has suggested, you can use "QTimer":http://qt-project.org/doc/qt-4.8/qtimer.html for this purpose.

    @//Constructor
    MyWindow::MyWindow
    {
    m_timer = new QTimer(this)
    m_timer->setInterval(50);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(timerDone()));
    m_timer->start();
    }

    //Slot function
    MyWindow::timerDone(void)
    {
    /* this will be called every 50 milliseconds! */
    }@



  • Thanks. I remember hearing about timers, even thought it would be a good idea for this program. But I never knew what to do, so I figured I would just use a for loop. Obviously, like you said, it was inefficient



  • Okay, so I tried a QTimer, and it isn't working. it says:
    QObject::connect: No such slot MainWindow::timerDone() in ..\Simon_Game\mainwindow.cpp:13

    I think it is because it isn't finding timerDone()? Any suggestions?



  • Of course you actually need to add a Slot of the name timerDone() to your class, if you which to connect to that Slot. Try like this:

    @/* main_window.h /
    class MainWindow
    {
    /
    [...] */

    public slots:
    void timeDone(void);

    /* [...] */
    };

    /* main_window.cpp */
    void MainWindow::timeDone(void)
    {
    //Your code here...
    }@

    See also:
    http://qt-project.org/doc/qt-4.8/signalsandslots.html



  • Did you declare your timerDone method as a slot? maybe show some code :)

    it should look like
    @
    private slots:
    void timerDone();
    @
    or something like that

    If you prefer you could also use the build in timer in every QObject (instead of a QTimer), see "QObject::startTimer":http://qt-project.org/doc/qt-5/qobject.html#startTimer.



  • Oh. Yeah. Whoops. Brainfart haha. Thanks for the heads up. I completely forgot about doing that.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.