c语言小游戏——贪吃蛇

Joymine 2018-11-01

贪吃蛇设计流程:

(1)数据设计

辅助宏定义

游戏地图的宽和高,以及蛇的最大长度

食物结构体

食物在地图上x和y上的显示

蛇结构体

蛇的长度,蛇得每一节的坐标存储,蛇的移动速度

辅助全局变量

蛇是否变化,蛇的初始移动方向

(2)模块化设计

地图设计

void drawMap();//绘制游戏地图

按键处理

void keyDown();//按键处理

食物设计

voidcreateFood();//产生食物

辅助函数

void gotoxy(int x,int y);//cmd移动辅助函数

终止游戏

int snakeStaus();//蛇状态

(3)具体实现

1.辅助函数:void gotoxy(int x,int y);//cmd移动辅助函数

//////////////////////////////////////

//cmd移动辅助函数

void gotoxy(int x, int y)

{

//获取cmd窗口句柄

HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

//光标坐标

COORD coord;

//设置窗口坐标

coord.X = x;

coord.Y = y;

SetConsoleCursorPosition(handle, coord);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

2.地图设计: void drawMap();//绘制游戏地图

////////////////////////////////////////

// 绘制游戏地图

void drawMap()

{

srand((unsigned int)time(NULL));

//食物

//1.食物属性

food.x = rand() % (MAPWIDTH - 4/*食物图标占用2个字符*/) + 2;

food.y = rand() % (MAPHEIGHT - 2) + 1;

//2.画食物

gotoxy(food.x, food.y);

printf("⊙");

//蛇

//1.蛇属性

mysnake.x[0] = MAPWIDTH / 2;//定位在中间

mysnake.y[0] = MAPHEIGHT / 2;

//2.画蛇

gotoxy(mysnake.x[0], mysnake.y[0]);

printf("■");

mysnake.len = 3;

mysnake.speed = 100;

for (int k = 1; k<mysnake.len; k++)

{

mysnake.x[k] = mysnake.x[k - 1] + 2;

mysnake.y[k] = mysnake.y[k - 1];

gotoxy(mysnake.x[k], mysnake.y[k]);

printf("■");

}

//边框

//1.左右

for (int i = 0; i <= MAPHEIGHT; i++)

{

gotoxy(0, i);

printf("■");

gotoxy(MAPWIDTH, i);

printf("■");

}

//2.上下

for (int i = 0; i <= MAPWIDTH; i += 2)

{

gotoxy(i, 0);

printf("■");

gotoxy(i, MAPHEIGHT);

printf("■");

}

}

////////////////////////////////////////

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

3.按键处理:void keyDown();//按键处理

////////////////////////////////////////

// 按键处理

void keyDown()

{

//无按键处理蛇要移动

if (_kbhit())

{

fflush(stdin);

key = _getch();

}

//没变化

if (!changeFlag)

{

gotoxy(mysnake.x[mysnake.len - 1], mysnake.y[mysnake.len - 1]);

printf(" ");

}

//后面的节数处理:往前移动

for (int i = mysnake.len - 1; i > 0; i--)

{

mysnake.x[i] = mysnake.x[i - 1];

mysnake.y[i] = mysnake.y[i - 1];

}

//有按键处理

switch (key)

{

case 'w':

case 'W':

case 72:

mysnake.y[0]--;

break;

case 's':

case 'S':

case 80:

mysnake.y[0]++;

break;

case 'a':

case 'A':

case 75:

mysnake.x[0] -= 2;

break;

case 'd':

case 'D':

case 77:

mysnake.x[0] += 2;

break;

}

gotoxy(mysnake.x[0], mysnake.y[0]);

printf("■");

changeFlag = 0;

gotoxy(MAPHEIGHT + 2, 0);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

4.食物设计:voidcreateFood();//产生食物

////////////////////////////////////////

// 产生食物

void createFood()//产生食物

{

//产生条件:食物被吃

if (mysnake.x[0] == food.x&&mysnake.y[0] == food.y)

{

//完整版本:食物不能是在蛇身

srand((unsigned int)time(NULL));

//x必须为偶数

while (1)

{

int flag = 1;

food.x = rand() % (MAPWIDTH - 4) + 2;

food.y = rand() % (MAPHEIGHT - 2) + 1;

for (int k = 0; k < mysnake.len; k++)

{

if (mysnake.x[k] == food.x&&mysnake.y[k] == food.y)

{

flag = 0;

break;

}

}

//食物坐标要为偶数并且不能再蛇身上

if (flag&&food.x % 2 == 0)

{

break;

}

}

gotoxy(food.x, food.y);

printf("⊙");

mysnake.len++;

changeFlag = 1;

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

5.终止游戏: int snakeStaus();//蛇状态

int snakeStaus()//蛇状态

{

if (mysnake.x[0] == 0 || mysnake.x[0] == MAPHEIGHT - 2 || mysnake.y[0] == MAPWIDTH - 2 || mysnake.y[0] == 0)

return 0;

for (int k = 1; k<mysnake.len; k++)

if (mysnake.x[k] == mysnake.x[0] && mysnake.y[k] == mysnake.y[0])

return 0;

return 1;

}

1

2

3

4

5

6

7

8

9

10

6.主函数

int main()

{

drawMap();

while (1)

{

createFood();

Sleep(mysnake.speed);

keyDown();

if (!snakeStaus())

{

break;

}

}

printf("GameOver");

system("pause");

return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

完整代码

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <conio.h>

#include <windows.h>

//⊙ ■

///////////////////////////////////////

//地图的长和宽

#define MAPHEIGHT 25

#define MAPWIDTH 60

#define SNAKESIZE 50

///////////////////////////////////////

//数据设计

int changeFlag = 0;//蛇变形标记

int key = 'w';

struct food

{

//食物的位置

int x;

int y;

}food;

struct snake

{

int x[SNAKESIZE]; //蛇坐标

int y[SNAKESIZE];

int len;//当前长度

int speed;//移动速度

}mysnake;//mysnake[0] 蛇头

/////////////////////////////////////////

//模块化设计

void drawMap();//绘制游戏地图

void createFood();//产生食物

void keyDown();//按键处理

int snakeStaus();//蛇状态

void gotoxy(int x, int y);//cmd移动辅助函数

int main()

{

drawMap();

while (1)

{

createFood();

Sleep(mysnake.speed);

keyDown();

if (!snakeStaus())

{

break;

}

}

printf("GameOver");

system("pause");

return 0;

}

//////////////////////////////////////

//cmd移动辅助函数

void gotoxy(int x, int y)

{

//获取cmd窗口句柄

HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

//光标坐标

COORD coord;

//设置窗口坐标

coord.X = x;

coord.Y = y;

SetConsoleCursorPosition(handle, coord);

}

////////////////////////////////////////

// 绘制游戏地图

void drawMap()

{

srand((unsigned int)time(NULL));

//食物

//1.食物属性

food.x = rand() % (MAPWIDTH - 4/*食物图标占用2个字符*/) + 2;

food.y = rand() % (MAPHEIGHT - 2) + 1;

//2.画食物

gotoxy(food.x, food.y);

printf("⊙");

//蛇

//1.蛇属性

mysnake.x[0] = MAPWIDTH / 2;//定位在中间

mysnake.y[0] = MAPHEIGHT / 2;

//2.画蛇

gotoxy(mysnake.x[0], mysnake.y[0]);

printf("■");

mysnake.len = 3;

mysnake.speed = 100;

for (int k = 1; k<mysnake.len; k++)

{

mysnake.x[k] = mysnake.x[k - 1] + 2;

mysnake.y[k] = mysnake.y[k - 1];

gotoxy(mysnake.x[k], mysnake.y[k]);

printf("■");

}

//边框

//1.左右

for (int i = 0; i <= MAPHEIGHT; i++)

{

gotoxy(0, i);

printf("■");

gotoxy(MAPWIDTH, i);

printf("■");

}

//2.上下

for (int i = 0; i <= MAPWIDTH; i += 2)

{

gotoxy(i, 0);

printf("■");

gotoxy(i, MAPHEIGHT);

printf("■");

}

}

////////////////////////////////////////

// 产生食物

void createFood()//产生食物

{

//产生条件:食物被吃

if (mysnake.x[0] == food.x&&mysnake.y[0] == food.y)

{

//完整版本:食物不能是在蛇身

srand((unsigned int)time(NULL));

//x必须为偶数

while (1)

{

int flag = 1;

food.x = rand() % (MAPWIDTH - 4) + 2;

food.y = rand() % (MAPHEIGHT - 2) + 1;

for (int k = 0; k < mysnake.len; k++)

{

if (mysnake.x[k] == food.x&&mysnake.y[k] == food.y)

{

flag = 0;

break;

}

}

//食物坐标要为偶数并且不能再蛇身上

if (flag&&food.x % 2 == 0)

{

break;

}

}

gotoxy(food.x, food.y);

printf("⊙");

mysnake.len++;

changeFlag = 1;

}

}

////////////////////////////////////////

// 按键处理

void keyDown()

{

//无按键处理蛇要移动

if (_kbhit())

{

fflush(stdin);

key = _getch();

}

//没变化

if (!changeFlag)

{

gotoxy(mysnake.x[mysnake.len - 1], mysnake.y[mysnake.len - 1]);

printf(" ");

}

//后面的节数处理:往前移动

for (int i = mysnake.len - 1; i > 0; i--)

{

mysnake.x[i] = mysnake.x[i - 1];

mysnake.y[i] = mysnake.y[i - 1];

}

//有按键处理

switch (key)

{

case 'w':

case 'W':

case 72:

mysnake.y[0]--;

break;

case 's':

case 'S':

case 80:

mysnake.y[0]++;

break;

case 'a':

case 'A':

case 75:

mysnake.x[0] -= 2;

break;

case 'd':

case 'D':

case 77:

mysnake.x[0] += 2;

break;

}

gotoxy(mysnake.x[0], mysnake.y[0]);

printf("■");

changeFlag = 0;

gotoxy(MAPHEIGHT + 2, 0);

}

int snakeStaus()//蛇状态

{

if (mysnake.x[0] == 0 || mysnake.x[0] == MAPHEIGHT - 2 || mysnake.y[0] == MAPWIDTH - 2 || mysnake.y[0] == 0)

return 0;

for (int k = 1; k<mysnake.len; k++)

if (mysnake.x[k] == mysnake.x[0] && mysnake.y[k] == mysnake.y[0])

return 0;

return 1;

}

c语言小游戏——贪吃蛇

相关推荐