📄 game5.c
字号:
#include <stdio.h>
#include "graphics.h"
#include "math.h"
#include "time.h"
#include "ctype.h"
#include "bios.h"
#include "conio.h"
#include "dos.h"
#include "stdlib.h"
#include "alloc.h"
#include "string.h"
#define closegr closegraph
/* direction key */
#define UP 0x4800
#define DOWN 0x5000
#define RIGHT 0x4b00
#define LEFT 0x4d00
/* control key */
#define ESC 0x11b
#define ENTER 0x1c0d
#define SPACE 0x3920
#define F2 0x3c00
/* ridge of game */
#define UPEST 1
#define DOWNEST 29
#define LEFTEST 1
#define RIGHTEST 42
#define head 0
void initgr(void); /* 图形初始化 */
void game(long speed); /* 游戏核心 */
long chooselevel(void); /* 开始控制菜单 */
void newfruit(int); /* 生成新目标 */
void mark(int); /* 分数管理 */
void end(int); /* 游戏结束 */
void high(void); /* 最高成绩 */
void grgets(int x,int y,int size,int color,char s[]); /* 图形下的gets */
void welcome(void); /* 欢迎画面 */
void clean(void); /* 清除记录 */
typedef struct Point{ /* the points in snake and target */
int x;
int y;
} point;
point snake[100]={{1,1}},fruit={6,6};
long speed;
int record[3];
char *name[3];
FILE *fp;
int main(void)
{
int i;
char *s;
initgr(); /* 图形初始化 */
welcome(); /* 欢迎画面 */
do{ /* 提取记录 */
fp=fopen("mark.dat","r");
fscanf(fp,"%d%d%d",&record[0],&record[1],&record[2]);
fgets(s,10,fp);
for(i=0;i<=2;i++){
name[i]=(char *)malloc(100);
fscanf(fp,"%s",name[i]);
}
fclose(fp);
speed=chooselevel(); /* 选择速度 */
setcolor(YELLOW);
rectangle(0,0,631,436);
game(speed);
}while(1);
}
void initgr(void) /* 图形初始化 */
{
int gd=DETECT, gm=0;
registerbgidriver(EGAVGA_driver);
initgraph(&gd, &gm, "c:\turboc2");
}
void game(long speed)
{
int top=0; /* length of snake */
int key;
int direction=3;
int a=1,b=1,c,d;
int i,j,k;
mark(top);
setfillstyle(SOLID_FILL,2);
bar((fruit.x-1)*15+1,(fruit.y-1)*15+1,
fruit.x*15,fruit.y*15);
while(1){
delay(speed); /* delay */
if(kbhit()!=0){ /* is there a pressure on keyboard */
key=bioskey(0);
switch(key){
case UP:direction=(direction==2?2:1); /* decide the dirction */
break;
case DOWN:direction=(direction==1?1:2);
break;
case LEFT:direction=(direction==4?4:3);
break;
case RIGHT:direction=(direction==3?3:4);
break;
case SPACE:bioskey(0); /* pause */
}
}
switch(direction){
case 1:b--; /* go up */
break;
case 2:b++; /* go down */
break;
case 3:a++; /* go left */
break;
case 4:a--; /* go right */
}
if(b<UPEST||b>DOWNEST|| /* if the snake out of the ridge */
a<LEFTEST||a>RIGHTEST)
break; /* end game */
if(a==fruit.x&&b==fruit.y){ /* if the snake ate the fruit */
top++; /* add 1 to length of snake */
newfruit(top);/* new fruit */
mark(top);
}
else{
c=snake[top].x;
d=snake[top].y;
}
for(i=top-1;i>=head;i--){ /* move the snake */
if(snake[i].x==a&&snake[i].y==b) /* if the head hit itself */
goto fail; /* end game */
snake[i+1].x=snake[i].x;
snake[i+1].y=snake[i].y;
}
snake[head].x=a;
snake[head].y=b;
setfillstyle(SOLID_FILL,2); /* draw fruit */
bar((fruit.x-1)*15+1,(fruit.y-1)*15+1,
fruit.x*15,fruit.y*15); /* draw the snake */
if(a==fruit.x&&b==fruit.y){ /* have eaten,draw head */
setfillstyle(SOLID_FILL,YELLOW);
bar((snake[head].x-1)*15+1,(snake[head].y-1)*15+1,
snake[head].x*15,snake[head].y*15);
}
else{ /* haven't eaten,draw head;clean tail */
setfillstyle(SOLID_FILL,0);
bar((c-1)*15+1,(d-1)*15+1,c*15,d*15);
setfillstyle(SOLID_FILL,YELLOW);
bar((snake[head].x-1)*15+1,(snake[head].y-1)*15+1,
snake[head].x*15,snake[head].y*15);
}
}
fail:end(top);
}
void newfruit(int top)
{
int flag,i;
int seed;
srand(time(0));
do{
flag=0; /* 获取一个位置 */
fruit.x=(int)(rand())%41+1;
fruit.y=(int)(rand())%28+1;
for(i=top;i>=0;i--) /* 不与蛇身重复 */
if(snake[i].x==fruit.x&&snake[i].y==fruit.y)
flag++;
}while(flag);
}
long chooselevel(void) /* 开始控制菜单 */
{
int j=0,k=3;
int key,flag=0;
long speed;
setcolor(LIGHTBLUE); /* 绘制菜单 */
settextstyle(0,0,3);
outtextxy(250,150,"SNAKE");
settextstyle(0,0,2);
outtextxy(200,190,"Choose a level:");
outtextxy(200,280,"<-,-> to choose");
outtextxy(200,300,"ENTER to play");
outtextxy(200,320,"F2 to check record");
outtextxy(200,340,"DELETE to reset record");
outtextxy(200,360,"ESC to exit");
setfillstyle(SOLID_FILL,CYAN);
bar(197,227,444,253);
setfillstyle(SOLID_FILL,BLACK);
bar(200,230,441,250);
do{ /* 选择界面 */
setfillstyle(SOLID_FILL,YELLOW);
bar(201+110*j,231,220+110*j,249);
setfillstyle(SOLID_FILL,BLACK);
bar(201+110*k,231,220+110*k,249);
key=bioskey(0);
switch (key){
case LEFT:if(j!=2){
k=j;
j++;
}
break;
case RIGHT:if(j!=0){
k=j;
j--;
}
break;
case ENTER:flag=1; /* 准备跳出 */
break;
case F2:high(); /* 显示最高记录 */
setcolor(LIGHTBLUE); /* 重绘界面 */
settextstyle(0,0,3);
outtextxy(250,150,"SNAKE");
settextstyle(0,0,2);
outtextxy(200,190,"Choose a level:");
outtextxy(200,280,"<-,-> to choose");
outtextxy(200,300,"ENTER to play");
outtextxy(200,320,"F2 to check record");
outtextxy(200,340,"DELETE to reset record");
outtextxy(200,360,"ESC to exit");
setfillstyle(SOLID_FILL,CYAN);
bar(197,227,444,253);
setfillstyle(SOLID_FILL,BLACK);
bar(200,230,441,250);
break;
case 0x5300: /* 清除记录 */
case 0x532e:clean();
break;
case ESC:closegr(); /* 退出 */
exit(0);
}
}while(flag!=1);
switch (j){ /* 决定速度 */
case 2:speed=15000;break;
case 1:speed=25000;break;
case 0:speed=40000;break;
}
cleardevice(); /* 清屏 */
return speed;
}
void mark(int top) /* 分数管理 */
{
char s[5],c[5];
setcolor(RED);
itoa(top,s,10);
itoa(record[(speed-15000)/10000],c,10);
setfillstyle(SOLID_FILL,GREEN); /* 绘制分数栏 */
bar(1,438,631,480);
settextstyle(0,0,3);
outtextxy(30,450,"RECORD:");
outtextxy(200,450,c);
outtextxy(410,450,"SCORE:");
outtextxy(560,450,s);
}
void end(int top) /*游戏结束*/
{
char *t;
settextstyle(0,0,1);
setcolor(BLACK);
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar(200,180,440,300);
setfillstyle(SOLID_FILL,BLACK);
rectangle(205,185,435,295);
if(top>record[(speed-15000)/10000]){ /* 如果蛇长比记录大 */
outtextxy(250,220,"congratulations!"); /* 庆祝一下 */
outtextxy(230,240,"You broke the record!");
sprintf(t,"Your score is %d",top);
outtextxy(255,260,t);
sleep(2);
while(kbhit()!=0)
bioskey(0); /* 等一会儿 */
record[(speed-15000)/10000]=top; /* 蛇长变成记录 */
setfillstyle(SOLID_FILL,LIGHTGRAY); /* 绘制姓名输入窗口 */
bar(160,228,480,268);
setfillstyle(SOLID_FILL,BLACK);
rectangle(165,233,475,263);
outtextxy(175,246,"Your name:");
grgets(260,246,1,BLACK,name[(speed-15000)/10000]); /* 输入姓名 */
fp=fopen("mark.dat","w"); /* 存入新数据 */
fprintf(fp,"%d\n%d\n%d\n",record[0],record[1],record[2]);
fprintf(fp,"%s\n%s\n%s\n",name[0],name[1],name[2]);
fclose(fp);
}
else{
outtextxy(275,230,"You failed"); /* 分数比记录小 */
sprintf(t,"Your score is %d",top); /* 失败了 */
outtextxy(255,260,t);
sleep(1);
bioskey(0);
}
cleardevice();
}
void high(void) /* 最高成绩 */
{
int i;
char *s;
cleardevice();
settextstyle(0,0,2); /* 显示记录 */
for(i=0;i<=2;i++){
sprintf(s,"LEVEL %d: %10s %5d",i+1,name[2-i],record[2-i]);
outtextxy(130,200+i*50,s);
}
bioskey(0);
cleardevice();
}
void grgets(int x,int y,int size,int color,char s[]) /* 图形下的gets */
{
int i=-1,j;
char c;
settextstyle(0,0,size);
setcolor(color);
setfillstyle(SOLID_FILL,LIGHTGRAY);
strcpy(s," "); /* 清空姓名 */
do{
i++;
c=getch(); /* 获取字符 */
if(c==8&&i!=0){ /* 是退格键,退格 */
s[i-1]=0;
i-=2;
}
else
s[i]=c; /* 加入字符 */
bar(x,y,x+8*(i+3)*size,y+10);
outtextxy(x,y,s); /* 显示姓名 */
}while(s[i]!=13); /* 直到字符为回车 */
s[i]='\0';
if(strlen(s)==0) /* 如果没有输入 */
strcpy(s,"NONAME"); /* 新姓名为NONAME */
}
void welcome(void)
{
int colors[5]={9,10,11,12,13}; /* 五种颜色 */
int i;
settextstyle(0,0,2);
setcolor(YELLOW);
outtextxy(170,390,"Designer:SUN"); /* 设计者 */
outtextxy(170,420,"Program:SUN"); /* 程序编制者 */
rectangle(170,150,460,350);
settextstyle(0,0,6);
while(kbhit()==0){ /* 如果没有按键 */
setcolor(colors[1]);
outtextxy(196,160,"S"); /* 显示SNAKE EAT BEAN(蛇吃豆)*/
setcolor(colors[2]);
outtextxy(246,160,"N");
setcolor(colors[3]);
outtextxy(296,160,"A");
setcolor(colors[4]);
outtextxy(346,160,"K");
setcolor(colors[5]);
outtextxy(396,160,"E");
setcolor(colors[3]);
outtextxy(246,230,"EAT");
setcolor(colors[2]);
outtextxy(220,300,"BEAN");
for(i=0;i<=5;i++){ /* 换种颜色 */
colors[i]++;
if(colors[i]==16)
colors[i]=9;
}
delay(55000); /* 等一会儿 */
}
bioskey(0);
cleardevice();
}
void clean(void) /* 清除记录 */
{
int i;
fp=fopen("mark.dat","w"); /* 清文件 */
fprintf(fp,"%d\n%d\n%d\n%s\n%s\n%s\n",0,0,0,"NONAME","NONAME","NONAME");
fclose(fp);
for(i=0;i<=2;i++){ /* 清记录 */
record[i]=0;
strcpy(name[i],"NONAME");
}
outtextxy(10,10,"OK!");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -