用户注册



邮箱:

密码:

用户登录


邮箱:

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

发表随想


还能输入: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、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

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

加载中,请稍后...