I am writing a game. By tick timer should work the this slot.

void game_process::animate_cell(MainWindow* m, const std::string& s, double x,double y, size_t i, size_t j, const std::string& step)
{ 
    painter.begin(m);
    std::string ss("C:\\Users\\Vardan\\GAmes_lines\\res\\red_" + step + ".png");
    ss += s;
    const char* p = ss.c_str();    
    QImage image(p);
    RECT temp = cal

    culate_cell_rect(i, j);
    QRectF target(x, y, image.width(), image.height());
    painter.drawImage(target, image);
    painter.end();
    m->update(x + temp.x0, y + temp.y0, 60, 60);
}
, that's it,

QTimer * timer = new QTimer (this); connect (timer, SIGNAL (timeout ()), this, SLOT (render_cell (MainWindow * m, const std :: string & s, double x, double y, size_t i, size_t j, const std :: string & step))); timer-> start ();

But as you can see the slot more parameters than the signal, and hence signals and slots mechanism does not work. What to do? Here cod

#include <QDesktopWidget>
#include <QResizeEvent>
#include <QDebug>
#include <QTimer>
#include <QTime> 
#include <phonon/MediaObject>
#include <phonon/MediaSource>
#include <phonon/AudioOutput>
#include <utility>
#include <cassert>

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent)
{
    QImage image("C:\\Users\\Vardan\\GAmes_lines\\res\\back_3.png");
    m_width = 1000;
    m_height = 800;
    m_game_width = image.width();
    m_game_height = image.height();
    setFixedSize(m_width, m_height);
    m_click_coords.first = 0;
    m_click_coords.second = 0;
    m_timer_tick = false;
    m_timer_id = 0;        
    setWindowFlags( Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
    m_area_x0_coordinate = (this->width() - image.width())/2;
    m_area_y0_coordinate = (this->height() - image.height())/2;
    m_r = new game_process(m_area_x0_coordinate, m_area_y0_coordinate, image.width()/*+30*/, image.height()/*+30*/, 57);
    m_status = false;     
    Phonon::MediaObject *mediaobject = new Phonon::MediaObject;
    QString filename("C://Users//Vardan//GAmes_lines//music//Casino Ambiance Music.wav");
    mediaobject->setCurrentSource(filename);
    Phonon::AudioOutput *audio = new Phonon::AudioOutput;
    Phonon::createPath(mediaobject,audio);
    mediaobject->play();
    QPixmap pixmap("C:\\Users\\Vardan\\GAmes_lines\\res\\background.png");    
    QPalette palette;    
    palette.setBrush(/*this->backgroundRole()*/QPalette::Background, QBrush(pixmap));
    this->setPalette(palette);

}
MainWindow::MainWindow(std::string& str, QWidget *parent):
    QWidget(parent)
{

}

double MainWindow::get_mouse_click_absolute_x_coordinate() const
{
    return m_area_x0_coordinate;
}

double MainWindow::get_mouse_click_absolute_y_coordinate() const
{
    return m_area_y0_coordinate;
}

void MainWindow::set_mouse_click_absolute_x_coordinate(double x)
{
    m_area_x0_coordinate = x;
}

void MainWindow::set_mouse_click_absolute_y_coordinate(double y)
{
    m_area_y0_coordinate = y;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    if(m_status == false)
    {
        m_r->game_loop(this);
    }
    else
    {   
        game_process::RECT temp = m_r->calculate_cell_rect(m_click_coords.first, m_click_coords.second);
        int x = m_area_x0_coordinate + temp.x0;
        int y = m_area_y0_coordinate + temp.y0;
        std::pair<double, double> p;
/////////////////////////////////////////////////////////
        start_timer();
//////////////////////////////////////////////////////////
        for(int i = 2; i < 8; ++i)
        {
            char buf[sizeof(int)];
            itoa(i, buf, 10);
            std::string s(buf);            
            m_r->erase_frame(this, x, y);
            while(m_timer_tick == false){}
            p = m_r->draw_frame(this, m_click_coords.first, m_click_coords.second, s.c_str());
            m_timer_tick = false;
        }
        end_timer();            
        m_status = false;
    }        
}

bool MainWindow::delay(int ms)
{
    QTime dieTime = QTime::currentTime().addMSecs(ms);
    while( QTime::currentTime() < dieTime )
    return true;
}

void MainWindow::mousePressEvent (QMouseEvent* e)
{
    qDebug() << "Local:" << e->pos().x();
    qDebug() << "Local:" << e->pos().y();    
    std::pair<double, double> p = m_r->calculate_index_of_the_coordinates(e->pos().x(), e->pos().y(), m_width, m_height);
    if(m_area_x0_coordinate <= e->pos().x() && m_area_y0_coordinate <= e->pos().y()
            && m_area_x0_coordinate + m_game_width >= e->pos().x() && m_area_y0_coordinate + m_game_height >= e->pos().y() )
    {        
        m_status = true;
        m_click_coords.first = p.first;
        m_click_coords.second = p.second;        
        game_process::RECT coords = m_r->calculate_cell_rect(p.first, p.second);                
        Figure* f = m_r->detect_figure_by_index(p.first, p.second);         
        m_r->delete_cluster(this, f);            
    }
    game_process::RECT r;
    qDebug() << "Local:" << p.first;
    qDebug() << "Local:" << p.second;
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    m_timer_tick = true;
} 

void MainWindow::start_timer()
{
    m_timer_id = startTimer(1000 / 30);
}

void MainWindow::end_timer()
{
    killTimer(m_timer_id);
}

bool MainWindow::event(QEvent *e)
{
    switch (e->type())
    {
        case QEvent::WindowActivate:
        case QEvent::WindowDeactivate:
          return true;
    }
    return QWidget::event(e);

}

I noticed that the timer does not start from paintEvent, and I need what he started with paintEvent. What to do?

I adjusted the code following your advice.

#include "mainwindow.h"
#include "game_process.h"

#include <QPixmap>
#include <QPainter>
#include <QPalette>
#include <QDesktopWidget>
#include <QResizeEvent>
#include <QDebug>
#include <QTimer>
#include <QTime> 
#include <phonon/MediaObject>
#include <phonon/MediaSource>
#include <phonon/AudioOutput>
#include <utility>
#include <cassert>

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent)
{
    QImage image("C:\\Users\\Vardan\\GAmes_lines\\res\\back_3.png");
    m_width = 1000;
    m_height = 800;
    m_game_width = image.width();
    m_game_height = image.height();
    setFixedSize(m_width, m_height);
    m_click_coords.first = 0;
    m_click_coords.second = 0;
    m_next_cell = 0;
    m_frame_count = 2;
    m_timer_tick = false;
    m_timer_id = 0;
    m_matrix_size = 0;
    m_timer_flag = false;
    setWindowFlags( Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
    m_area_x0_coordinate = (this->width() - image.width())/2;
    m_area_y0_coordinate = (this->height() - image.height())/2;
    m_r = new game_process(m_area_x0_coordinate, m_area_y0_coordinate, image.width()/*+30*/, image.height()/*+30*/, 57);
    m_status = false;     
    Phonon::MediaObject *mediaobject = new Phonon::MediaObject;
    QString filename("C://Users//Vardan//GAmes_lines//music//Casino Ambiance Music.wav");
    mediaobject->setCurrentSource(filename);
    Phonon::AudioOutput *audio = new Phonon::AudioOutput;
    Phonon::createPath(mediaobject,audio);
    mediaobject->play();
    QPixmap pixmap("C:\\Users\\Vardan\\GAmes_lines\\res\\background.png");    
    QPalette palette;    
    palette.setBrush(/*this->backgroundRole()*/QPalette::Background, QBrush(pixmap));
    this->setPalette(palette);
}

MainWindow::~MainWindow()
{

}

MainWindow::MainWindow(std::string& str, QWidget *parent):
    QWidget(parent)
{

}

double MainWindow::get_mouse_click_absolute_x_coordinate() const
{
    return m_area_x0_coordinate;
}

double MainWindow::get_mouse_click_absolute_y_coordinate() const
{
    return m_area_y0_coordinate;
}

void MainWindow::set_mouse_click_absolute_x_coordinate(double x)
{
    m_area_x0_coordinate = x;
}

void MainWindow::set_mouse_click_absolute_y_coordinate(double y)
{
    m_area_y0_coordinate = y;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    static int  ind = 0;
    if(m_status == false && m_timer_tick != true)
    {
        m_r->game_loop(this);
    }
    else
    {
        std::pair<double, double> p;
        int x = 0;
        int y = 0;

        static int s = m_r->get_close_map_size();
        static std::vector<std::pair<int, int> > v = m_r->get_close_map_indexes();
        if(m_frame_count >= 7)
        {
            m_frame_count = 2;            
            ++m_next_cell;
            if(m_next_cell <= v.size())
            {
                game_process::RECT temp = m_r->calculate_cell_rect(v[m_next_cell].second, v[m_next_cell].first);
                x = m_area_x0_coordinate + temp.x0;
                y = m_area_y0_coordinate + temp.y0;
                m_x = x;
                m_y = y;
            }
        }
        if(m_next_cell == 0)
        {
            game_process::RECT temp = m_r->calculate_cell_rect(v[m_next_cell].second, v[m_next_cell].first);
            x = m_area_x0_coordinate + temp.x0;
            y = m_area_y0_coordinate + temp.y0;
            m_x = x;
            m_y = y;
        }
        if(m_frame_count < 7 && m_next_cell < v.size())
        {
            char buf[sizeof(int)];
            itoa(m_frame_count, buf, 10);
            std::string s(buf);
            m_r->erase_frame(this, x, y);
            p = m_r->draw_frame(this, v[m_next_cell].second, v[m_next_cell].first, s.c_str());
            m_timer_tick = false;            
            c = true;
        }        
        if(c == false && m_next_cell > v.size() - 1)
        {
            end_timer();
            qDebug()<<"m_x = " << m_x;
            qDebug()<<"m_y = " << m_y;
            qDebug()<<"m_frame_count + 1 = " << m_frame_count + 1;
            qDebug()<<"v.size() = " << v.size();
            m_r->repaint_cells(this);
        }
        m_status = false;
    }    
}

void MainWindow::mousePressEvent (QMouseEvent* e)
{    
    qDebug() << "Local:" << e->pos().x();
    qDebug() << "Local:" << e->pos().y();    
    std::pair<double, double> p = m_r->calculate_index_of_the_coordinates(e->pos().x(), e->pos().y(), m_width, m_height);
    if(m_area_x0_coordinate <= e->pos().x() && m_area_y0_coordinate <= e->pos().y()
            && m_area_x0_coordinate + m_game_width >= e->pos().x() && m_area_y0_coordinate + m_game_height >= e->pos().y() )
    {
        start_timer();
        m_status = true;
        m_click_coords.first = p.first;
        m_click_coords.second = p.second;        
        game_process::RECT coords = m_r->calculate_cell_rect(p.first, p.second);                
        Figure* f = m_r->detect_figure_by_index(p.first, p.second);                 
        m_r->delete_cluster(this, f);
        //this->update(m_area_x0_coordinate + coords.x0, m_area_y0_coordinate + coords.y0, 57, 57);
    }
    game_process::RECT r;
    qDebug() << "Local:" << p.first;
    qDebug() << "Local:" << p.second;
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == m_timer_id)
    {        
        m_timer_tick = true;
        ++m_frame_count;
        if(m_x >=0 && m_y >=0)
        {
            qDebug()<<"m_x  "<<m_x <<"m_y  "<<m_y<<"time |||||| Passed";
            this->update(m_x, m_y, 60, 60);
        }
    }
    else
    {
        QWidget::timerEvent(event);
    }
}

