/****************************************************************************
** 贪吃蛇程序说明:
**
** 上下左右控制方向,esc重新开始,P键暂停游戏
**
** 游戏5个关卡,gamespeed为游戏速度,吃10个方块进入下关,游戏暂停,按P键继续
**
** QT3的代码,供大家交流!
**
** --by snailshell mail:youngst@yeah.net
****************************************************************************/
#include <qapplication.h>
#include <qpalette.h>
#include "snake.h"
#define N 100
#define LEFT 0x1012
#define RIGHT 0x1014
#define DOWN 0x1015
#define UP 0x1013
#define ESC 0x1000
#define PAUSE 0X50
struct Food
{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
}food;
/*食物的结构体*/
struct Snake
{
int x[N];
int y[N];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
}snake;
SnakeGame::SnakeGame(QWidget *parent,const char *name,WFlags f):QWidget(parent,name,f)
{
SnakeTime=new QTimer(this);
QObject::connect(SnakeTime,SIGNAL(timeout()),this,SLOT(SnakeRun()));
lcd =new QLCDNumber(5,this,"");
lcd->setSegmentStyle( QLCDNumber::Flat );
lcd->setFrameStyle( QFrame::NoFrame | QFrame::Plain );
InitGame();
}
void SnakeGame::paintEvent(QPaintEvent *event)
{
QPainter paint( this );
QRect v = paint.viewport();
paint.setViewport( v.left() ,
v.top() , width(), height());
lcd->setGeometry(width()-100,5,100,30);
DrawGame(&paint);
PlayGame(&paint);
}
void SnakeGame::InitGame()
{
pause=1;stage=1,score=0;gamespeed =400;
key=0;
setPaletteBackgroundColor(QColor(192,253,123));
SnakeTime->start(gamespeed,false);
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=50;snake.y[0]=100;/*蛇头*/
snake.x[1]=40;snake.y[1]=100;
snake.node=2;/*节数*/
}
void SnakeGame::SnakeRun()
{
update();
}
void SnakeGame::GameScore()
{
lcd->display
(score);
}
void SnakeGame::DrawGame(QPainter *painter)
{
painter->setPen( QPen(QColor( 41,75,35),1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
for(i=0;i<=18;i+=2)/*画围墙*/
{
painter->drawRect(i,i+40,width()-2*i,height()-2*i-40);
}
}
void SnakeGame::PlayGame(QPainter *painter)
{
GameScore();/*输出得分*/
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%width()/2+20;
food.y=rand()%height()/2+20+40;
while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%10!=0)
food.y++;
food.yes=0;/*画面上有食物了*/
}
if(food.yes==0)/*画面上有食物了就要显示*/
{painter->setBrush( QColor(Qt::yellow ));
painter->drawRoundRect(food.x,food.y,10,10,50,50);
}
if(snake.life==0&&pause==1)/*蛇移动*/
{
QString str;
str = QString( "GAME STAGE : %1" )
.arg( stage);
painter->drawText(10,20,str);
for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
if(key==UP&&snake.direction!=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
switch(snake.direction)
{
case 1: snake.x[0]+=10;break;
case 2: snake.x[0]-=10;break;
case 3: snake.y[0]-=10;break;
case 4: snake.y[0]+=10;break;
}
for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
snake.life=1;
break;
}
}
if(snake.x[0]<30||snake.x[0]>width()-40||snake.y[0]<70||
snake.y[0]>height()-40)/*蛇是否撞到墙壁*/
{
snake.life=1; /*蛇死*/
}
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/
{
painter->setBrush( QColor( 192,253,123));
painter->drawRoundRect(food.x,food.y,10,10,50,50); /*把画面上的食物东西去掉*/
snake.x[snake.node]=-20;snake.y[snake.node]=-20;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=10;
GameScore();/*输出新得分*/
if(snake.node>10*stage+1&&stage<6)
{
stage+=1;
gamespeed=gamespeed-100;
pause=0;
}/*关卡速度变快,游戏暂停*/
}
}
else
{
SnakeTime->stop();
if(pause==1)painter->drawText(10,20,"GAME OVER!");
else painter->drawText(10,20,"GAME PAUSE!");
}/*游戏结束、暂停*/
painter->setBrush( QColor( Qt::red));
painter->drawRoundRect(snake.x[0],snake.y[0],10,
10,50,50);
painter->setBrush( QColor( Qt::blue));
for(i=1;i<snake.node;i++)
painter->drawRoundRect(snake.x[i],snake.y[i],10,
10,50,50);/*画出蛇*/
painter->setPen( QPen(QColor( QColor(192,253,123)),1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
painter->setBrush( QColor( 192,253,123));
painter->drawRoundRect(snake.x[snake.node-1],snake.y[snake.node-1],
10,10,50,50);/*去除蛇的的最后一节*/
}
void SnakeGame::keyPressEvent(QKeyEvent *k)
{
key= k->key();
if(key==ESC){SnakeTime->stop();InitGame();}
if(key==PAUSE)
{
if(SnakeTime->isActive())
{//SnakeTime->stop();
pause=0;}
else
{
SnakeTime->start(gamespeed,false);
pause=1;
}
}
}
- 1
- 2
- 3
- 4
前往页