详解C语言实现推箱子的基本功能(2)

 更新时间:2022年02月18日 15:28:47   作者:D_eretay  
这篇文章主要为大家详细介绍了C语言实现推箱子的基本功能的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

1.前言

本文章将承接着上面的文章(上篇文章的地址),继续对推箱子的代码进行修改和完善,对上面杂乱的代码进行修改成函数。

2.地图代码修改成函数

注意:每次打印地图的时候要在前面加入system("cls")语句来清除刷新地图,该方法需要用到#include <Windows.h>的头文件。

对上篇文章的推箱子的地图代码进行函数封装,成果如下:

void drawMap() 
{ 
    system("CLS"); 
    // 使用循环,遍历数组(将游戏数据图形化) 
    for (size_t i = 0; i < 10; i++) 
    { 
        for (size_t j = 0; j < 10; j++) 
        { 
            /*printf("%2d", map[i][j]);*/ 
            switch (map[i][j]) 
            {
                case 0: 
                    printf(" "); // 两个空格 
                    break; 
                case 1: 
                    printf("█"); 
                    break; 
                case 2: 
                    printf("♀"); 
                    break; 
                case 3: 
                    printf("●"); 
                    break; 
                case 4: 
                    printf("☆"); 
                    break; 
                default: 
                    break; 
                } 
        }
        printf("\n"); 
    } 
}

而存储地图的地方可以放在主函数体外面来进行声明。

在这之后如果推到成功点和人走到成功点上仅需要加上case 2+4和case 3+4两个条件即可,具体代码如最后源码所示。

3.角色移动修改成函数

对角色移动的函数我们需要分为2个函数,一个是来控制角色移动的函数,另一个则是来寻找角色所在位置的坐标。

3.1寻找角色函数

在该函数中,我们需要对寻找角色,以及判断箱子能否推动做两个功能封装为一个函数,在该函数中,我们要先找到角色的位置,然后对移动的位置进行判断。

// 移动逻辑 参数:int X,int Y X和Y方向的偏移量 
void move(int X,int Y) 
{ 
    // 1 找人 
    int posX = 0, posY = 0; 
    for (size_t i = 0; i < 10; i++) 
    { 
        for (size_t j = 0; j < 10; j++) 
        { 
            if (2 == map[i][j] || 2 + 4 == map[i][j]) 
            { 
                posX = i; 
                posY = j; 
                break; 
            }
        } 
    }
    // 空地或成功点 map[posX][posY]:主角所在的位置 
    if (0 == map[posX + X][posY + Y] || 4 == map[posX + X][posY + Y]) 
    { 
    map[posX][posY] -= 2; 
    map[posX + X][posY + Y] += 2; 
    }
    // 箱子(将箱子从点上推走) 
    else if (3 == map[posX + X][posY + Y] || 3 + 4 == map[posX + X][posY + Y]) 
    { 
        // 箱子上面是空地或成功点 map[posX - 1][posY]: 箱子位置 
        if (0 == map[posX + (X * 2)][posY + (Y * 2)] || 4 == map[posX + (X * 2)] [posY + (Y * 2)]) 
        { 
            // 当前位置人离开 
            map[posX][posY] -= 2; 
            map[posX + X][posY + Y] += 2; 
            map[posX + X][posY + Y] -= 3; 
            map[posX + (X * 2)][posY + (Y * 2)] += 3; 
        } 
    } 
}

3.2角色移动函数

该函数对键盘输入进行处理,并且通过传入2个参数来一次性对移动进行操作,不需要四个方向都需要在写一遍函数,以下写法可以防止用户开大写而移动不了角色。

void heroMove() 
{ 
    // 控制人物移动 
    // 2 控制(键盘:WSAD(上下左右)) 
    // 需要从键盘获取按键(字符) 
    switch (getch())
    {
        case 'w': 
        case 'W': 
            move(-1, 0); 
            break; 
        case 's': 
        case 'S': 
            move(1, 0); 
            break; 
        case 'a': 
        case 'A': 
            move(0, -1); 
            break; 
        case 'd': 
        case 'D': 
            move(0, 1); 
            break; 
        default: 
            break; 
    } 
}

