C语言C++图形库 您所在的位置:网站首页 eup游戏画面 C语言C++图形库

C语言C++图形库

2024-03-15 18:55| 来源: 网络整理| 查看: 265

这一节中,我们来做一款经典小游戏,贪吃蛇。先看看最终效果图

 

在开始之前,我们把窗体创建好。

创建一个800 * 600的窗体。这一次我们使用默认的原点和坐标轴:原点在窗体左上角,X轴正方向向右,Y轴正方向向下。背景色设置为RGB(164, 225, 202),最后调用cleardevice函数,使用背景色清空整个窗体。

#include  #include  int main() {     initgraph(800, 600);     //  设置背景色     setbkcolor(RGB(164, 225, 202));     //  使用背景色清空窗体     cleardevice();     getchar();     closegraph();     return 0; } 1. 定位网格

图片

将整个800 * 600的窗体,水平分隔为20等分,垂直分隔为15等分,作为整个游戏的网格坐标系统。在上图中,蛇用5格白色的矩形表示。食物用黄色的一格矩形表示。

图片

这样,蛇的每一格身体坐标为:

(5, 7)

(4, 7)

(3, 7)

(2, 7)

(1, 7)

食物的坐标为:

(12, 7)

为了方便观察,把窗体用线段画上上述网格。网格每一格的宽度设为40像素,用符号常量NODE_WIDTH表示。

#define NODE_WIDTH 40 竖向线段

先绘制竖向的线段。

竖向线段中,起始点y坐标固定为0,终止点y坐标固定为600。

图片

每条线段的起始点与终止点的x坐标一致,且随着线段不同而变化。

图片

设线段条数从0开始计数。

第0条线段: 起始点、终止点的x坐标为0。 第10条线段: 起始点、终止点的x坐标为10 * NODE_WIDTH。 第20条线段: 起始点、终止点的x坐标为20 * NODE_WIDTH。

观察各线段起始点终止点坐标,可以总结出规律:

第n条线段:起始点(n * NODE_WIDTH, 0)、终止点(n * NODE_WIDTH, 600)。且x坐标的范围为[0, 800]。

//  竖线 for (int x = 0; x  D E C B A     for (int i = length - 1; i > 0; i--)     {         snake[i] = snake[i - 1];     }     //  根据方向,确定下一个头节点     node newHead;     newHead = snake[0];     if (direction == eUp)     {         newHead.y--;     }     else if (direction == eDown)     {         newHead.y++;     }     else if (direction == eLeft)     {         newHead.x--;     }     else //  right     {         newHead.x++;     }     //  更新头节点     //  D E C B A ---> D E C B N     snake[0] = newHead; } int main() {     initgraph(800, 600);     //  设置背景色     setbkcolor(RGB(164, 225, 202));     //  使用背景色清空窗体     cleardevice();     //  蛇节点坐标     node snake[100] = { {5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7} };     //  蛇节点长度     int length = 5;     while (1)     {         //  清空整个窗体         cleardevice();         //  绘制网格         paintGrid();         //  绘制蛇节点         paintSnake(snake, length);         //  休眠500ms         Sleep(500);         //  向右移动蛇节点         snakeMove(snake, length, eRight);     }     getchar();     closegraph();     return 0; } 4. 控制移动方向

现在,程序开始后蛇会向右移动,接下来,加入用键盘来控制蛇的移动方向的功能。

键盘交互功能如下:

按下w键,蛇向上移动

按下s键,蛇向下移动

按下a键,蛇向左移动

按下d键,蛇向右移动

在主函数中声明一个枚举变量d,初始为向右移动。

//  移动方向 enum direction d = eRight;

将d传递给snakeMove函数的第三个参数。snakeMove函数的第三个参数可以根据方向设置新蛇头的位置。若蛇需要更改移动方向,只要更改枚举变量d即可。

//  枚举变量d,控制蛇的移动方向 snakeMove(snake, length, d);

与之前的键盘交互一样,使用_getch与_kbhit函数配合,可以获取键盘输入且不会导致程序阻塞。使用这两个函数别忘了包含头文件#include 。获取到键盘输入后,通过传入枚举变量指针pD,修改变量枚举值。

//  键盘输入改变direction void changeDirection(enum direction* pD) {     //  检查输入缓存区中是否有数据     if (_kbhit() != 0)     {         //  _getch函数获取输入缓存区中的数据         char c = _getch();         //  判断输入并转向         switch (c)         {         case 'w':             //  向上移动             *pD = eUp;             break;         case 's':             //  向下移动             *pD = eDown;             break;         case 'a':             //  向左移动             *pD = eLeft;             break;         case 'd':             //  向右移动             *pD = eRight;             break;         }     } }

