您的位置:首页 > 编程语言 > C语言/C++

学习ios第八天 番外篇 《c语言小游戏 推箱子的实现》

2015-09-18 18:08 671 查看
技术交流QQ:3123905931

一、创建游戏地图

define ROWS 11

define COLS 12

char map[ROWS][COLS] = {

“###########”,

“# #”,

“#O #”,

“# X# # @#”,

“# # # #”,

“# # # #”,

“# # # #”,

“# #”,

“# #”,

“###########”

};

因为推箱子游戏地图是由多个格子组成的,所以我们可以使用二维字符数组或字符串数组创建地图。我们可以改变数组中的元素来对游戏功能进行实现。例如:小人移动方向无障碍物,就是小人原来位置的数组元素设置为路,移动后的元素设置为小人。这样就实现了小人移动功能,箱子也是同理。

二、初始化位置和游戏开关

//游戏开关

int flag = 1;

//人的坐标

int renRows = 2;

int renCols = 1;

//箱子的坐标

int xiangRows = 3;

int xiangCols = 2;

因为整个游戏操作都是放在循环里的,所以我们先定义一个全局开关,然后用while(开关)来控制游戏的结束。并且在判断用户输入方向前,我们需要先确定小人和箱子的初始位置,再根据用户输入进行判断。

三、接收用户输入方向

printf(“W.前 S.后 A.左 D.右 Q.退出\n”);

char enterInput = ‘a’;

rewind(stdin);

//接收键盘方向

scanf(“%c”,&enterInput);

接收用户从键盘输入的字符,由于方向4个,加上退出功能就5个分支。所以我们使用switch case结构来实现判断用户输入字符,并执行一些操作。

四、判断用户输入方向

[code]    //初始化人和箱子的下一个坐标
    int nextRows = 0,nextCols = 0,nextXiangRows = 0,nextXiangCols = 0;

    //判断方向并操作
    switch (enterInput) {
        case 'w':
        case 'W':{
            nextRows = renRows - 1;
            nextCols = renCols;
            nextXiangRows = xiangRows - 1;
            nextXiangCols = xiangCols;
            //调用移动函数
            moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
        }
            break;
        case 's':
        case 'S':{
            nextRows = renRows + 1;
            nextCols = renCols;
            nextXiangRows = xiangRows + 1;
            nextXiangCols = xiangCols;
            //调用移动函数
            moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
        }
            break;
        case 'a':
        case 'A':{
            nextRows = renRows;
            nextCols = renCols - 1;
            nextXiangRows = xiangRows;
            nextXiangCols = xiangCols - 1;
            //调用移动函数
            moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
        }
            break;
        case 'd':
        case 'D':{
            nextRows = renRows;
            nextCols = renCols + 1;
            nextXiangRows = xiangRows;
            nextXiangCols = xiangCols + 1;
            //调用移动函数
            moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
        }
            break;
        case 'q':
        case 'Q':
            //如果输入Q则关闭游戏
            flag = 0;
            break;
        default:
            printf("输入错误\n");
            break;
    }


人下一个位置的行下标 nextRows

人下一个位置的列下标 nextCols

箱子下一个位置的行下标 nextXiangRows

箱子下一个位置的列下标 nextXiangCols

这里说的下一个位置就好比,我输入w后向上移动了一个位置,这个新的位置我称他为下一个位置。

如果向上移动,人和箱子的行下标-1,列下标不变。

如果向下移动,人和箱子的行下标+1,列下标不变。

如果向左移动,人和箱子的行下标不变,列下标-1。

如果向右移动,人和箱子的行下标不变,列下标+1。

我这里是先根据方向判断出人和箱子位置会发生的移动变化,并使用局部变量临时存储,所以不用担心人没有顶着箱子的时候,箱子也会跟着移动的问题。因为最终移动后的新位置坐标还是由全局变量来存储的,我只是根据用户输入方向计算出人和箱子下一个位置的新坐标,然后再根据实际情况(实际情况就是人前进方向是否是障碍物,还是箱子来确定的。如果是障碍物,就只有人移动,并只有人刷新位置。如果是箱子,则判断箱子下一个位置是否是障碍物,来刷新人和箱子的新位置)赋值给全局变量。

五、移动控制实现

