我真的在与这个奇怪的虫子争吵了一段时间。我的应用程序甚至在显示小部件之前就崩溃了(但是显示了窗口本身)。这是我的代码:
的main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("Snake");
w.resize(500, 500);
w.show();
QTimer* timer = new QTimer();
while(!w.checkCollision())
{
if(timer -> isActive() == false)
{
w.play();
timer -> start(1);
}
}
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPainter>
#include <QKeyEvent>
#include <QDebug>
#include <snakeclass.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
Snake snake;
void paintEvent(QPaintEvent*);
void keyEvent(QKeyEvent* keyevent);
void move();
bool checkCollision();
void play();
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QPainterPath>
#include <QKeyEvent>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
}
void MainWindow::paintEvent(QPaintEvent*)
{
QPainter painter(this);
// Draw black background.
painter.drawRect(0, 0, 500, 500);
painter.fillRect(0, 0, 500, 500, Qt::black);
for(unsigned int i = 0; i < snake.getLength(); i++)
{
// Draw green snake's body.
painter.setPen(Qt::green);
painter.setBrush(Qt::green);
// If i = 0, so if we are drawing snake's head.
if(i == 0)
{
// Draw red head.
painter.setPen(Qt::red);
painter.setBrush(Qt::red);
}
painter.drawEllipse((snake.getDot(i)).x, (snake.getDot(i)).y, 10, 10);
}
}
void MainWindow::keyEvent(QKeyEvent* keyevent)
{
if(keyevent -> key() == Qt::Key_Left)
{
if(snake.getDirection() != Snake::Direction::RIGHT)
{
snake.setDirection(Snake::Direction::LEFT);
}
}
else if(keyevent -> key() == Qt::Key_Right)
{
if(snake.getDirection() != Snake::Direction::LEFT)
{
snake.setDirection(Snake::Direction::RIGHT);
}
}
else if(keyevent -> key() == Qt::Key_Up)
{
if(snake.getDirection() != Snake::Direction::DOWN)
{
snake.setDirection(Snake::Direction::UP);
}
}
else if(keyevent -> key() == Qt::Key_Down)
{
if(snake.getDirection() != Snake::Direction::UP)
{
snake.setDirection(Snake::Direction::DOWN);
}
}
}
void MainWindow::move()
{
for(unsigned int i = snake.getLength(); i > 0; i--)
{
snake.editDot((snake.getDot(i - 1)).x, (snake.getDot(i - 1)).y, i, (snake.getDot(i - 1)).direction);
}
if(snake.getDirection() == Snake::Direction::UP)
{
if(int(snake.getDot(0).y - 10) < 0)
{
snake.editDot((snake.getDot(0)).x, 500, 0, snake.getDirection());
}
else
{
snake.editDot((snake.getDot(0)).x, (snake.getDot(0)).y - 10, 0, snake.getDirection());
}
}
else if(snake.getDirection() == Snake::Direction::DOWN)
{
if(((snake.getDot(0)).y + 10) > 490)
{
snake.editDot((snake.getDot(0)).x, 0, 0, snake.getDirection());
}
else
{
snake.editDot((snake.getDot(0)).x, (snake.getDot(0)).y + 10, 0, snake.getDirection());
}
}
else if(snake.getDirection() == Snake::Direction::RIGHT)
{
if(((snake.getDot(0)).x + 10) > 490)
{
snake.editDot(0, (snake.getDot(0)).y, 0, snake.getDirection());
}
else
{
snake.editDot((snake.getDot(0)).x + 10, (snake.getDot(0)).y, 0, snake.getDirection());
}
}
else if(snake.getDirection() == Snake::Direction::LEFT)
{
if((int((snake.getDot(0)).x) - 10) < 0)
{
snake.editDot(500, (snake.getDot(0)).y, 0, snake.getDirection());
}
else
{
snake.editDot((snake.getDot(0)).x - 10, (snake.getDot(0)).y, 0, snake.getDirection());
}
}
}
bool MainWindow::checkCollision()
{
for(unsigned int i = 0; i < snake.getLength(); i++)
{
for(unsigned int j = 0; j < snake.getLength(); j++)
{
if((i != j) && ((snake.getDot(i)).x == (snake.getDot(j)).x) && ((snake.getDot(i)).y == (snake.getDot(j)).y))
{
return true;
}
}
}
return false;
}
void MainWindow::play()
{
//move();
update();
}
MainWindow::~MainWindow()
{
delete ui;
}
snakeclass.h
#ifndef SNAKECLASS
#define SNAKECLASS
#include <vector>
class Snake
{
public:
enum class Direction
{
LEFT,
RIGHT,
UP,
DOWN
};
// Dot is a part of the snake.
struct dot
{
unsigned int x;
unsigned int y;
// Number of the dot (head is 0).
unsigned int dotNumber;
// Direction of the particular dot.
Direction direction;
};
unsigned int getLength();
unsigned int getScore();
unsigned int getSpeed();
Direction getDirection();
dot getDot(unsigned int dotNumber);
void setLength(unsigned int length);
void setScore(unsigned int score);
void setSpeed(unsigned int speed);
void setDirection(Direction direction);
// Returns new dot's dotNumber.
unsigned int newDot();
void editDot(unsigned int x, unsigned int y, unsigned int dotNumber, Direction direction);
private:
unsigned int length = 3;
unsigned int score = 0;
unsigned int speed = 1;
Direction direction = Direction::RIGHT;
std::vector <dot> dots = {dot {250, 250, 0, Direction::RIGHT},
dot {240, 250, 1, Direction::RIGHT},
dot {230, 250, 2, Direction::RIGHT}};
};
#endif // SNAKECLASS
snakeclass.cpp
#include "snakeclass.h"
unsigned int Snake::getLength()
{
return length;
}
unsigned int Snake::getScore()
{
return score;
}
unsigned int Snake::getSpeed()
{
return speed;
}
Snake::Direction Snake::getDirection()
{
return direction;
}
Snake::dot Snake::getDot(unsigned int dotNumber)
{
return dots.at(dotNumber);
}
void Snake::setLength(unsigned int length)
{
this -> length = length;
}
void Snake::setScore(unsigned int score)
{
this -> score = score;
}
void Snake::setSpeed(unsigned int speed)
{
this -> speed = speed;
}
void Snake::setDirection(Snake::Direction direction)
{
this -> direction = direction;
}
unsigned int Snake::newDot()
{
dot newDot;
newDot.dotNumber = dots.size();
dots.push_back(newDot);
length ++;
return newDot.dotNumber;
}
void Snake::editDot(unsigned int x, unsigned int y, unsigned int dotNumber, Snake::Direction direction)
{
for(unsigned int i = 0; i < dots.size(); i++)
{
if((dots.at(i)).dotNumber == dotNumber)
{
dots.at(i).x = x;
dots.at(i).y = y;
dots.at(i).direction = direction;
}
}
}
我是Qt5的新手,这是我的第一个涉及画家和键盘事件的项目。你能帮我弄清楚上面代码中的问题是什么吗?谢谢你的所有答案!
答案 0 :(得分:1)
我的应用程序甚至在显示小部件之前就崩溃了(但是显示了窗口本身)。
它没有崩溃。在main.cpp
中有一个无限循环,其中有一些结果是预期的,即!w.checkCollision()
,但由于在main.cpp
中没有运行事件循环,所以没有任何事情发生,并且程序在那里等待是徒劳的。
作为对您问题的回答,为了查看小部件,请按以下方式添加QApplication::processEvents();
:
while(!w.checkCollision())
{
QApplication::processEvents();
if(timer -> isActive() == false)
{
w.play();
timer -> start(1);
}
}
然而,通过这种方法,您将面临更多问题。因此,我强烈建议您查看Qt Creator中的示例,以便了解Qt开发人员认为使用库的正确方法。