1

私はゲームを書いています。ティックタイマーによって、このスロットが機能するはずです。

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 = 新しい QTimer (これ); connect (タイマー, SIGNAL (タイムアウト ()), this, SLOT (render_cell (MainWindow * m, const std :: string & s, double x, double y, size_t i, size_t j, const std :: string & step)) ); タイマー-> 開始 ();

しかし、ご覧のとおり、スロットはシグナルよりも多くのパラメーターを持っているため、シグナルとスロットのメカニズムは機能しません。何をすべきか?ここでタラ

#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?

あなたのアドバイスに従ってコードを調整しました。

#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);

}

これがコード 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;                
            }
        }
     }
}

ここにリンクの説明を入力

2日間、なぜボールが1つしか描かれていないのか理解できません。残りのボールは描画されません。

4

2 に答える 2

5

主なアプローチは 2 つあります。

  1. を呼び出すパラメーターなしで別のスロットを定義game_process::render_cell()し、新しいスロットに接続するだけです。

  2. Qt 5 を使用している場合は、ラムダを使用します。例については、こちらを参照してください。次のようになります。connect(timer, &QTimer::timeout, [=](){/*call the function here*/});

#2をお勧めします。

于 2013-05-01T18:59:47.610 に答える
0

コード スニペットからMainWindowrender_cell()関数へのポインターを渡していることがわかります。これは、QObject から派生したある種のウィジェットまたはクラスであると想定しています。

その場合、クラスtimerEvent()ごとに定義されている をオーバーライドして、QObjectここにゲーム ループを実装できます。このようにして、 のパラメータを のrender_cell()メンバー変数にMainWindowするか、クラス全体game_processを に埋め込むことができますMainWindow

また、このアプローチはシグナルを使用するよりも少し速いと思います。これは、1 秒あたり 30 ~ 60 回何かをレンダリングし、他の多くのものを更新する必要があるコードにとって重要かもしれません。

ドキュメントについては、 http: //qt-project.org/doc/qt-4.8/qobject.html#timerEventを参照してください。

疑似コードでは、次のようにゲームを実装できます。

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 */);
    }

};
于 2013-05-01T20:12:34.047 に答える