用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - c++代码库

贪吃蛇(其中"snake_07.h"是一个自定义的头文件,要求自己把头文件放置)

2016-05-12 作者: 夜丶微凉举报

[c++]代码库

#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();
}

[源代码打包下载]




网友评论    (发表评论)

共2 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...