zoukankan      html  css  js  c++  java
  • 贪吃蛇easyx版本

    这学期学了图形交互学,三个星期下来,突然意识到已经可以用c++写一个贪吃蛇了。

    于是就用了两天写了这个小游戏。

    其中一天写了核心代码,半天找核心代码中的bug,还有半天进行了界面及操作的优化。

    但是有些代码写的依旧有些累赘,比如难度选择界面,不停用if语句,代码太杂了,但是也懒得去优化了,毕竟还有很多事情要做。

    下面是游戏运行程序,建议在win10下运行,因为找了几个win7win8系统的童鞋貌似都不能运行,给了他们运行库,运行库也安装不上去。

    点击这里下载游戏源程序。

    下面是游戏界面截图。

    好了接下来就贴出这些代码。仅供参考。

      1 #include "stdafx.h"
      2 #include <time.h>
      3 #include <conio.h>
      4 #include <graphics.h>
      5 #include <iostream>
      6 using namespace std;
      7 
      8 //bug:运行游戏开始后不能按除方向键和wasd键外的其它键,不然会提示撞墙
      9 
     10 
     11 /*画窗体边框*/
     12 void drawBorder(bool i, int borderWidth)
     13 {
     14     if (i)
     15     {
     16         setfillcolor(GREEN);
     17     }
     18     else
     19     {
     20         setfillcolor(RED);
     21     }
     22     bar(0, 0, getmaxx(), borderWidth - 1 - 1);//上边框
     23     bar(0, 0, borderWidth - 1 - 1, getmaxy());//左边框
     24     bar(getmaxx() - borderWidth + 1, 0, getmaxx(), getmaxy());//右边框
     25     bar(0, getmaxy() - borderWidth + 1, getmaxx(), getmaxy());//下边框
     26 }
     27 
     28 /*贪吃蛇结构体*/
     29 struct Snake
     30 {
     31     int snakeX;
     32     int snakeY;
     33 };
     34 void drawSnake(struct Snake snakeHeadTemp, int snakeR)
     35 {
     36     setfillcolor(WHITE);
     37     solidcircle(snakeHeadTemp.snakeX, snakeHeadTemp.snakeY, snakeR);
     38 }
     39 //擦除蛇尾
     40 bool eraseSnake(struct Snake snakeHeadTemp, struct Snake snakeTail, int snakeR, struct Snake snakeFood)
     41 {
     42     if ((snakeHeadTemp.snakeX == snakeFood.snakeX) && (snakeHeadTemp.snakeY == snakeFood.snakeY))
     43     {
     44         return true;//如果相同,则返回true,说明需要重新绘制一个食物并且不擦除当前蛇尾
     45     }
     46     else
     47     {
     48         setfillcolor(BLACK);
     49         solidcircle(snakeTail.snakeX, snakeTail.snakeY, snakeR);
     50         return false;
     51     }
     52 }
     53 //检测是否和自身相撞
     54 bool checkSnake(struct Snake *snake, struct Snake snakeHeadTemp, int * snakeLenPtr)
     55 {
     56     for (int i = 0; i < *snakeLenPtr; i++)
     57     {
     58         if (((snake + i)->snakeX == snakeHeadTemp.snakeX) && ((snake + i)->snakeY == snakeHeadTemp.snakeY))
     59         {
     60             return false;
     61         }
     62     }
     63     return true;
     64 }
     65 //对数组排序
     66 void sortSnake(struct Snake *snake, struct Snake snakeHeadTemp, int * snakeLenPtr)
     67 {
     68     for (int i = *snakeLenPtr - 1; i >= 0; i--)//妈蛋,i>=0i>=0i>=0罚抄一百遍!这个bug找了整整半天啊卧槽!
     69     {
     70         (snake + i + 1)->snakeX = (snake + i)->snakeX;
     71         (snake + i + 1)->snakeY = (snake + i)->snakeY;
     72     }
     73     snake->snakeX = snakeHeadTemp.snakeX;
     74     snake->snakeY = snakeHeadTemp.snakeY;
     75 }
     76 //去除尾巴
     77 void eraseTail(struct Snake snakeTail, int snakeR)
     78 {
     79     setfillcolor(BLACK);
     80     solidcircle(snakeTail.snakeX, snakeTail.snakeY, snakeR);
     81 }
     82 //主函数
     83 int main() {
     84     int screenX = 800;//窗口宽
     85     int screenY = 600;//窗口高
     86     int borderWidth = 20;//游戏边框宽度
     87     int snakeX = 50;
     88     int snakeY = 30;
     89     int snakeR = 10;
     90     int snakeI;//声明食物的横个数
     91     int snakeJ;//声明化食物的纵个数
     92     char ch = 'd';
     93     int foodCount = 0;//初始化吃掉的食物个数
     94     TCHAR str[100];//用于存储提示文字
     95 
     96     initgraph(screenX, screenY);
     97     int speed = 100;
     98 
     99     char choose;
    100     int hard = 1;
    101 
    102     restart:
    103     //初始化开始界面
    104     setfillcolor(BLUE);
    105     bar(0, 0, getmaxx(), getmaxy());
    106     setbkcolor(BLUE);
    107     setcolor(WHITE);
    108     settextstyle(30, 0, TEXT("黑体"));
    109     outtextxy(getmaxx() / 2 - 75, getmaxy() / 2 - 200, TEXT("英雄贪吃蛇"));
    110     settextstyle(15, 0, TEXT("黑体"));
    111     outtextxy(getmaxx() / 2 - 80, getmaxy() / 2 - 130, TEXT("请选择难度,切勿手滑"));
    112     setcolor(YELLOW);
    113     outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));//200
    114     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));//200
    115     setcolor(WHITE);
    116     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));//100
    117     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));//30
    118     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));//20
    119     outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));//退出
    120     settextstyle(13, 0, TEXT("黑体"));
    121     outtextxy(getmaxx() / 2 - 70, getmaxy() - 50, TEXT("版本 v1.1 made by cy"));
    122 
    123     //选择界面12 -32
    124     while (choose = _getch())
    125     {
    126         if (choose == -32) { choose = _getch(); }
    127         if (choose == 13)
    128         {
    129             if (hard == 1) { speed = 100; }
    130             if (hard == 2) { speed = 80; }
    131             if (hard == 3) { speed = 50; }
    132             if (hard == 4) { speed = 25; }
    133             if (hard == 5) { return 0; }
    134             break;
    135         }
    136         if (choose == 72) 
    137         {
    138             if (hard > 1) { hard--; }
    139             else{ hard = 5; }
    140         }
    141         if (choose == 80)
    142         {
    143             if (hard < 5) { hard++; }
    144             else { hard = 1; }
    145         }
    146         if (hard == 1)
    147         {
    148             settextstyle(15, 0, TEXT("黑体"));
    149             setcolor(BLUE);
    150             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
    151             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
    152             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
    153             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
    154             setcolor(YELLOW);
    155             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
    156             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
    157             setcolor(WHITE);
    158             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
    159             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
    160             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
    161             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
    162             speed = 100;
    163         }
    164         if (hard == 2)
    165         {
    166             settextstyle(15, 0, TEXT("黑体"));
    167             setcolor(BLUE);
    168             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
    169             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
    170             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
    171             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
    172             setcolor(WHITE);
    173             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
    174             setcolor(YELLOW);
    175             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
    176             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
    177             setcolor(WHITE);
    178             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
    179             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
    180             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
    181             speed = 80;
    182         }
    183         if (hard == 3)
    184         {
    185             settextstyle(15, 0, TEXT("黑体"));
    186             setcolor(BLUE);
    187             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
    188             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
    189             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
    190             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
    191             setcolor(WHITE);
    192             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
    193             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
    194             setcolor(YELLOW);
    195             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
    196             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
    197             setcolor(WHITE);
    198             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
    199             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
    200             speed = 50;
    201         }
    202         if (hard == 4)
    203         {
    204             settextstyle(15, 0, TEXT("黑体"));
    205             setcolor(BLUE);
    206             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
    207             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
    208             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
    209             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
    210             setcolor(WHITE);
    211             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
    212             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
    213             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
    214             setcolor(YELLOW);
    215             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
    216             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
    217             setcolor(WHITE);
    218             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
    219             speed = 25;
    220         }
    221         if (hard == 5)
    222         {
    223             settextstyle(15, 0, TEXT("黑体"));
    224             setcolor(BLUE);
    225             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 70, TEXT("->"));
    226             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 40, TEXT("->"));
    227             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 - 10, TEXT("->"));
    228             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 20, TEXT("->"));
    229             setcolor(WHITE);
    230             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 70, TEXT("脑残模式"));
    231             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 40, TEXT("凡人模式"));
    232             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 - 10, TEXT("大仙模式"));
    233             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 20, TEXT("自虐模式"));
    234             setcolor(YELLOW);
    235             outtextxy(getmaxx() / 2 - 50, getmaxy() / 2 + 50, TEXT("->"));
    236             outtextxy(getmaxx() / 2 - 30, getmaxy() / 2 + 50, TEXT("退出游戏"));
    237         }
    238     }
    239 
    240 
    241 
    242     setfillcolor(BLACK);
    243     settextstyle(20, 0, TEXT("黑体"));
    244     bar(0, 0, getmaxx(), getmaxy());
    245     setcolor(WHITE);
    246     setbkcolor(BLACK);
    247     outtextxy(getmaxx() / 2 - 135, getmaxy()/2-50, TEXT("食物还有5秒到达战场,碾碎它们!"));
    248     settextstyle(15, 0, TEXT("黑体"));
    249     outtextxy(getmaxx() / 2 - 175, getmaxy() / 2, TEXT("小提示:除了方向键,还可以用wasd键来控制方向哦~"));
    250     Sleep(5000);
    251     bar(0, 0, getmaxx(), getmaxy());
    252 
    253     drawBorder(true, borderWidth);
    254     //初始化贪吃蛇
    255     setfillcolor(YELLOW);
    256     int snakeLen = 1; int * snakeLenPtr = &snakeLen;//蛇的节点数,默认为1,即游戏一开始就有一个蛇头
    257     struct Snake snake[1064];
    258     snake->snakeX = borderWidth + 9; snake->snakeY = borderWidth + 9;//初始化蛇头
    259     solidcircle(snake->snakeX, snake->snakeY, snakeR);//初始化蛇头
    260     struct Snake snakeTail;//定义蛇尾snakeTail以及一个暂存蛇头的变量
    261     struct Snake snakeHeadTemp;//snakeHeadTemp用于在进行数组向后移动的时候保证蛇头不被覆盖
    262     struct Snake snakeFood;//snake的食物,随机产生
    263     //整个游戏思路是,如果蛇头遇到了新的食物,那么不擦除蛇尾,反之则擦除蛇尾
    264 
    265     //随机产生一个食物
    266     srand(time(NULL));
    267     snakeI = rand() % 38 + 1;
    268     snakeJ = rand() % 28 + 1;
    269     snakeFood.snakeX = borderWidth - 11 + 20 * snakeI;
    270     snakeFood.snakeY = borderWidth - 11 + 20 * snakeJ;
    271     setfillcolor(LIGHTRED);
    272     solidcircle(snakeFood.snakeX, snakeFood.snakeY, snakeR);
    273 
    274     char c;//用于处理方向键控制和wasd键的冲突
    275     while (1)
    276     {
    277         if (_kbhit())
    278         {
    279             c = _getch();
    280             if (c == 'a' || c == 'd' || c == 'w' || c == 's') { ch = c; }
    281             else {
    282                 ch = _getch();
    283                 if (ch == 75) { ch = 'a'; }
    284                 if (ch == 77) { ch = 'd'; }
    285                 if (ch == 72) { ch = 'w'; }
    286                 if (ch == 80) { ch = 's'; }
    287             }
    288         }
    289         //存储蛇尾以及待添加的位置的值
    290         snakeTail.snakeX = snake[snakeLen - 1].snakeX;
    291         snakeTail.snakeY = snake[snakeLen - 1].snakeY;
    292 
    293         switch (ch)
    294         {
    295         case 'a'://
    296             snakeHeadTemp.snakeX = snake->snakeX - 20;
    297             snakeHeadTemp.snakeY = snake->snakeY;
    298             break;
    299         case 'd'://
    300             snakeHeadTemp.snakeX = snake->snakeX + 20;
    301             snakeHeadTemp.snakeY = snake->snakeY;
    302             break;
    303         case 'w'://
    304             snakeHeadTemp.snakeY = snake->snakeY - 20;
    305             snakeHeadTemp.snakeX = snake->snakeX;
    306             break;
    307         case 's'://
    308             snakeHeadTemp.snakeY = snake->snakeY + 20;
    309             snakeHeadTemp.snakeX = snake->snakeX;
    310             break;
    311         default:
    312             break;
    313         }
    314         //如果撞墙了
    315         if (snakeHeadTemp.snakeX > 769 || snakeHeadTemp.snakeX < 19 || snakeHeadTemp.snakeY < 19 || snakeHeadTemp.snakeY > 569)
    316         {
    317             drawBorder(false, borderWidth);
    318             setfillcolor(LIGHTGRAY);
    319             bar(0, getmaxy() / 2 - 30, getmaxx(), getmaxy() / 2 + 40);//提示框
    320             setbkcolor(LIGHTGRAY);
    321             _stprintf_s(str, _T("你撞墙啦!总共吃了%d个食物,5秒后自动重新开始游戏,渣渣⋯⋯"), foodCount);
    322             outtextxy(getmaxx() / 2 - 210, getmaxy() / 2, str);
    323             Sleep(5000);
    324             ch='d';
    325             hard = 1;
    326             foodCount = 0;
    327             goto restart;
    328         }
    329         if (checkSnake(snake, snakeHeadTemp, snakeLenPtr))
    330         {
    331             drawSnake(snakeHeadTemp, snakeR);
    332             sortSnake(snake, snakeHeadTemp, snakeLenPtr);//更新蛇身体内的数据
    333             //如果为真,说明吃到了食物,则需要重新分配一个食物。并且要把snakeTail推入数组
    334             if (eraseSnake(snakeHeadTemp, snakeTail, snakeR, snakeFood))
    335             {
    336                 foodCount++;
    337                 snake[snakeLen].snakeX = snakeTail.snakeX;
    338                 snake[snakeLen].snakeY = snakeTail.snakeY;
    339                 snakeLen++;
    340                 eraseTail(snakeTail, snakeR);
    341                 sortSnake(snake, snakeHeadTemp, snakeLenPtr);//更新蛇身体内的数据
    342                                                              //随机产生一个食物
    343                 snakeI = rand() % 38 + 1;
    344                 snakeJ = rand() % 28 + 1;
    345                 snakeFood.snakeX = borderWidth - 11 + 20 * snakeI;
    346                 snakeFood.snakeY = borderWidth - 11 + 20 * snakeJ;
    347             }
    348             //每一步都刷新一下食物,因为有时会生成在蛇的身体上,如果不刷新就会被蛇的身体遮挡掉
    349             setfillcolor(LIGHTRED);
    350             solidcircle(snakeFood.snakeX, snakeFood.snakeY, snakeR);
    351         }
    352         else
    353         {
    354             drawBorder(false, borderWidth);
    355             setfillcolor(LIGHTGRAY);
    356             bar(0, getmaxy() / 2 - 30, getmaxx(), getmaxy() / 2 + 40);//提示框
    357             setbkcolor(LIGHTGRAY);
    358             _stprintf_s(str, _T("居然会有人撞到自己!噗笑尿!总共吃了%d个食物,5秒后自动重新开始游戏,渣渣⋯⋯"), foodCount);
    359             outtextxy(getmaxx() / 2 - 310, getmaxy() / 2, str);
    360             Sleep(5000);
    361             ch = 'd';
    362             hard = 1;
    363             foodCount = 0;
    364             goto restart;
    365         }
    366         Sleep(speed);
    367     }
    368     closegraph();
    369     return 0;
    370 }
  • 相关阅读:
    R语言代写实现 Copula 算法建模依赖性案例分析报告
    R语言代写回归中的Hosmer-Lemeshow拟合优度检验
    ggplot2如何在R语言代写中绘制表格
    用SAS代写进行泊松,零膨胀泊松和有限混合Poisson模型分析
    R语言代写实现有限混合模型建模分析
    R语言代写使用混合模型进行聚类
    BZOJ 4370: [IOI2015]horses马 线段树+贪心+对数
    luoguP5824 十二重计数法 组合+生成函数+第二类斯特林数
    BZOJ 5296: [Cqoi2018]破解D-H协议 BSGS
    BZOJ 2242: [SDOI2011]计算器 BSGS
  • 原文地址:https://www.cnblogs.com/chenyangsocool/p/5303771.html
Copyright © 2011-2022 走看看