#include "stdio.h" |
#include "stdlib.h" |
#include "graphics.h" |
#include "conio.h" |
#include "bios.h" |
#include "time.h" |
#include "dos.h" |
#include "string.h" |
#include "snake_07.h" |
struct snake{ |
int x[snake_node]; // 蛇每一节的左上角x坐标 |
int y[snake_node]; // 蛇每一节的左上角y坐标 |
int node; // 蛇当前有多少节,初始化为2 |
int direction; // 蛇移动的方向,初始化为DIRECTION_RIGHT |
int life; // 蛇的生命值 |
int foodCount; // 蛇吃了多少食物,初始为0 |
int score; // 得分,初始为0 |
} snake; |
struct food{ |
int x; // 食物的左上角的x坐标 |
int y; // 食物的左上角的y坐标 |
} food; |
void init(); |
void close(); |
void startCanvas(); |
void playCanvas( int mission); |
void play( int wallMission, int barreriMission, int speed, char title[], int snakeX, int snakeY); |
void initFood(); |
void drawFood(); |
void initSnake( int x, int y); |
void drawSnake(); |
void snakeMove( int key); |
int needToMove( int key); |
int isDirectionKey( int key); |
void initHorizontalWall( int mission); |
void initVerticalWall( int mission); |
void initBarriers( int mission); |
void drawWallAndBarrier( int wallMission, int barrierMission); |
int collision(); |
void bitFood(); |
int bitSelf(); |
void printScore(); |
void gameOver(); |
void ccl(); |
int round( int o); |
int getX( int col); |
int getY( int row); |
int getRow( int y); |
int getCol( int x); |
int main() |
{ |
init(); |
startCanvas(); |
close(); |
return 0; |
} |
void init(){ |
int gdriver=DETECT,gmode; |
registerbgidriver(EGAVGA_driver); |
initgraph(&gdriver,&gmode, "" ); |
} |
void close(){ |
getch(); |
closegraph(); |
} |
/** |
游戏开始界面,提供相应的选项,如模式选择,关卡选择,及退出 |
*/ |
void startCanvas(){ |
int key; |
cleardevice(); |
setbkcolor(9); |
setcolor(14); |
settextstyle(0,0,3); |
outtextxy(20,20, "Welcome to My Snake Game!" ); |
settextstyle(0,0,2); |
outtextxy(200,130, "1. Mission One" ); |
outtextxy(200,160, "2. Mission Two" ); |
outtextxy(200,190, "3. Mission Three" ); |
outtextxy(200,220, "4. Quit" ); |
key=bioskey(0); |
switch (key){ |
case key_one:playCanvas(key_one); break ; |
case key_two:playCanvas(key_two); break ; |
case key_three:playCanvas(key_three); break ; |
case key_four:cleardevice(); exit (0); break ; |
} |
} |
/** |
进入指定模式或关卡的游戏界面 |
*/ |
void playCanvas( int mission){ |
cleardevice(); |
if (mission==key_one){ |
play(WALL_MISSION_ONE,BARRIER_MISSION_ONE,SPEED_MISSION_ONE, "Mission:1" ,30,60); |
} else if (mission==key_two){ |
play(WALL_MISSION_TWO,BARRIER_MISSION_TWO,SPEED_MISSION_TWO, "Mission:2" ,30,60); |
} else if (mission==key_three){ |
play(WALL_MISSION_THREE,BARRIER_MISSION_THREE,SPEED_MISSION_THREE, "Minssion:3" ,30,60); |
} |
} |
void play( int wallMission, int barrierMission, int speed, char title[], int snakeX, int snakeY) |
{ |
int key=key_right; |
int isRunning=1; |
ccl(); |
outtextxy(20,20,title); |
initHorizontalWall(wallMission); |
initVerticalWall(wallMission); |
initBarriers(barrierMission); |
initFood(); // 出现随机食物 |
initSnake(snakeX, snakeY); //出现一条随机的蛇 |
printScore(); // 开始判断用户的键盘输入 |
while (snake.life){ |
while (!kbhit()){ |
snakeMove(key); //让蛇移动 |
drawFood(); // 重新绘制食物 |
drawWallAndBarrier(wallMission, barrierMission); //绘制围墙和障碍物 |
if (collision()){ //进行碰撞检测 ,如果有碰撞,则游戏结束 |
if (--snake.life==0){ |
isRunning=0; |
break ; |
} |
} |
bitFood(); //检测吃食物 |
delay(speed); // 延迟5指定毫秒数 |
} |
if (!isRunning){ |
break ; |
} |
//接收用户的键盘输入,如果按的方向键,则让蛇在该方向上移动,如果按的esc键,则退出到选择界面 |
key=bioskey(0); |
if (isDirectionKey(key)){ |
if (needToMove(key)){ // 判断蛇是否需要更换方向 |
snakeMove(key); |
} |
} else if (key==key_esc){ |
startCanvas(); |
} else if (key==key_a){ |
getch(); |
} |
} |
gameOver(); |
} |
/** |
根据围墙数组和关卡初始化该关的横向围墙 |
*/ |
void initHorizontalWall( int mission){ |
int i; |
for (i=0;i<TOTAL_COLS;i++){ |
canvas[0][i]=HORIZONTAL_WALL[mission-1][i]; |
canvas[TOTAL_ROWS-1][i]=HORIZONTAL_WALL[mission][i]; |
} |
} |
/** |
通过列索引获取该格子的x坐标 |
*/ |
int getX( int col){ |
return col*rectangle_size+canvas_min_x; |
} |
/** |
通过行索引获取该格子的y坐标 |
*/ |
int getY( int row){ |
return row*rectangle_size+canvas_min_y; |
} |
/** |
根据围墙数组和关卡初始化该关的纵向围墙 |
*/ |
void initVerticalWall( int mission){ |
int i; |
for (i=0;i<TOTAL_ROWS;i++){ |
canvas[i][0]=VERTICAL_WALL[mission-1][i]; |
canvas[i][TOTAL_COLS-1]=VERTICAL_WALL[mission][i]; |
} |
} |
void initBarriers( int mission){ |
int i; |
int type; |
for (i=0;i<TOTAL_BARRIERS;i++){ |
type=barriers[mission][i].type; |
if (type==EMPTY){ // 去除掉barriers后面的那些未被赋值的障碍物 |
break ; |
} |
canvas[barriers[mission][i].row][barriers[mission][i].col]=barriers[mission][i].type; |
} |
} |
/** |
根据初始化的围墙数据绘制围墙 |
*/ |
void drawWallAndBarrier( int , int ){ |
int i,j; |
for (i=0;i<TOTAL_ROWS;i++){ |
for (j=0;j<TOTAL_COLS;j++){ |
if (canvas[i][j]==WALL){ |
setfillstyle(8,10); |
bar(getX(j),getY(i), getX(j)+rectangle_size,getY(i)+rectangle_size); |
} else if (canvas[i][j]==BARRIER_RECT){ |
setfillstyle(8,12); |
bar(getX(j),getY(i), getX(j)+rectangle_size,getY(i)+rectangle_size); |
} else if (canvas[i][j]==BARRIER_CIRCLE){ |
circle(getX(j)+rectangle_size/2, getY(i)+rectangle_size/2,rectangle_size/2); |
} |
} |
} |
} |
/** |
在有效区域内随机产生食物,保留坐标,并且确保食物与方格重合 |
*/ |
void initFood(){ |
int row,col; |
randomize(); |
food.x= rand ()%(canvas_valid_max_x-canvas_valid_min_x-2*rectangle_size)+canvas_valid_min_x; |
food.y= rand ()%(canvas_valid_max_y-canvas_valid_min_y-2*rectangle_size)+canvas_valid_min_y; |
food.x=round(food.x); |
food.y=round(food.y); |
row=getRow(food.y); |
col=getCol(food.x); |
// 判断食物是否出现在障碍物上,如果在障碍物上,重新获取食物 |
while (canvas[row][col]==BARRIER_RECT||canvas[row][col]==BARRIER_CIRCLE){ |
if (food.x==canvas_valid_max_x-rectangle_size){ |
food.x=canvas_valid_min_x; |
} |
if (food.y==canvas_valid_max_y-rectangle_size){ |
food.y=canvas_valid_min_y; |
} |
food.x+=rectangle_size; |
food.y+=rectangle_size; |
row=getRow(food.y); |
col=getCol(food.x); |
} |
} |
/** |
对整数o进行四舍五入取整操作 |
*/ |
int round( int o){ |
return ( int )((o+5)/10.f)*10; |
} |
/** |
根据随机产生的食物坐标绘制食物 |
*/ |
void drawFood(){ |
setfillstyle(1,GREEN); |
bar(food.x,food.y,food.x+rectangle_size,food.y+rectangle_size); |
} |
/** |
在有效区域内随机产生一条蛇并保留坐标,并且确保蛇头与某个方格重合,方向初始化为向右,蛇身2节 |
*/ |
void initSnake( int x, int y){ |
snake.node=2; |
snake.life=1; |
snake.foodCount=0; |
snake.score=0; |
snake.direction=direction_right; |
snake.x[0]=x; |
snake.y[0]=y; |
} |
/** |
根据随机产生的蛇的坐标绘制蛇 |
*/ |
void drawSnake(){ |
int i; |
for (i=0;i<snake.node;i++){ |
rectangle(snake.x[i],snake.y[i],snake.x[i]+rectangle_size,snake.y[i]+rectangle_size); |
} |
} |
/** |
根据指定的方向让蛇在该方向上移动。 |
1、需要擦除蛇身的最后一节,先保留住最后一节的x和y坐标,最后使用与背景色相同的颜色重新画最后一节 |
2、让蛇移动起来,相当于把蛇前面的坐标赋值给蛇后面节点,最后整条蛇重新绘制出来 |
*/ |
void snakeMove( int key){ |
int i; |
int x=snake.x[snake.node-1]; |
int y=snake.y[snake.node-1]; |
for (i=snake.node-1;i>0;i--){ |
snake.x[i]=snake.x[i-1]; |
snake.y[i]=snake.y[i-1]; |
} |
if (key==key_up&&(snake.direction==direction_left||snake.direction==direction_right)){ |
snake.direction=direction_up; |
} else if (key==key_down&&(snake.direction==direction_left||snake.direction==direction_right)){ |
snake.direction=direction_down; |
} else if (key==key_left&&(snake.direction==direction_down||snake.direction==direction_up)){ |
snake.direction=direction_left; |
} else if (key==key_right&&(snake.direction==direction_up||snake.direction==direction_down)){ |
snake.direction=direction_right; |
} |
if (snake.direction==direction_up){ |
snake.y[0]-=rectangle_size; |
} else if (snake.direction==direction_down){ |
snake.y[0]+=rectangle_size; |
} else if (snake.direction==direction_left){ |
snake.x[0]-=rectangle_size; |
} else if (snake.direction==direction_right){ |
snake.x[0]+=rectangle_size; |
} |
setcolor(9); |
rectangle(x, y,x+rectangle_size,y+rectangle_size); |
setcolor(14); |
drawSnake(); |
} |
/** |
判断用户按键后,是否需要把蛇换个方向 |
*/ |
int needToMove( int key){ |
if (snake.direction==key|| |
(snake.direction==direction_up&&key==direction_down)|| |
(snake.direction==direction_down&&key==direction_up)|| |
(snake.direction==direction_left&&key==direction_right)|| |
(snake.direction==direction_right&&key==direction_left)){ |
return 0; |
} |
return 1; |
} |
/** |
判断用户是否按的方向键 |
*/ |
int isDirectionKey( int key){ |
return (key==key_up||key==key_down||key==key_left||key==key_right)?1:0; |
} |
/** |
判断是否碰撞围墙,障碍物,蛇身,如果碰撞,则返回1 |
*/ |
int collision(){ |
int snakeRow=getRow(snake.y[0]); |
int snakeCol=getCol(snake.x[0]); |
int snakeRow1=getRow(snake.y[1]); |
int snakeCol1=getCol(snake.x[1]); |
if ((canvas[snakeRow][snakeCol]==WALL||canvas[snakeRow1][snakeCol1]==WALL)|| |
(canvas[snakeRow][snakeCol]==BARRIER_RECT||canvas[snakeRow1][snakeCol1]==BARRIER_RECT)|| |
(canvas[snakeRow][snakeCol]==BARRIER_CIRCLE||canvas[snakeRow1][snakeCol1]==BARRIER_CIRCLE)||bitSelf()){ |
return 1; |
} |
return 0; |
} |
/** |
通过y坐标获取该格子的行索引 |
*/ |
int getRow( int y){ |
return (y-canvas_min_y)/10; |
} |
/** |
通过x坐标获取该格子的列索引 |
*/ |
int getCol( int x){ |
return (x-canvas_min_x)/10; |
} |
/** |
吃到食物,蛇身变长,分数增加,重新出现食物 |
*/ |
void bitFood(){ |
int foodRow=getRow(food.y); |
int foodCol=getCol(food.x); |
int snakeRow=getRow(snake.y[0]); |
int snakeCol=getCol(snake.x[0]); |
int snakeRow1=getRow(snake.y[1]); |
int snakeCol1=getCol(snake.x[1]); |
if (foodRow==snakeRow&&foodCol==snakeCol||foodRow==snakeRow1&&foodCol==snakeCol1){ |
snake.score+=10; |
setfillstyle(1,9); |
bar(food.x,food.y,food.x+rectangle_size,food.y+rectangle_size); |
initFood(); |
snake.x[snake.node]=snake.x[snake.node-1]; |
snake.y[snake.node]=snake.y[snake.node-1]; |
snake.node+=1; |
printScore(); |
} |
} |
/** |
判断是否碰撞蛇本身 |
*/ |
int bitSelf(){ |
int i; |
if (snake.node<5){ |
return 0; |
} |
for (i=5;i<snake.node;i++){ |
if (snake.x[0]==snake.x[i]&&snake.y[0]==snake.y[i]){ |
return 1; |
} |
} |
return 0; |
} |
/** |
在游戏界面打印分数 |
*/ |
void printScore(){ |
char score[20]; |
setcolor(9); |
outtextxy(400,20,lastScore); |
sprintf (score, "Score: %d" ,snake.score); |
strcpy (lastScore,score); |
setcolor(14); |
outtextxy(400,20,score); |
} |
void gameOver(){ |
cleardevice(); |
settextstyle(0,0,4); |
outtextxy(150,150, "Game Over!" ); |
outtextxy(180,250,lastScore); |
} |
/** |
显示游戏结束画面 |
*/ |
void ccl(){ |
int i,j; |
for (i=0;i<TOTAL_ROWS;i++){ |
for (j=0;j<TOTAL_COLS;j++){ |
canvas[i][j]=EMPTY; |
} |
} |
cleardevice(); |
} |
中级程序员
by: Andy_Victory 发表于:2016-09-25 11:25:19 顶(0) | 踩(0) 回复
请问楼主 "graphics.h" 这个和snake_07.h 里面是啥啊?
回复评论