好久没这么舒服了,在家什么也不用干,一家人简单的在一起吃饭,感觉都挺好的。
这次的疫情十分严重,不知道什么才能出门。
那就在家写一个C语言的贪吃蛇吧!!
磨磨唧唧写了四五天,,,大概三百行,算是完成了,放上来供大家参考
仅限刚学C语言的新手,老鸟请鄙视之。。。
话不多说,先上代码:
1、main.cpp文件
#include "stdio.h"
#include "stdlib.h"
#include "funtion.h"
#pragma comment(lib,"Winmm.lib")
unsigned int timerIDsnake;
//上下左右按键返回值(返回两个字节)(第一个字节都为224,第二个字节如下):
//上:72
//下:80
//左:75
//右:77
//a:ascll:97
void HideCursor() //隐藏光标
{
CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
int main(int argc, char * argv[])
{
HideCursor();
showscore();
wallinit();
snakeinit();
goto_xy(45, 10);
printf("贪吃蛇游戏");
goto_xy(44, 11);
printf("按箭头键开始");
_getch();
goto_xy(45, 10);
printf(" ");
goto_xy(44, 11);
printf(" ");
timerIDsnake = timeSetEvent(200, 1, (LPTIMECALLBACK)move, 0 , TIME_PERIODIC);
food_generate();
while (1)
{
keyscan();
}
return 0;
}
2、funtion.cpp文件
#include "funtion.h"
extern unsigned int timerIDsnake;
bool over_f = 0;
int key;
int lastkey;
bool key_valid = 1;
unsigned char score_cnt = 0;
unsigned char Food_x, Food_y;
unsigned char snake[100][2]; //蛇的长度,节坐标,和食物计数,都从0开始
unsigned char snakelength;
unsigned char tempheadx = 1, tempheady = 2;
#define Length_BK 100
#define Height_BK 25
void goto_xy(short x, short y)//定位光标位置到指定坐标
{
HANDLE hOut;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos = { x,y };
SetConsoleCursorPosition(hOut, pos);
}
void showscore(void)
{
goto_xy(107, 2);
printf("分数:%4d",score_cnt);
}
void snakeinit(void)
{
unsigned char i;
snakelength = 2;
lastkey = keydown;
for (i = 0; i < 100; i++)
{
snake[i][0] = 0;
snake[i][1] = 0;
}
snake[0][0] = 1;
snake[0][1] = 2;
goto_xy(snake[0][0], snake[0][1]);
putchar(64);//@
snake[1][0] = 1;
snake[1][1] = 1;
goto_xy(snake[1][0], snake[1][1]);
putchar(64);//@
}
void wallinit(void)
{
unsigned char i;
for (i = 0; i <= Length_BK; i++)
{
goto_xy(i, 0);
printf("#");
}
for (i = 0; i <= Height_BK; i++)
{
goto_xy(0, i);
printf("#");
}
for (i = 0; i <= Length_BK; i++)
{
goto_xy(i, Height_BK);
printf("#");
}
for (i = 0; i <= Height_BK; i++)
{
goto_xy(Length_BK, i);
printf("#");
}
}
void deletesnake(void)
{
unsigned char i;
for (i = 0; i < snakelength; i++)
{
goto_xy(snake[i][0], snake[i][1]);
putchar(32);
}
goto_xy(tempheadx, tempheady);
putchar(32);//删除旧蛇头
goto_xy(Food_x, Food_y);
putchar(32);//删除食物
}
void gameinit(void)
{
score_cnt = 0;
deletesnake();
snakeinit();
wallinit();
srand((unsigned)time(NULL));
food_generate();
}
void keyscan(void)
{
key = _getch(); //按键上下左右开始游戏
if (key == 224)
{
key = _getch();
if (over_f)
{
gameinit();
over_f = 0;
timerIDsnake = timeSetEvent(200, 1, (LPTIMECALLBACK)move, 0, TIME_PERIODIC);
goto_xy(45, 26);
printf(" ");
goto_xy(42, 27);
printf(" ");
}
if (key_valid)
{
switch (key)//限制不能反向移动
{
case keyup:
if (snake[0][1] && (lastkey != keydown))
lastkey = key;
break;
case keydown:
if (snake[0][1] <= 255 && (lastkey != keyup))
lastkey = key;
break;
case keylift:
if (snake[0][0] && (lastkey != keyright))
lastkey = key;
break;
case keyright:
if (snake[0][0] <= 255 && (lastkey != keylift))
lastkey = key;
break;
}
key_valid = 0;
}
}
}
bool foodok(void)
{
unsigned char i;
for (i = 0; i < snakelength; i++)
{
if (snake[i][0] == Food_x && snake[i][1] == Food_y)
{
return 0;
}
}
return 1;
}
void food_generate(void)
{
do
{
Food_x = rand() % 99 + 1;
Food_y = rand() % 24 + 1;
} while (!foodok());
goto_xy(Food_x, Food_y);
putchar(97); //a
}
void movedetection(void)
{
unsigned char i;
for (i = 0; i <= Length_BK; i++)
{
if (snake[0][1] == 0 || snake[0][1] == Height_BK)
over_f = 1;
}
for (i = 0; i < Height_BK; i++)
{
if (snake[0][0] == 0 || snake[0][0] == Length_BK)
over_f = 1;
}
for (i = 0; i < (snakelength-2); i++)
{
if (snake[0][0] == snake[i + 1][0] && snake[0][1] == snake[i + 1][1])
over_f = 1;
}
if (over_f)
{
timeKillEvent(timerIDsnake);
goto_xy(45, 26);
printf("游戏结束!");
goto_xy(42, 27);
printf("按箭头键重新开始");
}
}
void move(void)
{
unsigned char i, tempa, tempb;
tempheadx = snake[0][0];
tempheady = snake[0][1];
switch (lastkey) //移动
{
case keyup:
snake[0][1] --;
break;
case keydown:
snake[0][1] ++;
break;
case keylift:
snake[0][0] --;
break;
case keyright:
snake[0][0] ++;
break;
}
movedetection();
if (snake[0][0] == Food_x && snake[0][1] == Food_y)
{
snake_growup();
food_generate();
}
else if(!over_f)
{
goto_xy(snake[snakelength-1][0], snake[snakelength-1][1]);
putchar(32); //space //清除蛇尾
for (i = 0; i < (snakelength - 1); i++)
{
tempa = snake[i+1][0];
tempb = snake[i+1][1];
snake[i+1][0] = tempheadx;
snake[i+1][1] = tempheady;
tempheadx = tempa;
tempheady = tempb;
}
}
if(!over_f)
snake_draw();
key_valid = 1;
}
void snake_growup(void)
{
unsigned char i, tempa, tempb;
snake[snakelength][0] = snake[snakelength - 1][0];
snake[snakelength][1] = snake[snakelength - 1][1];
for (i = 0; i < (snakelength - 1); i++)
{
tempa = snake[i + 1][0];
tempb = snake[i + 1][1];
snake[i + 1][0] = tempheadx;
snake[i + 1][1] = tempheady;
tempheadx = tempa;
tempheady = tempb;
}
snakelength++;
score_cnt++;
}
void snake_draw(void)
{
unsigned char i;
for (i = 0; i < snakelength; i ++)
{
goto_xy(snake[i][0], snake[i][1]);
putchar(64);//@
}
showscore();
}
3、function.h文件
#include "windows.h"
#include "time.h"
#include "stdio.h"
#include "conio.h"
#define keyup 72
#define keydown 80
#define keylift 75
#define keyright 77
extern unsigned char Food_x, Food_y;
extern int key;
extern int lastkey;
void showscore(void);
void wallinit(void);
void snakeinit(void);
void gameinit(void);
void goto_xy(short x, short y); //定位光标位置到指定坐标
void food_generate(void); //食物生成
void snake_draw(void); //蛇身绘制
void snake_growup(void); //长大
void keyscan(void); //按键扫描
void move(void);
感觉逻辑还是很简单的,没有用到高级的语法和算法,用一个二维数组来表示蛇的身体坐标,
然后每移动一次就让坐标都向身体方向移动一次,
吃到食物时也移动一次,然后增加一段身体。
吃到自己和墙检查蛇头的坐标,然后多测试几遍没什么大bug就ok了