好家伙,我直接好家伙,拿走直接运行~
看下效果,再下拉看代码实现 ! ! !
老规矩,直接上代码<双击空格开始,单击空格控制暂停与开始>
.h写的啥
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QKeyEvent>
#include <QRectF>
#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QDebug>
#include <QTimer>
#include <QTime>
namespace Ui {
class Widget;
}
class Widget : public QWidget // 继承QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
protected:
void paintEvent(QPaintEvent *);
void keyPressEvent(QKeyEvent *);
private:
void addTopRectF(); // 上
void addDownRectF(); // 下
void addLeftRectF(); // 左
void addRightRectF(); // 右
void deleteLastRectF(); // 删除last数据
bool snakeStrike(); // 判断是否相撞
enum Move{ Left,Right,Up,Down};
protected slots:
void timeOut();
void rewardTimeOut();
private:
Ui::Widget *ui;
QList<QRectF> snake;
int snakeNodeWidth = 10;
int snakeNodeHeight = 10;
QTimer *timer;
QTimer *rewardTimer;
int time = 100;
int moveFlage = Up;
bool gameOver = false;
bool gameStart = false;
QList<QRectF> rewardNode;
};
#endif // WIDGET_H
.cpp写的啥
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
resize(600,500);
setStyleSheet("QWidget{background:gray}");
snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight));
addTopRectF();
addTopRectF();
// 在坐标(400,200)处设置第一个瓜
rewardNode.append(QRectF(400,200,snakeNodeWidth,snakeNodeWidth));
timer = new QTimer;
connect(timer, SIGNAL(timeout()),this,SLOT(timeOut()));
rewardTimer = new QTimer;
connect(rewardTimer,SIGNAL(timeout()),this,SLOT(rewardTimeOut()));
this->setWindowTitle("All In 贪吃蛇Demo");
}
Widget::~Widget()
{
delete ui;
}
void Widget::timeOut()
{
int flage = 1;
for(int i=0; i<rewardNode.length(); i++){
if(rewardNode.at(i).contains(snake.at(0).topLeft()+QPointF(snakeNodeWidth/2,snakeNodeHeight/2))){
if(rewardNode.at(i).width()>snakeNodeWidth){
flage += 2; // 吃个大瓜+2
}
flage++; // 吃个小瓜+1
rewardNode.removeAt(i);
break;
}
}
while(flage--){
switch (moveFlage) {
case Up:
addTopRectF();
break;
case Down:
addDownRectF();
break;
case Right:
addRightRectF();
break;
case Left:
addLeftRectF();
break;
default:
break;
}
}
deleteLastRectF();
update();
}
void Widget::rewardTimeOut()
{
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
if(rewardNode.length() > 5){
rewardNode.removeAt(qrand()%5);
}
rewardNode.append(QRectF(qrand()%(this->width()/20)*20,qrand()%(this->height()/20)*20,snakeNodeWidth,snakeNodeWidth));
if(qrand()%5 == 3){
rewardNode.append(QRectF(qrand()%(this->width()/20)*20-5,qrand()%(this->height()/20)*20-5,snakeNodeWidth*2,snakeNodeWidth*2));
}
}
// 向上移动
void Widget::addTopRectF()
{
if(snake.at(0).y()-snakeNodeHeight < 0){
snake.insert(0,QRectF(QPointF(snake.at(0).x(),this->height()-snakeNodeHeight),
QPointF(snake.at(0).x()+snakeNodeWidth,this->height())));
}else{
snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(0,-snakeNodeHeight),snake.at(0).topRight()));
}
}
// 向下移动
void Widget::addDownRectF()
{
if(snake.at(0).y()+snakeNodeHeight*2 > this->height()){
snake.insert(0,QRectF(QPointF(snake.at(0).x(),snakeNodeHeight),
QPointF(snake.at(0).x()+snakeNodeWidth,0)));
}else{
snake.insert(0,QRectF(snake.at(0).bottomLeft(),snake.at(0).bottomRight()+QPointF(0,snakeNodeHeight)));
}
}
// 向左移动
void Widget::addLeftRectF()
{
if(snake.at(0).x()-snakeNodeWidth < 0){
snake.insert(0,QRectF(QPointF(this->width()-snakeNodeWidth,snake.at(0).y()),
QPointF(this->width(),snake.at(0).y()+snakeNodeHeight)));
}else{
snake.insert(0,QRectF(snake.at(0).topLeft()+QPointF(-snakeNodeWidth,0),snake.at(0).bottomLeft()));
}
}
// 向右移动
void Widget::addRightRectF()
{
if(snake.at(0).x()+snakeNodeWidth*2 > this->width()){
snake.insert(0,QRectF(QPointF(0,snake.at(0).y()),
QPointF(snakeNodeWidth,snake.at(0).y()+snakeNodeHeight)));
}else{
snake.insert(0,QRectF(snake.at(0).topRight(),snake.at(0).bottomRight()+QPointF(snakeNodeWidth,0)));
}
}
// 删除结尾数据
void Widget::deleteLastRectF()
{
snake.removeLast();
}
// 绘图
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen pen;
QBrush brush;
QFont fontg ( "Microsoft YaHei", 20, 50);
painter.setRenderHint(QPainter::Antialiasing);
pen.setColor(Qt::black);
brush.setColor(Qt::lightGray);
brush.setStyle(Qt::SolidPattern);
painter.setPen(pen);
painter.setBrush(brush);
for(int i=0; i<snake.length(); i++){
painter.drawRect(snake.at(i));
}
brush.setColor(Qt::green);
painter.setBrush(brush);
for(int i=0; i<rewardNode.length(); i++){
painter.drawEllipse(rewardNode.at(i));
}
pen.setColor(Qt::black);
painter.setPen(pen);
painter.setFont(fontg);
painter.drawText(245,40,QString("分数:")+QString("%1").arg(snake.length()));
if(snakeStrike()){
QFont font("方正舒体",30,QFont::ExtraLight,false);
painter.setFont(font);
painter.drawText((this->width()-300)/2,(this->height()-30)/2,QString("GAME OVER!"));
timer->stop();
rewardTimer->stop();
gameOver = true;
}
QWidget::paintEvent(event);
}
void Widget::keyPressEvent(QKeyEvent *event)
{
switch(event->key()){
case Qt::Key_Up:
if(moveFlage != Down){
moveFlage = Up;
}
break;
case Qt::Key_Down:
if(moveFlage != Up){
moveFlage = Down;
}
break;
case Qt::Key_Right:
if(moveFlage != Left){
moveFlage = Right;
}
break;
case Qt::Key_Left:
if(moveFlage != Right){
moveFlage = Left;
}
break;
case Qt::Key_Enter:
case Qt::Key_Return:
if(gameOver){
snake.clear();
rewardNode.clear();
moveFlage = Up;
snake.append(QRectF(200,500,snakeNodeWidth,snakeNodeHeight));
addTopRectF();
addTopRectF();
//首先生成一个奖励节点
rewardNode.append(QRectF(100,100,snakeNodeWidth,snakeNodeWidth));
timer->start(time);
rewardTimer->start(time*30);
gameOver = false;
}
break;
case Qt::Key_Space:
if(gameStart && !gameOver){
timer->start(time);
rewardTimer->start(time*30);
gameStart = false;
}else if(!gameStart && !gameOver){
timer->stop();
rewardTimer->stop();
gameStart = true;
}
break;
default:
break;
}
}
// 判断是否相撞
bool Widget::snakeStrike()
{
for(int i=0; i<snake.length(); i++){
for(int j=i+1; j<snake.length(); j++){
if(snake.at(i) == snake.at(j)){
return true;
}
}
}
return false;
}