|
作者: kenter1643 [kenter1643] 论坛用户 | 登录 |
贪吃蛇源程序 本程序为贪吃蛇游戏,想必大家都玩过这个游戏,程序源代码用TC2.0编译通过,需要图形驱动文件的支持,在TC2.0的集成环境中有. 本程序利用数据结构中的链表,来将蛇身连接,同时当蛇吃到一定数目的东西时会自动升级,及移动速度会加快,程序会时刻将一些信息显示在屏幕上,包括所得分数,要吃多少东西才能升级,并且游戏者可以自己手动选择游戏级别,级别越高,蛇的移动速度越快. 另外,此游戏可能与CPU的速度有关系. 源代码如下: ********************************************************************************** /*******************************COMMENTS**********************************/ /* snake_game.c */ /* it is a game for entermainment. */ /* in the begin,there is only a snake head,and it will have to eat food */ /* to become stronger,and it eat a piece of food each time,it will */ /* lengthen it's body,with the number of food the snake eats going up,it */ /* will become long more and more,and the score will goes up also. */ /* there is always useful information during the game process. */ /* if the path by which the snake goes to eat food is the shortest,the */ /* score will add up a double. */ /* */ /* enjoy yourself,and any problem,contact <blldw@etang.com> */ /*************************************************************************/ /* all head file that will be used */ #include<stdio.h>/*调用输入输出函数*/ #include<time.h>/**/ #include<graphics.h>/**/ #include<stdlib.h>/**/ #include<ctype.h>/*调用字符函数*/ #include<string.h>/*调用字符串函数*/ /* useful MACRO */ #define FOOD_SIZE 8 #define SCALE 8 #define UP_KEY 0x4800 #define DOWN_KEY 0x5000 #define LEFT_KEY 0x4b00 #define RIGHT_KEY 0x4d00 #define MOVE_UP 1 #define MOVE_LEFT 2 #define MOVE_DOWN 3 #define MOVE_RIGHT 4 #define INVALID_DIRECTION 0 #define QUIT_KEYC 0x1051 #define QUIT_KEY 0x1071 #define SELECT_KEYC 0x1f53 #define SELECT_KEY 0x1f73 #define PAUSE_KEYC 0x1950 #define PAUSE_KEY 0x1970 #define DEFAULT_LEVEL 1 #define HELP_COLOR WHITE #define WELCOME_COLOR WHITE #define DEFAULT_COLOR GREEN /* define the macro as follows to improve the game in future */ #define FOOD_COLOR YELLOW #define SNAKE_HEAD_COLOR RED #define DEFAULT_SNAKE_COLOR YELLOW #define EXIT_COLOR WHITE #define SCORE_COLOR YELLOW /* sturcture for snake body mainly ,and food also */ typedef struct food_infor *FOOD_INFOR_PTR; typedef struct food_infor{ int posx; /* position for each piece of snake body */ int posy; int next_move; /* next move direction */ int pre_move; /* previous move direction,seems unuseful */ int beEaten; /* xidentifier for snake body or food */ FOOD_INFOR_PTR next; /* pointer to next piece of snake body */ FOOD_INFOR_PTR pre; /* pointer to previous piece of snake body */ }FOOD_INFOR; /* structure for snake head */ typedef struct _snake_head{ int posx; int posy; int next_move; int pre_move; int eatenC; /* number of food that have been eaten */ int hop; /* number of steps to eat food */ FOOD_INFOR_PTR next; /* pointer to the first piece of eaten food */ }SNAKE_HEAD; /* the left-up corner and right-down corner */ typedef struct point{ int x; int y; }POINT; /* standards for game speed */ /* before level 5,the time interval is level_b[level - 1] / 10,and after */ /* level 5,the time interval is 1.00 / level_b[level - 1] */ float level_b[9] = {10.0,8.0,6.0,3.0,1.0,20.0,40.0,160.0,640.0}; /* available varary */ SNAKE_HEAD snake_head; FOOD_INFOR *current; /* always point to food */ POINT border_LT,border_RB; int driver,mode; /* for graphics driver */ int maxx,maxy; /* max length and width of screen,in pixel */ int eaten; /* identifier if the food is eaten */ int score = 0; /* total score */ int level = DEFAULT_LEVEL; /* level or speed */ float interval; /* based on speed */ int snake_color = DEFAULT_SNAKE_COLOR; /* snake body color */ int hopcount = 0; /* the shortest number of steps for snake */ /* to eat food */ /* all sub function */ void init_graphics(); void generate_first_step(); int judge_death(); int willeatfood(); void generate_food(); void addonefood(); void redrawsnake(); void show_all(); void sort_all(); void change_direction(); void help(); void show_score(int); void change_level(); void show_level(); void release(SNAKE_HEAD); int can_promote(); void win(); void show_infor_to_level(); void show_eaten(); void calculate_hop(); /* main function or entry */ void main() { char str[50] = "YOU LOSE!!!"; /* fail information */ clock_t start; int querykey; int tempx,tempy; /* if fail and want to resume game,go here */ retry: init_graphics(); show_all(); /* show wall */ generate_first_step(); /* generate food and snake head */ show_score(score); /* show score to player */ eaten = 0; /* begin to play game */ while(1) { if(judge_death() == 1) /* die */ break; if(willeatfood() == 1) { eaten = 1; addonefood(); snake_head.hop ++; if(snake_head.hop == hopcount) score += level * 2; else score += level; can_promote(); show_score(score); } sort_all(); redrawsnake(); snake_head.hop ++; show_infor_to_level(); show_eaten(); show_all(); change_direction(); if(eaten == 1) { generate_food(); calculate_hop(); snake_head.hop = 0; eaten = 0; } if(level <= 5) interval = level_b[level - 1] / 10.0; else interval = 1.00 / level_b[level - 1]; start = clock(); while((clock() - start) / CLK_TCK < interval) { querykey = bioskey(1); if(querykey != 0) { switch(bioskey(0)) { case UP_KEY: snake_head.next_move = MOVE_UP; break; case LEFT_KEY: snake_head.next_move = MOVE_LEFT; break; case DOWN_KEY: snake_head.next_move = MOVE_DOWN; break; case RIGHT_KEY: snake_head.next_move = MOVE_RIGHT; break; case SELECT_KEYC: case SELECT_KEY: change_level(); score = 0; show_score(score); show_level(); break; case PAUSE_KEYC: case PAUSE_KEY: while(!bioskey(1)); break; case QUIT_KEYC: case QUIT_KEY: goto exit_game; default: break; } } } } settextstyle(DEFAULT_FONT,0,2); setcolor(EXIT_COLOR); tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2; tempy = border_LT.y + (border_RB.y - border_LT.y) / 2; outtextxy(tempx,tempy,str); strcpy(str,"press <R/r> to retry,or ENTER key to exit"); tempy += textheight(str) * 2; settextstyle(DEFAULT_FONT,0,1); tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2; outtextxy(tempx,tempy,str); select: while(!bioskey(1)); querykey = bioskey(0); if((querykey == 0x1372) || (querykey == 0x1352)) { level = DEFAULT_LEVEL; score = 0; release(snake_head); closegraph(); goto retry; } if(querykey != 0x1c0d) goto select; closegraph(); return; exit_game: release(snake_head); closegraph(); } /* sub function show_eaten() */ /* function: to show the total number piece of food */ /* that have been eaten by snake any time */ void show_eaten() { int tempx,tempy; int size; void *buf; char str[15]; settextstyle(DEFAULT_FONT,0,1); setcolor(DEFAULT_COLOR); sprintf(str,"eaten:%d",snake_head.eatenC); tempx = 0; tempy = border_LT.y + textheight(str) * 6; size = imagesize(tempx,tempy,tempx + textwidth(str) + textwidth("A"), tempy + textheight(str)); buf = malloc(size); getimage(tempx,tempy,tempx + textwidth(str) + textwidth("A"), tempy + textheight(str),buf); putimage(tempx,tempy,buf,XOR_PUT); outtextxy(tempx,tempy,str); free(buf); } /* sub function: show_infor_to_level */ /* function:show information to player that how many pieces */ /* of food have to been eaten to get to next level */ /* ,and this is not related with score,but only */ /* eaten number of food */ /* */ /* level standard:let highlevel stand for the number of */ /* pieces of food that can be put int the */ /* vertical direction of play area,and */ /* before level 5,as long as the snake eat */ /* a quarter of highlevel,it will go to next */ /* level,and between level 5 and 7,as long */ /* as the snake eat one thirds of highlevel, */ /* it will go to next level,and between */ /* level 8 and 9,the snake will go to next */ /* level as long as it eat half of highlevel */ /* note: level is between 1 to 9. */ void show_infor_to_level() { int highlevel; int size; int tempx,tempy; int toeat; void *buf; char str[50]; highlevel = (border_RB.y - border_LT.y) / SCALE; switch(level) { case 1: case 2: case 3: case 4: toeat = (highlevel / 4) * level - snake_head.eatenC; break; case 5: case 6: case 7: toeat = (highlevel + highlevel / 3 * (level - 4)) - snake_head.eatenC; break; case 8: case 9: toeat = (highlevel * 2 + highlevel / 2 * (level - 7)) - snake_head.eatenC; break; default: break; } settextstyle(DEFAULT_FONT,0,1); setcolor(DEFAULT_COLOR); if(snake_head.next == NULL) { sprintf(str,"next level"); tempx = 0; tempy = border_LT.y + textheight(str) * 2; outtextxy(tempx,tempy,str); } if(toeat < 0) toeat = 0; sprintf(str,"%d:%d",level + 1,toeat); tempx = 0; tempy = border_LT.y + textheight(str) * 4; size = imagesize(tempx,tempy,tempx + textwidth(str) + textwidth("A"),tempy + textheight(str)); buf = malloc(size); getimage(tempx,tempy,tempx + textwidth(str) + textwidth("A"),tempy + textheight(str),buf); putimage(tempx,tempy,buf,XOR_PUT); outtextxy(tempx,tempy,str); free(buf); } /* sub function: win() */ /* function:if the player pass level 9,this function */ /* will be called ,to show "YOU WIN information */ /* and after a key is pressed,the game will go */ /* on,but all is back to begin,excepte the */ /* snake body length. */ void win() { char str[] = "YOU WIN"; int tempx,tempy; settextstyle(DEFAULT_FONT,0,8); setcolor(WELCOME_COLOR); tempx = border_LT.x + (border_RB.x - border_LT.x - textwidth(str)) / 2; tempy = border_LT.y + (border_RB.y - border_LT.y - textheight(str)) / 2; outtextxy(tempx,tempy,str); while(!bioskey(1)); } /* sub function: can_promote() */ /* function:see if the snake can go to next level on basis */ /* of the snake length. */ /* */ /* note:standards of promote level is instructed above */ int can_promote() { /* compare SCORE with standard level score */ int high_level; static int last_score = 0; high_level = (border_RB.y - border_LT.y) / SCALE; switch(level) { case 1: case 2: case 3: case 4: if(snake_head.eatenC == (high_level / 4 * level)) level ++; last_score = score; break; case 5: case 6: case 7: if(snake_head.eatenC == (high_level + high_level / 3 * (level - 4))) level ++; last_score = score; break; case 8: if(snake_head.eatenC == (high_level * 2 + high_level / 2 )) level ++; last_score = score; break; case 9: if(snake_head.eatenC == (high_level * 3)) { win(); score = 0; last_score = 0; level = DEFAULT_LEVEL; } break; default: break; } show_level(); } /* sub function: calulate_hop() */ /* function: calculate the shortest path from snake head to */ /* the food it will eaten. */ void calculate_hop() { hopcount = (snake_head.posx >= current->posx) ? ((snake_head.posx - current->posx) / SCALE) : ((current->posx - snake_head.posx) / SCALE); hopcount += (snake_head.posy >= current->posy) ? ((snake_head.posy - current->posy) / SCALE) : ((current->posy - snake_head.posy) / SCALE); } /* sub function: release() */ /* function:free memory before exit game or restart */ void release(SNAKE_HEAD snake_head) { FOOD_INFOR_PTR traceon,last; traceon = snake_head.next; snake_head.eatenC = 0; snake_head.next = NULL; snake_head.hop = 0; while(traceon) if(traceon->next != NULL) traceon = traceon->next; else break; while(traceon) { last = traceon->pre; free(traceon); traceon = last; } } /* sub function: show_level()x */ /* function:show level information to player anytime */ void show_level() { char str[20]; int size; void *buf; settextstyle(DEFAULT_FONT,0,1); setcolor(DEFAULT_COLOR); sprintf(str,"Level:%d",level); size = imagesize(0,border_LT.y,textwidth(str),border_LT.y + textheight(str)); buf = malloc(size); getimage(0,border_LT.y,textwidth(str), border_LT.y + textheight(str),buf); putimage(0,border_LT.y,buf,XOR_PUT); free(buf); outtextxy(0,border_LT.y,str); } /* sub function: change_level() */ /* function:if the play choose "select level <S/S>" item, */ /* this function will be called */ void change_level() { int c; int size; void *buf; int tempx,tempy; char str[] = "new level (1--9):"; settextstyle(DEFAULT_FONT,0,1); setcolor(DEFAULT_COLOR); tempx = 0; tempy = border_LT.y - textheight("A") * 3 / 2; outtextxy(tempx,tempy,str); goon: while(!bioskey(1)); c = bioskey(0); if((c == 0x1051) || (c == 0x1071)) goto exit; if(isdigit(c&0x00ff)) level = (c&0x00ff) - 48; else goto goon; exit: size = imagesize(tempx,tempy,tempx + textwidth(str),tempy + textheight(str)); buf = malloc(size); getimage(tempx,tempy,tempx + textwidth(str),tempy + textheight(str),buf); putimage(tempx,tempy,buf,XOR_PUT); free(buf); } /* sub function: show_score() */ /* function:show score information to player anytime */ void show_score(int count) { int th; int size; void *buf; char str[20]; settextstyle(DEFAULT_FONT,0,2); setcolor(SCORE_COLOR); sprintf(str,"Score: %d",count); th = textheight("hello"); if((count == 0) && (snake_head.next == NULL)) { 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 */ |
地主 发表时间: 08/21 10:12 |
回复: 286 [unique] 版主 | 登录 |
不错,很好。 |
B1层 发表时间: 08/21 17:27 |
回复: jkd [jkd] 论坛用户 | 登录 |
大哥!!!!!!!! 用QB给我编一个!!!!!!!!! |
B2层 发表时间: 08/21 17:34 |
回复: kenter1643 [kenter1643] 论坛用户 | 登录 |
我不会QB |
B3层 发表时间: 08/22 10:52 |
回复: zzzaaa [zzzaaa] 论坛用户 | 登录 |
唉,,,还是一篇灌水文章。。。。 失望啊。。。。。 |
B4层 发表时间: 08/22 11:11 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号