4.判断胜利修改成函数

这里用到了C++的bool类型,c语言也是可以使用,如果不想用这种函数,改成int也是可以使用的。

bool isWin() 
{ 
    for (size_t i = 0; i < 10; i++) 
    { 
        for (size_t j = 0; j < 10; j++) 
        { 
            if (map[i][j] == 3) 
            { 
                return false; 
            } 
        } 
    }
    return true;
}

5.主体函数的实现

这里的思想是,先绘制地图,然后对移动进行判断,直到判断所有的箱子没有后,判定玩家胜利。

int main() 
{ 
    while (!isWin()) // 游戏主循环 
    { 
        drawMap(); 
        heroMove(); 
    }
    drawMap(); 
    return 0; 
}

6.推箱子能实现基本功能的源码

#include <stdio.h> 
#include <conio.h> 
#include <Windows.h> 
char map[10][10] = 
{ 
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 1 }, 
    { 1, 0, 0, 0, 0, 1, 4, 0, 0, 1 }, 
    { 1, 0, 0, 4, 0, 1, 1, 0, 0, 1 }, 
    { 1, 0, 0, 3, 0, 1, 0, 0, 0, 1 }, 
    { 1, 0, 0, 2, 0, 0, 0, 0, 0, 1 },
    { 1, 1, 1, 1, 0, 0, 3, 0, 0, 1 }, 
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, 
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } 
};
/* 函数声明 */ 
void drawMap(); 
void heroMove(); 
void move(int X, int Y); 
bool isWin();
int main() 
{ 
    while (!isWin()) // 游戏主循环 
    { 
        drawMap(); 
        heroMove(); 
    }
    drawMap(); 
    return 0; 
}
/* 函数定义 */ 
// 绘制地图 
void drawMap() 
{ 
    system("CLS"); 
    // 使用循环,遍历数组(将游戏数据图形化) 
    for (size_t i = 0; i < 10; i++) 
    { 
        for (size_t j = 0; j < 10; j++) 
        { 
            /*printf("%2d", map[i][j]);*/ 
            switch (map[i][j]) 
            {
                case 0: 
                    printf(" "); // 两个空格 
                    break; 
                case 1: 
                    printf("█"); 
                    break; 
                case 2: 
                    printf("♀"); 
                    break; 
                case 3: 
                    printf("●"); 
                    break; 
                case 4: 
                    printf("☆"); 
                    break; 
                case 2 + 4: 
                    printf("♀");
                    break; 
                case 3 + 4: 
                    printf("★"); 
                    break; 
                default: 
                    break; 
                } 
        }
        printf("\n"); 
    } 
}
void heroMove() 
{ 
    // 控制人物移动 
    // 2 控制(键盘:WSAD(上下左右)) 
    // 需要从键盘获取按键(字符) 
    switch (getch())
    {
        case 'w': 
        case 'W': 
            move(-1, 0); 
            break; 
        case 's': 
        case 'S': 
            move(1, 0); 
            break; 
        case 'a': 
        case 'A': 
            move(0, -1); 
            break; 
        case 'd': 
        case 'D': 
            move(0, 1); 
            break; 
        default: 
            break; 
    } 
}
// 移动逻辑 参数:int X,int Y X和Y方向的偏移量 
void move(int X,int Y) 
{ 
    // 1 找人 
    int posX = 0, posY = 0; 
    for (size_t i = 0; i < 10; i++) 
    { 
        for (size_t j = 0; j < 10; j++) 
        { 
            if (2 == map[i][j] || 2 + 4 == map[i][j]) 
            { 
                posX = i; 
                posY = j; 
                break; 
            }
        } 
    }
    // 空地或成功点 map[posX][posY]:主角所在的位置 
    if (0 == map[posX + X][posY + Y] || 4 == map[posX + X][posY + Y]) 
    { 
    map[posX][posY] -= 2; 
    map[posX + X][posY + Y] += 2; 
    }
    // 箱子(将箱子从点上推走) 
    else if (3 == map[posX + X][posY + Y] || 3 + 4 == map[posX + X][posY + Y]) 
    { 
        // 箱子上面是空地或成功点 map[posX - 1][posY]: 箱子位置 
        if (0 == map[posX + (X * 2)][posY + (Y * 2)] || 4 == map[posX + (X * 2)] [posY + (Y * 2)]) 
        { 
            // 当前位置人离开 
            map[posX][posY] -= 2; 
            map[posX + X][posY + Y] += 2; 
            map[posX + X][posY + Y] -= 3; 
            map[posX + (X * 2)][posY + (Y * 2)] += 3; 
        } 
    } 
}
//判断胜利
bool isWin() 
{ 
    for (size_t i = 0; i < 10; i++) 
    { 
        for (size_t j = 0; j < 10; j++) 
        { 
            if (map[i][j] == 3) 
            { 
                return false; 
            } 
        } 
    }
    return true;
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!   

相关文章

  • C语言 Freertos的递归锁详解

    C语言 Freertos的递归锁详解

    这篇文章主要为大家详细介绍了C语言的递归锁,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Qt模仿Visual Studio停靠窗口效果

    Qt模仿Visual Studio停靠窗口效果

    这篇文章主要介绍了如何利用Qt制作与Visual Studio相似的带有停靠方向标及停靠区域预览的停靠窗口框架,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2022-01-01
  • 详解C++中赋值和输入输出语句的用法

    详解C++中赋值和输入输出语句的用法

    这篇文章主要介绍了详解C++中赋值和输入输出语句的用法,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • visual studio 2022中的scanf问题解决

    visual studio 2022中的scanf问题解决

    昨天在使用Visual Studio 2022编写C语言程序时遇到了scanf问题,对于vs的编译器来说scanf是不安全的,编译器通过不了scanf,本文就来介绍一下解决方法,感兴趣的可以了解一下
    2023-12-12
  • C++ 中构造函数的实例详解

    C++ 中构造函数的实例详解

    这篇文章主要介绍了C++ 中构造函数的实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • C++面试常见问题整理汇总

    C++面试常见问题整理汇总

    这篇文章主要介绍了C++面试常见问题整理,汇总了C++基本语法、面向对象各种概念与易错点,需要的朋友可以参考下
    2017-05-05
  • 详解C语言中strcpy函数与memcpy函数的区别与实现

    详解C语言中strcpy函数与memcpy函数的区别与实现

    这篇文章主要介绍了C语言中字符串拷贝函数(strcpy)与内存拷贝函数(memcpy)的不同及内存拷贝函数的模拟实现,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-12-12
  • c语言枚举类型enum的用法及应用实例

    c语言枚举类型enum的用法及应用实例

    enum是C语言中的一个关键字,enum叫枚举数据类型,枚举数据类型描述的是一组整型值的集合,这篇文章主要给大家介绍了关于c语言枚举类型enum用法及应用的相关资料,需要的朋友可以参考下
    2021-07-07
  • C语言中结构体与内存对齐实例解析

    C语言中结构体与内存对齐实例解析

    C语言结构体对齐也是老生常谈的话题了,基本上是面试题的必考题,这篇文章主要给大家介绍了关于C语言中结构体与内存对齐的相关资料,需要的朋友可以参考下
    2021-07-07
  • 五个经典链表OJ题带你进阶C++链表篇

    五个经典链表OJ题带你进阶C++链表篇

    做题之前呢,小编想提醒下大家,要三思而后行,不要一上来就嘎嘎敲代码,要先学会自己画图分析,把自己的思路捋清楚,不要到时候写代码五分钟,调试两小时,记住,编程思路很重要
    2022-03-03

最新评论