我正在写一个游戏。通过滴答计时器应该工作这个插槽。
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();
但是你可以看到插槽比信号更多的参数,因此信号和插槽机制不起作用。该怎么办? 这里鳕鱼
#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;
}
}
}
}
两天我无法理解为什么只抽出一个球。剩下的球没有画出来。
答案 0 :(得分:5)
您有两种主要方法:
只需定义另一个没有参数的插槽即可调用game_process::render_cell()
,然后连接到新插槽。
如果您使用的是Qt 5,请使用lambda。有关示例,请参阅here。它看起来像这样:connect(timer, &QTimer::timeout, [=](){/*call the function here*/});
我建议#2。
答案 1 :(得分:0)
我从你的代码片段中看到你正在向你的MainWindow
函数传递一个指向render_cell()
的指针,我假设它是某种从QObject派生的小部件或类。
在这种情况下,您可以覆盖timerEvent()
,它是为每个QObject
类定义的,并在此处实现您的游戏循环。这样,render_cell()
的参数可以是MainWindow
的成员变量,也可以将整个game_process
类嵌入MainWindow
。
另外,我认为这种方法比使用信号要快一些,这对于必须每秒渲染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 */);
}
};