2013-05-01 7 views
1

나는 게임을 쓰고있다. 틱 타이머는이 슬롯을 사용해야합니다.QTimer. 슬롯이 신호보다 매개 변수가 더 많으면 어떻게해야합니까?

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 & 단계))); 타이머 -> 시작();

그러나 신호보다 많은 슬롯을 볼 수 있으므로 신호 및 슬롯 메커니즘이 작동하지 않습니다. 무엇을해야합니까? 는 여기에 내가 조언 다음 코드를 조정

#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를()의 단 하나의 볼이 그려진 이유를 이해할 수없는 이틀간

enter link description here

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

. 나머지 공들은 그려지지 않습니다.

+0

질문에 온다? 그 정보로 그 클래스를위한 새로운 슬롯을 만들 수 있습니다. 그런 다음 필요한 모든 매개 변수를 사용하여 render_cell을 호출합니다. 매개 변수로 정보를받는 대신 render_cell에서 필요한 정보가있는 클래스를 쿼리하고 render_cell 슬롯을 유지할 수도 있습니다. –

+0

'timerEvent'는 이벤트이므로 이벤트 루프가 처리하도록해야합니다. 소스 코드에서 볼 수 있듯이 타이머가 시작될 때까지 기다리는 것이 바쁩니다. 그건 어떻게 작동하지 않습니다. 'timerEvent'는 당신을 위해 모든 시간을 예약하고 있습니다. 'timerEvent'에서'update()'를 호출하면 화면이 업데이트됩니다. 이것이 어떻게 작동하는지 예제를 보려면, 내 게임 [여기] (https://github.com/jcxz/Pexeso3D)을보고 'timerEvent' 자체를 사용할 수 있습니다. 중요한 파일은'Pexeso3D/src/game/CPexesoScene.cpp'이다. – jcxz

+0

또한,'delay' 함수에서 세미콜론이 누락되어 있습니다. 즉, while은 반복 만 처리합니다 (아마 원하는 것은 아니지만 오타가 될 수 있음). 그러나 CPU에 과도한 부하가 걸리기 때문에 이와 같은'delay' 함수의 사용을 중단해야합니다. 그 대신'timerEvent'에서 어떤 종류의 상태 머신을 구현하거나'singleShot QTimer'를 사용하는 것을 고려하십시오. – jcxz

답변

0

코드 조각에서 함수에 대한 포인터를 MainWindow에 전달하고있는 것을 볼 수 있습니다.이 함수는 QObject에서 파생 된 위젯이나 클래스라고 생각합니다.

이 경우 각각의 QObject 클래스에 대해 정의 된 timerEvent()을 재정 의하여 여기에 게임 루프를 구현할 수 있습니다. 이 방법으로 render_cell()의 매개 변수는 MainWindow의 멤버 변수가되거나 game_process 클래스 전체가 MainWindow에 포함될 수 있습니다.

또한이 접근법은 신호를 사용하는 것보다 약간 빠르다고 생각합니다. 이는 초당 30-60 회의 렌더링을하고 다른 많은 것들을 업데이트해야하는 코드에서 중요 할 수 있습니다. 의사 코드에서 문서를 참조 http://qt-project.org/doc/qt-4.8/qobject.html#timerEvent

를 들어

,이 같은 게임을 구현할 수 : 어떤 클래스가 요구하는 모든 정보에 접근 할 render_cell 것을 :

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

}; 
+0

좋은 답변을 주셔서 감사합니다 –

+0

상단 코드를 볼 수 있습니다. –

5

당신은 두 가지 방법이 있습니다

  1. 단순히 game_process::render_cell()를 호출 매개 변수없이 다른 슬롯을 정의를, 새로운 슬롯에 연결합니다.

  2. Qt 5를 사용하는 경우 람다를 사용하십시오. 예제는 here을 참조하십시오. 그것은 다음과 같이 보일 것입니다 :

connect(timer, &QTimer::timeout, [=](){/*call the function here*/}); 내가 # 2를 추천합니다.

+0

감사합니다. 목표를 달성하려고합니다. –

+0

+1 생명의 힘 : –