📄 sourcecode.c
字号:
outtextxy(border_LT.x + (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,str);
}
else
{
size = imagesize(border_LT.x + (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,
border_LT.x + (border_RB.x - border_LT.x) / 4 +
textwidth(str) + textwidth("100"),
border_LT.y - 2 * th + th);
buf = malloc(size);
getimage(border_LT.x + (border_RB.x - border_LT.x) / 4,border_LT.y - 2 * th,
border_LT.x + (border_RB.x - border_LT.x) / 4 + textwidth(str) +
textwidth("100"),
border_LT.y - 2 * th + th,buf);
putimage(border_LT.x + (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,buf,XOR_PUT);
outtextxy(border_LT.x + (border_RB.x - border_LT.x) / 4,
border_LT.y - 2 * th,str);
free(buf);
}
}
/* sub function: help()
*/
/* function: show help information at the beginning of game */
/* and let player know how to play the game */
void help()
{
char str[100];
int th;
settextstyle(DEFAULT_FONT,0,1);
setcolor(HELP_COLOR);
th = textheight("hello");
sprintf(str,"move left : %c",27);
outtextxy(border_LT.x,border_RB.y,str);
sprintf(str,"move up : %c",24);
outtextxy(border_LT.x + (border_RB.x - border_LT.x) / 2,
border_RB.y,str);
sprintf(str,"move down : %c",25);
outtextxy(border_LT.x,border_RB.y + th + 2,str);
sprintf(str,"move right: %c",26);
outtextxy(border_LT.x + (border_RB.x - border_LT.x) / 2,
border_RB.y + th + 2,str);
outtextxy(border_LT.x,border_RB.y + th * 2 + 4,"quit <Q/q>");
outtextxy(border_LT.x + textwidth("quit <Q/q>") * 3 / 2,border_RB.y + th * 2 + 4,
"pause <P/p>");
outtextxy(border_LT.x + (border_RB.x - border_LT.x) / 2,
border_RB.y + th * 2 + 4,"select level <S/s>");
}
/* sub function: show_all()
*/
/* function:redraw the play area,means show wall */
void show_all()
{
int i,j;
setcolor(DEFAULT_COLOR);
/*
for(i = border_LT.x; i <= border_RB.x; i += SCALE)
for(j = border_LT.y; j <= border_RB.y; j += SCALE)
rectangle(i,j,i + SCALE, j + SCALE);
*/
rectangle(border_LT.x,border_LT.y,border_RB.x,border_RB.y);
}
/* sub function: generate_food()
*/
/* function:after the food is eaten by snake,the function will */
/* be called to generate another food,and it will */
/* ensure that the generated food shouldn't appeare */
/* in the snake body.
*/
void generate_food()
{
FOOD_INFOR_PTR traceon;
int tempx,tempy;
generate:
current->posx = random(border_RB.x - SCALE / 2);
while((current->posx <= border_LT.x) || ((current->posx - border_LT.x) % SCALE == 0) ||
((current->posx - border_LT.x) % SCALE % (SCALE / 2) != 0))
current->posx ++;
current->posy = random(border_RB.y - SCALE / 2);
while((current->posy <= border_LT.y) || ((current->posy - border_LT.y) % SCALE == 0) ||
((current->posy - border_LT.y) % SCALE % (SCALE / 2) != 0))
current->posy ++;
traceon = snake_head.next;
while(traceon)
{
if((traceon->posx == current->posx) && (traceon->posy == current->posy))
goto generate;
traceon = traceon->next;
}
if(current->posx - border_LT.x == SCALE / 2)
current->posx += SCALE;
if(border_RB.x - current->posx == SCALE / 2)
current->posx -= SCALE;
if(current->posy - border_LT.y == SCALE / 2)
current->posy += SCALE;
if(border_RB.y - current->posy == SCALE / 2)
current->posy -= SCALE;
setcolor(DEFAULT_COLOR);
rectangle(current->posx - SCALE / 2,current->posy - SCALE / 2,
current->posx + SCALE / 2,current->posy + SCALE / 2);
setfillstyle(SOLID_FILL,YELLOW);
floodfill(current->posx,current->posy,DEFAULT_COLOR);
}
/* sub function: init_graphics()
*/
/* function:initialize the game interface */
void init_graphics()
{
driver = DETECT;
mode = 0;
initgraph(&driver,&mode,"*.bgi");
maxx = getmaxx();
maxy = getmaxy();
border_LT.x = maxx / SCALE;
border_LT.y = maxy / SCALE;
border_RB.x = maxx * (SCALE - 1) / SCALE;
border_RB.y = maxy * (SCALE - 1) / SCALE;
while((border_RB.x - border_LT.x) % FOOD_SIZE)
(border_RB.x) ++;
while((border_RB.y - border_LT.y) % FOOD_SIZE)
(border_RB.y) ++;
while((border_RB.y - border_LT.y) % ( 12 * SCALE))
border_RB.y += SCALE;
setcolor(DEFAULT_COLOR);
rectangle(border_LT.x,border_LT.y,border_RB.x,border_RB.y);
help();
show_level();
}
/* sub function: generateX_first_step() */
/* function:generate snake head and first food to prepare for */
/* game to start,and this function will also initialize*/
/* the move direction of snake head,and show welcome */
/* information to player.
*/
void generate_first_step()
{
char str[] = "welcome to snake game,press ENTER key to start";
int size;
int tempx,tempy;
void *buf;
randomize();
/* generate snake head */
snake_head.posx = random(border_RB.x - SCALE / 2);
while((snake_head.posx <= border_LT.x) || ((snake_head.posx - border_LT.x) % SCALE == 0)
||
((snake_head.posx - border_LT.x) % SCALE % (SCALE / 2) != 0))
snake_head.posx ++;
snake_head.posy = random(border_RB.y - SCALE / 2);
while((snake_head.posy <= border_LT.y) || ((snake_head.posy - border_LT.y) % SCALE == 0)
||
((snake_head.posy - border_LT.y) % SCALE % (SCALE / 2) != 0))
snake_head.posy ++;
setcolor(DEFAULT_COLOR);
rectangle(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,
snake_head.posx + SCALE / 2,snake_head.posy + SCALE / 2);
setfillstyle(SOLID_FILL,SNAKE_HEAD_COLOR);
floodfill(snake_head.posx,snake_head.posy,DEFAULT_COLOR);
/* generate first food */
current = (FOOD_INFOR_PTR)malloc(sizeof(FOOD_INFOR));
goon_generate:
current->posx = random(border_RB.x - SCALE / 2);
while((current->posx <= border_LT.x) || ((current->posx - border_LT.x) % SCALE == 0) ||
((current->posx - border_LT.x) % SCALE % (SCALE / 2) != 0))
current->posx ++;
current->posy = random(border_RB.y - SCALE / 2);
while((current->posy <= border_LT.y) || ((current->posy - border_LT.y) % SCALE == 0) ||
((current->posy - border_LT.y) % SCALE % (SCALE / 2) != 0))
current->posy ++;
if((current->posx == snake_head.posx) && (current->posy == snake_head.posy))
goto goon_generate;
rectangle(current->posx - SCALE / 2,current->posy - SCALE / 2,
current->posx + SCALE / 2,current->posy + SCALE / 2);
setfillstyle(SOLID_FILL,FOOD_COLOR);
floodfill(current->posx,current->posy,DEFAULT_COLOR);
calculate_hop();
snake_head.next = NULL;
snake_head.eatenC = 0;
snake_head.hop = 0;
current->next = NULL;
current->pre = NULL;
current->beEaten = 0;
current->next_move = INVALID_DIRECTION;
current->pre_move = INVALID_DIRECTION;
if(snake_head.posx == current->posx)
{
if(snake_head.posy > current->posy)
snake_head.next_move = MOVE_UP;
else
snake_head.next_move = MOVE_DOWN;
}
else
{
if(snake_head.posx < current->posx)
snake_head.next_move = MOVE_RIGHT;
else
snake_head.next_move = MOVE_LEFT;
}
snake_head.pre_move = snake_head.next_move;
settextstyle(DEFAULT_FONT,0,1);
setcolor(WELCOME_COLOR);
tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2;
tempy = border_LT.y - textheight("A") * 6 / 2;
outtextxy(tempx,tempy,str);
size = imagesize(tempx,tempy,tempx + textwidth(str),
tempy + textheight(str));
buf = malloc(size);
getimage(tempx,tempy,tempx + textwidth(str),
tempy + textheight(str),buf);
while(bioskey(0) != 0x1c0d);
putimage(tempx,tempy,buf,XOR_PUT);
free(buf);
}
/* sub function: judge_death()
*/
/* function:judge if the snake will die because of incorrect */
/* move,there are two things that will result */
/* the snake to death:first,it run into the wall */
/* ,and second,it run into its body.
*/
int judge_death()
{
/* return 1 means will die,and return 0 means will survive */
int tempx,tempy;
switch(snake_head.next_move)
{
case MOVE_UP:
tempx = snake_head.posx;
tempy = snake_head.posy - SCALE;
break;
case MOVE_LEFT:
tempx = snake_head.posx - SCALE;
tempy = snake_head.posy;
break;
case MOVE_DOWN:
tempx = snake_head.posx;
tempy = snake_head.posy + SCALE;
break;
case MOVE_RIGHT:
tempx = snake_head.posx + SCALE;
tempy = snake_head.posy;
break;
default:
break;
}
if((tempx < border_LT.x) || (tempx > border_RB.x) ||
(tempy < border_LT.y) || (tempy > border_RB.y))
return 1;
if(getpixel(tempx,tempy) == snake_color)
{
FOOD_INFOR_PTR traceon;
traceon = snake_head.next;
while(traceon != NULL)
{
if((traceon->posx == tempx) && (traceon->posy == tempy))
return 1;
traceon = traceon->next;
}
}
return 0; /* survive */
}
/* sub function: willeatfood() */
/* function:judge if the sanke can eat food.the method like */
/* this:provided that the snake move a step based */
/* on its next move direction,and if this place */
/* have food,then the snake can eat food. */
int willeatfood()
{
/* 1 means will eat food ,and 0 means won't eat food */
int tempx,tempy;
switch(snake_head.next_move)
{
case MOVE_UP:
tempx = snake_head.posx;
tempy = snake_head.posy - SCALE;
break;
case MOVE_LEFT:
tempx = snake_head.posx - SCALE;
tempy = snake_head.posy;
break;
case MOVE_DOWN:
tempx = snake_head.posx;
tempy = snake_head.posy + SCALE;
break;
case MOVE_RIGHT:
tempx = snake_head.posx + SCALE;
tempy = snake_head.posy;
break;
default:
break;
}
if(getpixel(tempx,tempy) == FOOD_COLOR)
return 1;
return 0;
}
/* sub function: addonefood() */
/* function: this function will lengthen the snake body */
/* this function is important because it will */
/* not only locate memory for new snake body, */
/* but also handle the relationship of pointer*/
/* between the new snake body and its previous*/
/* snake body.
*/
void addonefood()
{
FOOD_INFOR_PTR traceon;
snake_head.eatenC ++ ;
traceon = snake_head.next;
if(snake_head.next == NULL) /* haven't eaten any food */
{
traceon = (FOOD_INFOR_PTR)malloc(sizeof(FOOD_INFOR));
switch(snake_head.next_move)
{
case MOVE_UP:
traceon->posx = snake_head.posx;
traceon->posy = snake_head.posy + SCALE;
break;
case MOVE_LEFT:
traceon->posx = snake_head.posx + SCALE;
traceon->posy = snake_head.posy;
break;
case MOVE_DOWN:
traceon->posx = snake_head.posx;
traceon->posy = snake_head.posy - SCALE;
break;
case MOVE_RIGHT:
traceon->posx = snake_head.posx - SCALE;
traceon->posy = snake_head.posy;
break;
default:
break;
}
traceon->next_move = snake_head.next_move;
traceon->pre_move = snake_head.next_move;
traceon->next = NULL;
traceon->pre = NULL;
traceon->beEaten = 1;
snake_head.next = traceon;
}
else
{
while(traceon)
{
if(traceon->next != NULL)
traceon = traceon->next;
else
break;
}
traceon->next = (FOOD_INFOR_PTR)malloc(sizeof(FOOD_INFOR));
traceon->next->next = NULL;
traceon->next->pre = traceon;
traceon = traceon->next;
switch(traceon->pre->next_move)
{
case MOVE_UP:
traceon->posx = traceon->pre->posx;
traceon->posy = traceon->pre->posy + SCALE;
break;
case MOVE_LEFT:
traceon->posx = traceon->pre->posx + SCALE;
traceon->posy = traceon->pre->posy;
break;
case MOVE_DOWN:
traceon->posx = traceon->pre->posx;
traceon->posy = traceon->pre->posy - SCALE;
break;
case MOVE_RIGHT:
traceon->posx = traceon->pre->posx - SCALE;
traceon->posy = traceon->pre->posy;
break;
default:
break;
}
traceon->next_move = traceon->pre->next_move;
traceon->pre_move = traceon->pre->next_move;
traceon->beEaten = 1;
}
}
/* sub function: sort_all()
*/
/* function:this function will calculate the next position of snake */
/* and it is assume the snake has move to next position,but*/
/* haven't appeared yet.
*/
void sort_all()
{
/* sort all food,include snake head,and virtual place */
FOOD_INFOR_PTR traceon;
void *buf;
int size;
size = imagesize(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,
snake_head.posx + SCALE / 2,snake_head.posy + SCALE /
2);
buf = malloc(size);
getimage(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,
snake_head.posx + SCALE / 2,snake_head.posy + SCALE / 2,buf);
putimage(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,
buf,XOR_PUT);
switch(snake_head.next_move)
{
case MOVE_UP:
snake_head.posy -= SCALE;
break;
case MOVE_LEFT:
snake_head.posx -= SCALE;
break;
case MOVE_DOWN:
snake_head.posy += SCALE;
break;
case MOVE_RIGHT:
snake_head.posx += SCALE;
break;
default:
break;
}
traceon = snake_head.next;
while(traceon)
{
getimage(traceon->posx - SCALE / 2,traceon->posy - SCALE / 2,
traceon->posx + SCALE / 2,traceon->posy + SCALE / 2,buf);
putimage(traceon->posx - SCALE / 2,traceon->posy - SCALE / 2,
buf,XOR_PUT);
switch(traceon->next_move)
{
case MOVE_UP:
traceon->posy -= SCALE;
break;
case MOVE_LEFT:
traceon->posx -= SCALE;
break;
case MOVE_DOWN:
traceon->posy += SCALE;
break;
case MOVE_RIGHT:
traceon->posx += SCALE;
break;
default:
break;
}
traceon = traceon->next;
}
free(buf);
}
/* sub function: redrawsnake()
*/
/* function:the function will redraw the snake based on function*/
/* sort_all().
*/
void redrawsnake()
{
FOOD_INFOR_PTR traceon;
setcolor(DEFAULT_COLOR);
/* redraw snake head */
setfillstyle(SOLID_FILL,SNAKE_HEAD_COLOR);
rectangle(snake_head.posx - SCALE / 2,snake_head.posy - SCALE / 2,
snake_head.posx + SCALE / 2,snake_head.posy + SCALE / 2);
floodfill(snake_head.posx,snake_head.posy,DEFAULT_COLOR);
/* redraw all eaten foodd */
setfillstyle(SOLID_FILL,snake_color);
traceon = snake_head.next;
while(traceon)
{
rectangle(traceon->posx - SCALE / 2,traceon->posy - SCALE / 2,
traceon->posx + SCALE / 2,traceon->posy + SCALE / 2);
floodfill(traceon->posx,traceon->posy,DEFAULT_COLOR);
traceon = traceon->next;
}
}
/* sub function: change_direction() */
/* function:this function will assign the next move direction*/
/* of snake,it calculate on basis of the information*/
/* of snake body structure.
*/
void change_direction()
{
FOOD_INFOR_PTR traceon,temp1,temp2;
traceon = snake_head.next;
/*if(traceon == NULL)*/ /* only have snake head */
snake_head.pre_move = snake_head.next_move;
if(traceon != NULL)
{
while(traceon)
{
if(traceon->next != NULL)
traceon = traceon->next;
else
break;
}
while(traceon->pre != NULL)
{
traceon->pre_move = traceon->next_move;
traceon->next_move = traceon->pre->next_move; /***/
traceon = traceon->pre;
}
traceon->pre_move = traceon->next_move;
traceon->next_move = snake_head.pre_move;
}
}
/* SOCRE CODE ENDED */
/* DATE: JUL 2th,01 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -