贪吃蛇
课程设计:
我在原版的贪吃蛇加入了一点点创新。加入了用户系统、背景音乐、和界面(开始和结束界面),有分数,提示性文字等。
玩家系统:
#include <stdio.h>
#include <string.h>
#include <windows.h>
//定义变量
char reg_name[30]="",reg_pwd[10]="";
char on_name[30],on_pwd[10];
//用户注册系统
void regist()
{
//清屏
system("pause");
system("cls");
printf("\n\n\t\t\t欢迎使用注册系统\n\n");
while(1)
{
//输入用户名
printf("\t\t请输入用户名[不能大于10个字符]:");
scanf("%s",reg_name);
//判断用户名
if(strlen(reg_name)<=10)
{
while(1)
{
//输入密码
printf("\n\t\t请输入密码[密码长度为八位]:");
scanf("%s",reg_pwd);
//判断密码
if(strlen(reg_pwd)==8)
{
printf("\n\n\t\t注册成功,您的用户名是%s,密码是%s\n\n",reg_name,reg_pwd);
break;
}
else
{
printf("\n\t\t密码的长度为%d,请重新输入\n",strlen(reg_pwd));
}
}
break;
}
else
{
printf("\n\t\t用户名的长度为%d,请重新输入\n\n",strlen(reg_name));
}
}
}
//判断是否注册
int judge()
{
if(strcmp(reg_name,"")==0&&strcmp(reg_pwd,"")==0)
{
printf("\n\n\t\t您尚未注册,请先注册!\n\n");
return 0;
}
else
{
return 1;
}
}
//用户登录
void dl()
{
int i;
system("pause");
system("cls");
printf("\n\n\t\t\t欢迎登录系统\n\n");
//三次登录验证
for(i=1;i<=3;i++)
{
printf("\t\t请输入用户名:");
scanf("%s",on_name);
printf("\n\t\t请输入密 码:");
scanf("%s",on_pwd);
if(strcmp(reg_name,on_name)==0&&strcmp(reg_pwd,on_pwd)==0)
{
printf("\n\n\t\t登录成功,祝您游戏愉快\n\n");
break;
}
else
{
printf("\n\n\t\t登录失败,请重新登录,您还有%d次机会\n\n",3-i);
}
}
}
void main()//注册登陆系统
{
//定义变量
int id;
while(1)
{
system("pause");
system("cls");
//输出界面
printf("\n\n\t\t\t用户管理系统\n\n");
printf("\t\t\t1:注册\n");
printf("\t\t\t2:登录\n");
printf("\t\t\t0:退出\n\n");
//输入功能编号
printf("\t\t请选择功能编号:");
scanf("%d",&id);
//判断
switch(id)
{
case 1:regist();break;
case 2:
if(judge()==1)
{
dl();
}
break;
case 0:exit(1);break;
default:
printf("\n\t\t您输入的功能编号有误,请重新输入!\n");
}
}
}
音乐需要自己设置,需要下载音乐,把下好的音乐放在bin文件夹下的Debug文件夹下。新建一个文件夹,然后才能使用。而且音乐的格式要是wav格式,不能为mp3格式,下载后看看文件格式。如果不是wav就转换一下。
完整游戏代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<windows.h> //光标设计API
#include<time.h> //食物随机
#include<conio.h> //按键监控
//音乐
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
//用户系统
//定义变量
char reg_name[30]="",reg_pwd[10]="";
char on_name[30],on_pwd[10];
//宏定义属性
//窗口属性
#define SNAKESIZE 100 //蛇的最大节数
#define MAPHEIGHT 40 //地图高度
#define MAPWIDTH 70 //地图宽度
void gotoxy(int x,int y);//1.辅助函数:光标移动
void drawMap();//2.画地图
void keyDown();//3.按键操作
void creatFood();//4.食物的产生
int snakeStatus();//5.蛇的状态:判断是否结束游戏
void welcometogame();//6.开始界面
void gamecircle();//7.控制游戏
void endgame();//8.游戏结束界面
//9.背景音乐
void bgm1();//音乐1
void bgm2();//音乐2
void bgm3();//音乐3
void regist();//10.用户注册系统
void dl();//11.用户登录
void HideCursor();//12.隐藏光标
//1.辅助函数:光标移动
void gotoxy(int x,int y)
{
//光标结构体
COORD coord;
//设置坐标
coord.X=x;
coord.Y=y;
//同步到控制台/设置控制台光标位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
//食物结构体
struct
{
int x;
int y;
} food;
//蛇结构体
struct
{
int speed; //蛇的速度
int len; //蛇的长度
//记录每一节蛇的坐标
//一条蛇有多少节
int x[SNAKESIZE];
int y[SNAKESIZE];
} snake;
//全局变量
int i;
int key=72; //初始化移动方向,表示蛇移动的方向,72为按下“↑”所代表的数字
int changeFlag=0; //蛇变化标记,判断蛇是否吃掉了食物
int score=0; //记录玩家的得分
//2.画地图
void drawMap()
{
//左右边框
for(i=1; i<=MAPHEIGHT; i++)
{
gotoxy(0,i);
printf("■");
gotoxy(MAPWIDTH,i);
printf("■");
}
//上下边框
for(i=0; i<=MAPWIDTH; i+=2)
{
gotoxy(i,0);
printf("■");
gotoxy(i,MAPHEIGHT);
printf("■");
}
//食物刷新,画食物
while(1)
{
srand((unsigned int)time(NULL));
food.x=rand()%(MAPWIDTH-4)+2;
food.y=rand()%(MAPHEIGHT-2)+1;
if(food.x%2==0) break;
}
//产生新的食物
gotoxy(food.x,food.y); //食物的光标
printf("●");
snake.len=3; //蛇初始长度
snake.speed=200; //蛇初始速度
snake.x[0]=MAPWIDTH/2+1;
snake.y[0]=MAPHEIGHT/2;
gotoxy(snake.x[0],snake.y[0]);
printf("■");
for(i=1; i<snake.len; i++)
{
snake.x[i]=snake.x[i-1]+2;
snake.y[i]=snake.y[i-1];
gotoxy(snake.x[i],snake.y[i]);
printf("■");
}
gotoxy(MAPWIDTH-2,0);
return ;
}
//3.按键操作
void keyDown()
{
//无按键操作,缓冲
int pre_key=key;
if(_kbhit())
{
//有按键接收
fflush(stdin);
key=_getch();
key=_getch();
}
//擦除
if(changeFlag==0)
{
gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
printf(" ");
}
//后面蛇身的结束
for(i=snake.len-1; i>0; i--)
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
/*
*控制台按键所代表的数字
*“↑”:72
*“↓”:80
*“←”:75
*“→”:77
*/
//移动方向处理
if(pre_key==72&&key==80)
key=72;
if(pre_key==80 && key==72)
key=80;
if(pre_key==75 && key==77)
key=75;
if(pre_key==77 && key==75)
key=77;
switch(key)
{
case 75:
snake.x[0]-=2 ;
break;
case 77:
snake.x[0]+=2;
break;
case 72:
snake.y[0]--;
break;
case 80:
snake.y[0]++;
break;
}
gotoxy(snake.x[0],snake.y[0]);
printf("■");
gotoxy(MAPWIDTH-2,0); //移动不能一直看着光标
changeFlag=0;
return ;
}
//4.食物的产生
void creatFood()
{
//蛇把食物吃了
if(snake.x[0]==food.x && snake.y[0]==food.y)
{
//产生的食物不能在蛇身上
while(1)
{
int flag=1;
srand((unsigned int)time(NULL));
food.x=rand()%(MAPWIDTH-4)+2;
food.y=rand()%(MAPHEIGHT-2)+1;
//产生的食物不能在蛇身上
for(i=0; i<snake.len; i++)
{
if(snake.x[i]==food.x && snake.y[i]==food.y)
{
flag=0;
break;
}
}
if(flag && food.x%2==0)
break;
}
//产生新的食物
gotoxy(food.x,food.y);
printf("●");
snake.len++;
score += 10; //每个食物得10分
changeFlag=1; //很重要,因为吃到了食物,就不用再擦除蛇尾的那一节,以此来造成蛇身体增长的效果
}
return ;
}
//5.蛇的状态:判断是否结束游戏
int snakeStatus()
{
if(snake.y[0]==0 || snake.y[0]==MAPHEIGHT)
return 0;
if(snake.x[0]==0 || snake.x[0]==MAPWIDTH)
return 0;
//蛇头不能撞自己
for(i=1; i<snake.len; i++)
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
return 0;
}
return 1;
}
//6.开始界面
void welcometogame()
{
gotoxy(45,12);
printf("欢迎来到贪吃蛇游戏\n");
gotoxy(45,25);
system("pause");
system("cls");
gotoxy(30,12);
printf("请用↑ ↓ ← → 分别控制蛇的移动\n");
gotoxy(30,13);
system("pause");
system("cls");
}
//7.控制游戏
void gamecircle()//控制游戏
{
gotoxy(90,7);
printf("蛇吃得越长,游戏结束后的得分越高。");
gotoxy(90,20);
printf("游戏小提示:");
gotoxy(90,22);
printf("1.蛇不能穿墙,也不能咬到自己哦。");
gotoxy(90,23);
printf("2.如果撞墙或者咬到自己游戏会失败哦。");
gotoxy(90,24);
printf("3.请用↑ ↓ ← → 分别控制蛇的移动。");
/*gotoxy(64,18)
printf("F1 为加速,F2 为减速\n");*/
gotoxy(90,25);
printf("4.鼠标点击暂停游戏。");
}
//8.游戏结束界面
void endgame()//游戏结束
{
system("cls");
system("color 8E");
gotoxy(4,2);
printf("玩家需要多加练习才能得到更高的分数啊,加油哦!!!\n");
gotoxy(18,7);
printf("游戏结束。");
gotoxy(17,8);
printf("Game Over!!!");
gotoxy(14,10);
printf("本次游戏的得分为: %d",score);
exit(0);
}
//9.BGM
//9.1
void bgm1()
{
//播放音乐
PlaySound(TEXT("sounds\\bgm.wav"),NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
}
//9.2
void bgm2()
{
//播放音乐
PlaySound(TEXT("sounds\\b我是小绿.wav"),NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
}
//9.3
void bgm3()
{
//播放音乐
PlaySound(TEXT("sounds\\a赛车.wav"),NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
}
//10.用户注册系统
void regist()
{
//清屏
system("pause");
system("cls");
printf("\n\n\t\t\t欢迎使用注册系统\n\n");
while(1)
{
//输入用户名
printf("\t\t请输入用户名[不能大于10个字符]:");
scanf("%s",reg_name);
//判断用户名
if(strlen(reg_name)<=10)
{
while(1)
{
//输入密码
printf("\n\t\t请输入密码[密码长度为八位]:");
scanf("%s",reg_pwd);
//判断密码
if(strlen(reg_pwd)==8)
{
printf("\n\n\t\t注册成功,您的用户名是%s,密码是%s\n\n",reg_name,reg_pwd);
break;
}
else
{
printf("\n\t\t密码的长度为%d,请重新输入\n",strlen(reg_pwd));
}
}
break;
}
else
{
printf("\n\t\t用户名的长度为%d,请重新输入\n\n",strlen(reg_name));
}
}
}
//判断是否注册
int judge()
{
if(strcmp(reg_name,"")==0&&strcmp(reg_pwd,"")==0)
{
printf("\n\n\t\t您尚未注册,请先注册!\n\n");
return 0;
}
else
{
return 1;
}
}
//11.用户登录
void dl()
{
int i;
system("pause");
system("cls");
printf("\n\n\t\t\t欢迎登录系统\n\n");
//三次登录验证
for(i=1;i<=3;i++)
{
printf("\t\t请输入用户名:");
scanf("%s",on_name);
printf("\n\t\t请输入密 码:");
scanf("%s",on_pwd);
if(strcmp(reg_name,on_name)==0&&strcmp(reg_pwd,on_pwd)==0)
{
printf("\n\n\t\t登录成功,祝您游戏愉快\n\n");
break;
}
else
{
printf("\n\n\t\t登录失败,请重新登录,您还有%d次机会\n\n",3-i);
}
}
}
//12隐藏光标
void HideCursor() //隐藏光标,防止干扰视线
{
CONSOLE_CURSOR_INFO cursor;
cursor.bVisible = FALSE;
cursor.dwSize = sizeof(cursor);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(handle, &cursor);
}
int main()
{
SetConsoleTitle("贪吃蛇小游戏"); //编译控制栏信息
HideCursor();//隐藏光标
//用户系统
system("color 70");
bgm2();
//定义变量
int id;
while(1)
{
HideCursor();//隐藏光标
system("pause");
system("cls");
//输出界面
printf("\n\n\t\t\t用户管理系统\n\n");
printf("\t\t\t1:注册账号\n");
printf("\t\t\t2:登录账号\n");
printf("\t\t\t0:退出游戏\n\n");
//输入功能编号
printf("\t\t请选择功能编号:");
scanf("%d",&id);
//判断
switch(id)
{
case 1:regist();break;
case 2:
if(judge()==1)
{
dl();
goto skip;
}
break;
case 0:exit(1);break;
default:
printf("\n\t\t您输入的功能编号有误,请重新输入!\n");
}
}
//贪吃蛇游戏
skip:;
system("pause");
system("cls");
system("color 70");
bgm3();
welcometogame();
gamecircle();
drawMap();
while(1)
{
HideCursor();//隐藏光标
keyDown();
if(!snakeStatus()) break;
creatFood();
Sleep(snake.speed);
}
endgame();
Sleep(5000);
return 0;
}
我备注写的挺详细的,每个函数的用途,定义的参数的意义什么的。所以就不多加赘述了。
课程设计主要是为了练习自己的能力,自己的思考能力和对C语言的掌握,代码能力。同时平时要养成写注释的好习惯,以防到时候出错的时候不知道自己写的都是什么意思。尽量自己写一下。