贪吃蛇项目要求:
(1)实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”。玩家能利用上下左右键控制“蛇”的移动,“蛇”吃到“食物”后“蛇”身体加长一节,得分增加,“蛇”碰到边界或蛇头与蛇身相撞,“蛇”死亡,游戏结束。
(2)进行交互界面的设计,要有开始键、暂停键和停止退出的选项,能够控制游戏进程。对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。
需要的知识:QT基础知识,基本算法知识
需要解决的问题:
1.如何存储蛇:将蛇存储为一个队列,其中放入矩形元素;
2.如何在屏幕上画出蛇和食物:通过QT的printEvent来处理画图
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)); //奖励节点
}
3.如何让蛇移动和控制难度:设置一个定时器,定时器超时就会调用相关函数,可以通过定时器设置的时间来控制难度
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;
}
flage++;
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();
}
4.如何生成食物?
通过一个定时器,定时器超时后进行食物的生成
void Widget::rewardTimeOut()
{
srand(QTime(0,0,0).secsTo(QTime::currentTime()));
if(rewardNode.length() > 5){
rewardNode.removeAt(rand()%5);
}
rewardNode.append(QRectF(rand()%(this->width()/20)*20,rand()%(this->height()/20)*20+70,snakeNodeWidth,snakeNodeWidth));
if(rand()%5 == 3){
rewardNode.append(QRectF(rand()%(this->width()/20)*20-5,rand()%(this->height()/20)*20-5+70,snakeNodeWidth*2,snakeNodeWidth*2));
}
}
5.如何判断游戏结束?
枚举蛇的每一部分,检查是否碰撞
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;
}
6.如何实现移动并穿越墙壁?(以向上穿越为例)
void Widget::addTopRectF()
{
if(snake.at(0).y()-snakeNodeHeight < 70){
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()));
}
}
贪吃蛇运行主要界面如下