void MainWindow::start_timer()
{
    m_timer_id = startTimer(50);
}

void MainWindow::end_timer()
{    
       killTimer(m_timer_id);     
}

bool MainWindow::event(QEvent *e)
{
    switch (e->type())
    {
        case QEvent::WindowActivate:
        case QEvent::WindowDeactivate:
          return true;
    }
    return QWidget::event(e);

}

Here's the code repaint_cells()

void game_process::repaint_cells(MainWindow* m)
{
    Figure* f = 0;    
    for(int i = 0; i < 8; ++i)
    {        
        for(int j = 0; j < 8; ++j)
        {
            if(m_close_list[j][i] == -1)
            {
                f = create_new_figure(j, i);
                m_figures.push_back(f);
                assert(f != 0);
                draw_figure(m, f, i, j);
                m_close_list[j][i] = 0;                
            }
        }
     }
}

enter link description here

For two days I can not understand why only one ball is drawn. Тhe remaining balls are not drawn.

有帮助吗?

解决方案 2

I see from your code snippet that you are passing a pointer to MainWindow to your render_cell() function, which I assume is some kind of widget or class derived from QObject.

In that case you could override the timerEvent(), which is defined for each QObject class and implement your game loop here. This way the parameters of your render_cell() could be be member variables of MainWindow, or your entire game_process class could be embedded in MainWindow.

Also, I think this approach is a little faster than using signals, which might be important for code that has to render something 30-60 times per second and update a bunch of other things.

For documentation see http://qt-project.org/doc/qt-4.8/qobject.html#timerEvent

In pseudo code, you could implement your game like this:

class MainWindow : public QWidget
{
  private:
    game_process *game;
    int timer_id;

  public:
    MainWindow(void)
      : QWidget(0),
        game(0),
        timer_id(0)
    {
      game = new game_process;
    }

    void startGame(void)
    {
      timer_id = startTimer(1000 / 30);   // 30 fps
    }

    void endGame(void)
    {
      killTimer(timer_id);
    }

  protected:
    virtual void timerEvent(QTimerEvent *event)
    {
       // update AI
       // update network
       // render game
       game->render_cell(/* params */);
    }

};

其他提示

You have two main approaches:

  1. Simply define another slot with no parameters that will call game_process::render_cell(), then connect to the new slot.

  2. If you're using Qt 5, use a lambda. See here for examples. It would look something like this: connect(timer, &QTimer::timeout, [=](){/*call the function here*/});

I recommend #2.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top