这里还需要注意一个问题,蛇不能后退,如果新的方向与原方向相反,那么按键无效。

//  键盘输入改变direction void changeDirection(enum direction* pD) {     //  检查输入缓存区中是否有数据     if (_kbhit() != 0)     {         //  _getch函数获取输入缓存区中的数据         char c = _getch();         //  判断输入并转向         switch (c)         {         case 'w':             //  向上移动             if (*pD != eDown)                 *pD = eUp;             break;         case 's':             //  向下移动             if (*pD != eUp)                 *pD = eDown;             break;         case 'a':             //  向左移动             if (*pD != eRight)                 *pD = eLeft;             break;         case 'd':             //  向右移动             if (*pD != eLeft)                 *pD = eRight;             break;         }     } }

主函数中,在snakeMove函数前调用changeDirection函数检查是否有键盘输入,若有输入且非回头方向的输入,则改变方向枚举变量d。新的方向枚举变量d传入snakeMove函数后,即可使用新方向设置新蛇头的位置,实现蛇改变移动方向功能。

//  蛇节点坐标 node snake[100] = { {5, 7}, {4, 7}, {3, 7}, {2, 7}, {1, 7} }; //  蛇节点长度 int length = 5; enum direction d = eRight; while (1) {     cleardevice();     paintGrid();     paintSnake(snake, length);     Sleep(500);     //  获取键盘输入并将方向存储到变量d     changeDirection(&d);     //  根据变量d的方向移动蛇节点     snakeMove(snake, length, d); }

图片

现阶段代码:

#include  #include  #include  #define NODE_WIDTH 40 //  节点 typedef struct {     int x;     int y; }node; //  绘制网格 //  横线(0, y), (800, y)   0  D E C B A     for (int i = length - 1; i > 0; i--)     {         snake[i] = snake[i - 1];     }     //  根据方向,确定下一个头节点     node newHead;     newHead = snake[0];     if (direction == eUp)     {         newHead.y--;     }     else if (direction == eDown)     {         newHead.y++;     }     else if (direction == eLeft)     {         newHead.x--;     }     else //  right     {         newHead.x++;     }     //  更新头节点     //  D E C B A ---> D E C B N     snake[0] = newHead; } //  键盘输入改变direction void changeDirection(enum direction* pD) {     //  检查输入缓存区中是否有数据     if (_kbhit() != 0)     {         //  _getch函数获取输入缓存区中的数据         char c = _getch();         //  判断输入并转向         switch (c)         {         case 'w':             //  向上移动             if (*pD != eDown)                 *pD = eUp;             break;         case 's':             //  向下移动             if (*pD != eUp)                 *pD = eDown;             break;         case 'a':             //  向左移动             if (*pD != eRight)                 *pD = eLeft;             break;         case 'd':             //  向右移动             if (*pD != eLeft)                 *pD = eRight;             break;         }     } } //  绘制食物 /* (x * NODE_WIDTH, y * NODE_WIDTH) @----------- |          | |          | |          | |          | |          | -----------@ ((x + 1) * NODE_WIDTH, (y + 1) * NODE_WIDTH) */ void paintFood(node food) {     int left, top, right, bottom;     left = food.x * NODE_WIDTH;     top = food.y * NODE_WIDTH;     right = (food.x + 1) * NODE_WIDTH;     bottom = (food.y + 1) * NODE_WIDTH;     setfillcolor(YELLOW);     solidrectangle(left, top, right, bottom);     setfillcolor(WHITE); } //  随机创建食物 node createFood(node* snake, int length) {     node food;     while (1)     {         food.x = rand() % (800 / NODE_WIDTH);         food.y = rand() % (600 / NODE_WIDTH);         int i;         for (i = 0; i          //  限制snake节点最大长度         if (length  E E D C B     for (int i = length - 1; i > 0; i--)     {         snake[i] = snake[i - 1];     }     //  下一个头节点     node newHead;     newHead = snake[0];     if (direction == eUp)     {         newHead.y--;     }     else if (direction == eDown)     {         newHead.y++;     }     else if (direction == eLeft)     {         newHead.x--;     }     else //  right     {         newHead.x++;     }     //  更新头节点     //  E D C B A ---> F E D C B     snake[0] = newHead;     //for (int i = 0; i 


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有