QT实现贪吃蛇

board.h

#ifndefBOARD_H
#defineBOARD_H

#defineMAX_X40
#defineMAX_Y30
#defineNORMAL_LABEL0//普通label
#defineBORDER_LABEL1//边界label
#defineSNAKE_LABEL2//蛇身label
#defineFOOD_LABEL3//食物label

#include<QWidget>
#include<QLabel>
#include<QList>
#include<QTimer>
#include<QKeyEvent>

structNode{
QLabel*label;
inttype;//边界:1蛇身:2普通:0食物:3
intx;
inty;
};

classBoard:publicQWidget
{
Q_OBJECT
public:
explicitBoard(QWidget*parent=0);
voidinit();
voiddrawBorder();//画边界
voidinitSnake();
voidmoveStep();
voidgetHeadTail();//得到头和尾
boolleft();//判断是否能上下左右移动
boolright();
boolup();
booldown();
voidkeyPressEvent(QKeyEvent*e);//键盘事件
//voidgameover();
//voidshowAllType();
voidgenerateFood();//生成食物

signals:

publicslots:
voidslotMoveStep();//槽函数,可以当做普通函数使用


private:
Node*matrix[MAX_X][MAX_Y];
QList<Node*>snake;//蛇身

intdx,dy;
Node*head;//蛇头指针
Node*tail;//蛇尾指针

QTimertimer;

};

#endif//BOARD_H


boarder.cpp

#include"board.h"
#include<QDebug>
#include<QString>
#include<QTimer>
#include<QMessageBox>
#include<QKeyEvent>
#include<ctime>

Board::Board(QWidget*parent):
QWidget(parent)
{
this->setWindowTitle("贪吃蛇");
init();//初始化
drawBorder();//画边界
initSnake();//初始化蛇身
moveStep();

generateFood();//初始化完就产生一个食物

connect(&timer,SIGNAL(timeout()),this,SLOT(slotMoveStep()));
timer.start(100);

}

voidBoard::init(){
intgridSize=25;

for(intx=0;x<MAX_X;x++){
for(inty=0;y<MAX_Y;y++){
QLabel*label=newQLabel(this);
label->setStyleSheet("background:red");
label->setGeometry(x*gridSize,y*gridSize,gridSize-1,gridSize-1);
label->hide();
matrix[x][y]=newNode;
matrix[x][y]->label=label;
matrix[x][y]->type=NORMAL_LABEL;//将所有的都初始化成普通label
matrix[x][y]->x=x;
matrix[x][y]->y=y;
}
}
}

voidBoard::drawBorder(){//画边界
for(intx=0;x<MAX_X;x++){
for(inty=0;y<MAX_Y;y++){
if(x==0||x==MAX_X-1||y==0||y==MAX_Y-1){
matrix[x][y]->label->show();
matrix[x][y]->type=BORDER_LABEL;//边界label
}
}
}
}

voidBoard::initSnake(){//画蛇身
intx0=5,y0=5;
intsnakeLen=5;//初始蛇身长5

dx=1;
dy=0;
snake.clear();
for(intx=x0;x<x0+snakeLen;x++){

snake.append(matrix[x][y0]);
snake.at(snake.length()-1)->x=x;
snake.at(snake.length()-1)->y=y0;
matrix[x][y0]->type=SNAKE_LABEL;//蛇身label
matrix[x][y0]->label->show();
}

}

voidBoard::moveStep(){
getHeadTail();//获取蛇头和蛇尾指针
Node*n=matrix[head->x+dx][head->y+dy];
n->label->show();
//n是即将变成蛇头的那个label
if(n->type==BORDER_LABEL||n->type==SNAKE_LABEL){
qDebug()<<"Gameover@!!!";
timer.stop();
QMessageBox::information(this,"提示","***GameOver***",QMessageBox::Ok);
}else{
if(n->type==FOOD_LABEL){//吃到食物了
n->type=SNAKE_LABEL;
snake.append(n);
//不移除尾巴
generateFood();//生成下一个食物
}else{
n->type=SNAKE_LABEL;
snake.append(n);
tail->label->hide();
tail->type=NORMAL_LABEL;
snake.removeFirst();
}
}
}

voidBoard::getHeadTail(){
head=snake.at(snake.length()-1);//蛇头其实是list的尾巴
tail=snake.at(0);//蛇尾其实是list的第一个元素
//gameover();
}

voidBoard::slotMoveStep(){
//qDebug()<<"movestep";
moveStep();
}

voidBoard::keyPressEvent(QKeyEvent*e){
//qDebug()<<Qt::Key_up;
qDebug()<<e->key();
switch(e->key()){
case16777235://上
if(up()){
dy=-1;
dx=0;
}
break;
case16777237://下
if(down()){
dy=1;
dx=0;
}
break;
case16777234://左
if(left()){
dx=-1;
dy=0;
}
break;
case16777236://右
if(right()){
dx=1;
dy=0;
}
break;
default:
break;;
}
}

voidBoard::generateFood(){//生成食物
intfood_x,food_y;
srand((unsigned)time(0));
do{
food_x=rand()%MAX_X;
food_y=rand()%MAX_Y;
}while(matrix[food_x][food_y]->type!=NORMAL_LABEL);
//matrix[food_x][food_y]->label->setText("food");
matrix[food_x][food_y]->type=FOOD_LABEL;
matrix[food_x][food_y]->label->show();

}

boolBoard::left(){
if(dy==0){//向左或向右走
returnfalse;
}
returntrue;
}

boolBoard::right(){
if(dy==0){//向左或向右走
returnfalse;
}
returntrue;
}

boolBoard::up(){
if(dx==0){//向上或向下走
returnfalse;
}
returntrue;
}

boolBoard::down(){
if(dx==0){//向上或向下走
returnfalse;
}
returntrue;
}


wKiom1Oeqa-ymO_qAAG6R9KtXxQ333.jpg

本文出自 “阿凡达” 博客,请务必保留此出处http://shamrock.blog.51cto.com/2079212/1426968

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值