void moveRen(int nextRows, int nextCols,int nextXiangRows,int nextXiangCols){

if (map[nextRows][nextCols] == ’ ‘) {

//如果人下一个位置是路

map[nextRows][nextCols] = ‘O’;//下一个位置设置为人

map[renRows][renCols] = ’ ‘;//人原来的位置设置为路

[code]    //刷新人的位置
    renRows = nextRows;
    renCols = nextCols;
}else if (map[nextRows][nextCols] == 'X' && map[nextXiangRows][nextXiangCols] != '#' && map[nextXiangRows][nextXiangCols] != '@'){
    //如果人下一个位置是箱子,并且箱子下一个位置不是墙也不是关卡
    map[nextRows][nextCols] = 'O';//下一个位置设置为人
    map[renRows][renCols] = ' ';//人原来的位置设置为路
    map[nextXiangRows][nextXiangCols] = 'X';//箱子下一个位置设置为箱子

    //刷新人和箱子的位置
    renRows = nextRows;
    renCols = nextCols;
    xiangRows = nextXiangRows;
    xiangCols = nextXiangCols;
}else if (map[nextXiangRows][nextXiangCols] == '@'){
    //如果箱子下一个位置是关卡,就过关
    printf("您已经过关!\n");
    flag = 0;
}


}

接下来是推箱子的源代码

[code]#include <stdio.h>
#include <stdlib.h>
#define ROWS 11
#define COLS 12

char map[ROWS][COLS] = {
    "###########",
    "#         #",
    "#O        #",
    "# X#  #  @#",
    "#  #  #   #",
    "#  #  #   #",
    "#  #  #   #",
    "#         #",
    "#         #",
    "###########"
};

//游戏开关
int flag = 1;

//人的坐标
int renRows = 2;
int renCols = 1;

//箱子的坐标
int xiangRows = 3;
int xiangCols = 2;

//移动小人
void moveRen(int nextRows, int nextCols,int nextXiangRows,int nextXiangCols);

int main(int argc, const char * argv[]) {

    while (flag) {
        system("clear");
        //刷新地图
        for (int i = 0; i < ROWS; i++) {
            printf("%s\n",map[i]);
        }

        printf("W.前  S.后  A.左  D.右  Q.退出\n");
        char enterInput = 'a';
        rewind(stdin);
        //接收键盘方向
        scanf("%c",&enterInput);

        //初始化人和箱子的下一个坐标
        int nextRows = 0,nextCols = 0,nextXiangRows = 0,nextXiangCols = 0;

        //判断方向并操作
        switch (enterInput) {
            case 'w':
            case 'W':{
                nextRows = renRows - 1;
                nextCols = renCols;
                nextXiangRows = xiangRows - 1;
                nextXiangCols = xiangCols;
                //调用移动函数
                moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
            }
                break;
            case 's':
            case 'S':{
                nextRows = renRows + 1;
                nextCols = renCols;
                nextXiangRows = xiangRows + 1;
                nextXiangCols = xiangCols;
                //调用移动函数
                moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
            }
                break;
            case 'a':
            case 'A':{
                nextRows = renRows;
                nextCols = renCols - 1;
                nextXiangRows = xiangRows;
                nextXiangCols = xiangCols - 1;
                //调用移动函数
                moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
            }
                break;
            case 'd':
            case 'D':{
                nextRows = renRows;
                nextCols = renCols + 1;
                nextXiangRows = xiangRows;
                nextXiangCols = xiangCols + 1;
                //调用移动函数
                moveRen(nextRows,nextCols,nextXiangRows,nextXiangCols);
            }
                break;
            case 'q':
            case 'Q':
                //如果输入Q则关闭游戏
                flag = 0;
                break;
            default:
                printf("输入错误\n");
                break;
        }
    }
    return 0;
}

//移动小人
void moveRen(int nextRows, int nextCols,int nextXiangRows,int nextXiangCols){
    if (map[nextRows][nextCols] == ' ') {
        //如果人下一个位置是路
        map[nextRows][nextCols] = 'O';//下一个位置设置为人
        map[renRows][renCols] = ' ';//人原来的位置设置为路

        //刷新人的位置
        renRows = nextRows;
        renCols = nextCols;
    }else if (map[nextRows][nextCols] == 'X' && map[nextXiangRows][nextXiangCols] != '#' && map[nextXiangRows][nextXiangCols] != '@'){
        //如果人下一个位置是箱子,并且箱子下一个位置不是墙也不是关卡
        map[nextRows][nextCols] = 'O';//下一个位置设置为人
        map[renRows][renCols] = ' ';//人原来的位置设置为路
        map[nextXiangRows][nextXiangCols] = 'X';//箱子下一个位置设置为箱子

        //刷新人和箱子的位置
        renRows = nextRows;
        renCols = nextCols;
        xiangRows = nextXiangRows;
        xiangCols = nextXiangCols;
    }else if (map[nextXiangRows][nextXiangCols] == '@'){
        //如果箱子下一个位置是关卡,就过关
        printf("您已经过关by  bruceyou 2015 9 18!\n");
        flag = 0;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: