计算机软件技术实习项目二 贪吃蛇的游戏开发

目录

项目需求

 项目准备

 项目框架

 关键算法分析

 食物的生成

详细设计

 蛇的移动

判断蛇头是否对撞

判断蛇是否撞到墙体

成品展示

 项目总结


项目需求

  1. 实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子,上下左右控制“蛇”的移动,吃到“豆子”以后“蛇”的身体加长一点;
  2. “蛇”碰到边界或蛇头与蛇身相撞,蛇死亡,游戏结束;
  3. 为游戏设计友好的交互界面;例如欢迎界面,游戏界面,游戏结束界面。要有开始键、暂停键和停止退出的选项;
  4. 对蛇吃到豆子进行分值计算,可以设置游戏速度,游戏音乐等拓展元素。

 项目准备

  1. 仔细思考分析项目需求,生成项目的总体框架;
  2. 解决如何生成食物、蛇的移动、碰撞等问题,学习相关算法;
  3. 构造合适的界面UI;
  4. 思考拓展部分,比如双人模式,添加得分,移动速度等等。

 项目框架

 关键算法分析

 食物的生成

主体功能是随机生成食物的行列坐标值,但不能出现在蛇身中。如果出现在蛇身中,需要重新生成。除此以外,为保证游戏的激情, 生成食物的速度会根据得分逐渐加快。

 //判断是否吃到食物
   if(snake[0][0]==foodx&&snake[0][1]==foody)
    {
       //吃到食物发出声音
       sound->play();
        //如果吃到食物,食物坐标更新
       int i=0;
        foodcount++;
        score++;
        str1=QString::number(score);
        scoreshow->setText(str1);
        QTime t;
        t= QTime::currentTime();
        qsrand(t.msec()+t.second()*1000);
        foodx=qrand()%COL;
        foody=qrand()%ROW;
        while(i<=foodcount)
        {
            i++;
            //判断食物是否出现在蛇身上,如果出现在蛇身上重新产生食物
            if(snake[i][0]==foodx&&snake[i][1]==foody)
            {
                foodx=qrand()%COL;
                foody=qrand()%ROW;
                i=0;
            }
        }
        switch(score)
        {
        case 1:timer->setInterval(180);level++;break;
        case 10:timer->setInterval(160);level++;break;
        case 20:timer->setInterval(140);level++;break;
        case 30:timer->setInterval(120);level++;break;
        }
    }

详细设计

 蛇的移动

通过不断更改坐标值来实现。

 //实现蛇1的游动
    for(int i=foodcount;i>=1;i--)
    {
        snake[i][0]=snake[i-1][0];
        snake[i][1]=snake[i-1][1];
    }

    switch(direction)
    {
    case UP:snake[0][1]--;break;
    case DOWN:snake[0][1]++;break;
    case LEFT:snake[0][0]--;break;
    case RIGHT:snake[0][0]++;break;
    }
    //蛇2的游动
    for (int i_two=foodcount_two;i_two>=1;i_two--)
    {
        snake_two[i_two][0]=snake_two[i_two-1][0];
        snake_two[i_two][1]=snake_two[i_two-1][1];
    }
    switch(direction_two)
    {
    case UP_TWO:snake_two[0][1]--;break;
    case DOWN_TWO:snake_two[0][1]++;break;
    case LEFT_TWO:snake_two[0][0]--;break;
    case RIGHT_TWO:snake_two[0][0]++;break;
    }

判断蛇头是否对撞

通过坐标是否重合来判断,分为了两种情况。

for (int i =1;i<=foodcount;i++){
    if(snake_two[0][0]==snake[i][0]&&snake_two[0][1]==snake[i][1]){
        sound1->play();
        if(QMessageBox::question(this,"提示","玩家2被击杀",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
                      {
                      delete this;
                       return ;
                      }
    }
}


for (int i =1;i<=foodcount_two;i++){
    if(snake[0][0]==snake_two[i][0]&&snake[0][1]==snake_two[i][1]){
        sound1->play();
        if(QMessageBox::question(this,"提示","玩家1被击杀",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
                      {
                      delete this;
                       return ;
                      }
    }
}

判断蛇是否撞到墙体

游戏整体设计均为无法穿越墙体,通过蛇头坐标值与墙体行列的比较来实现

if(snake[0][0]<0||snake[0][0]>=COL||snake[0][1]<0||snake[0][1]>=ROW)
    {
        sound1->play();
       timer->stop();
       if(QMessageBox::question(this,"提示","玩家1撞墙,玩家2胜利!",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
      {delete this;
       return ;}

    }
   if(snake_two[0][0]<0||snake_two[0][0]>=COL||snake_two[0][1]<0||snake_two[0][1]>=ROW){
       sound1->play();
      timer->stop();
      if(QMessageBox::question(this,"提示","玩家2撞墙,玩家1胜利!",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
     {delete this;
      return ;}
       }

成品展示

 

 项目总结

在本实验项目中,我认为最难的部分在于设计蛇吃了一个食物之后身体的增长,主要是坐标的处理,为简化这个问题我才决定将游戏设置为碰到墙就结束游戏,个人觉得穿墙有点复杂;其次是食物的生成,以及两蛇相撞的设计,食物生成不仅要确保不生成在蛇身体上,还要确保随着玩家得分的增加,食物生成以及蛇移动速度的增加。

除此之外,我觉得这个最基本的游戏可以融入很多元素和技术,比如自动吃食物以及角色的选择和历史记录的保存,但对应都要有ui界面的设计,比较复杂。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值