C语言基础入门48篇_31_二维数组应用之游戏中的碰撞检测(二维数组初始化边界,利用边界值判断是否可移动)

本篇在上篇C语言基础入门48篇_18_使用循环移动游戏人物(屏幕符号运动、while(1){}进行实时响应,if(表达式){},switch(表达式){},windows的API及API进行自行封装使)的基础上增加了移动边界,并且游戏人物不会移动出所设计的边界。

1. 没有碰撞检测的版本

#include <windows.h>
#include <conio.h>
#include <stdio.h>

void MoveCursorTo(int nRow, int nCol)
{
    COORD crdLocation;
    crdLocation.X = 2*nCol;
    crdLocation.Y = nRow;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), crdLocation);
}

char g_chBackground[20][20] = { 0 };

void InitBackGround()
{
    for (size_t nRow = 0; nRow < 20; nRow++)
    {
        for (size_t nCol = 0; nCol < 20; nCol++)
        {
            if (nRow == 0
                || nCol == 0
                || nRow == 19
                || nCol == 19)
            {
                g_chBackground[nRow][nCol] = 1;
            }
            else
            {
                g_chBackground[nRow][nCol] = 0;
            }
        }
    }
}

void ShowBackGround()
{
    for (size_t nRow = 0; nRow < 20; nRow++)
    {
        for (size_t nCol = 0; nCol < 20; nCol++)
        {
            if (g_chBackground[nRow][nCol] == 1)
            {
                MoveCursorTo(nRow, nCol);
                printf("■");
            }
            else
            {
                
            }
        }
    }
}

void ClearPlayer(int nRow, int nCol)
{
    MoveCursorTo(nRow, nCol);
    printf(" ");
}
void ShowPlayer(int nRow, int nCol)
{
    MoveCursorTo(nRow, nCol);
    printf("×");
}

int main(int argc, char* argv[])
{
    char chInput = 0;

    InitBackGround();
    ShowBackGround();

    int nRow = 10;
    int nCol = 10;

    ShowPlayer(nRow, nCol);

    while (1)
    {
        if (_kbhit() != 0)
        {
            chInput = _getch();
            switch (chInput)
            {
            case 'a':
                ClearPlayer(nRow, nCol);
                nCol -= 1;
                ShowPlayer(nRow, nCol);
                break;
            case 'w':
                ClearPlayer(nRow, nCol);
                nRow -= 1;
                ShowPlayer(nRow, nCol);
                break;
            case 's':
                ClearPlayer(nRow, nCol);
                nRow += 1;
                ShowPlayer(nRow, nCol);
                break;
            case 'd':
                ClearPlayer(nRow, nCol);
                //改变坐标并移动、打印
                nCol += 1;
                ShowPlayer(nRow, nCol);
                break;
            default:
                break;
            }
        }

    }

    return 0;
}

运行结果:存在移动边界,但是人物可以越过边界
在这里插入图片描述

2. 有碰撞检测的版本

#include <windows.h>
#include <conio.h>
#include <stdio.h>

void MoveCursorTo(int nRow, int nCol)
{
    COORD crdLocation;
    crdLocation.X = 2*nCol;
    crdLocation.Y = nRow;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), crdLocation);
}

char g_chBackground[20][20] = { 0 };
//判断移动后的位置为1,代表到达边界,不可移动
int IsCanMove(int nToRow, int nToCol)
{
    if (g_chBackground[nToRow][nToCol] == 1)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}
//程序背景对一个二维数据的第0列和最后1列,第0行和最后1行进行赋值为1
//其他地方赋值为0,即可实现一个方框边缘的目的
void InitBackGround()
{
    for (size_t nRow = 0; nRow < 20; nRow++)
    {
        for (size_t nCol = 0; nCol < 20; nCol++)
        {
            if (nRow == 0
                || nCol == 0
                || nRow == 19
                || nCol == 19)
            {
                g_chBackground[nRow][nCol] = 1;
            }
            else
            {
                g_chBackground[nRow][nCol] = 0;
            }
        }
    }
}

//遍历二维数组,为1的初始化为方格
void ShowBackGround()
{
    for (size_t nRow = 0; nRow < 20; nRow++)
    {
        for (size_t nCol = 0; nCol < 20; nCol++)
        {
            if (g_chBackground[nRow][nCol] == 1)
            {
                MoveCursorTo(nRow, nCol);//坐标移动到对应的行列
                printf("■");
            }
            else
            {
                
            }
        }
    }
}
//清除轨迹,利用空格覆盖x
void ClearPlayer(int nRow, int nCol)
{
    MoveCursorTo(nRow, nCol);
    printf(" ");
}
void ShowPlayer(int nRow, int nCol)
{
    MoveCursorTo(nRow, nCol);
    printf("×");
}

int main(int argc, char* argv[])
{
    char chInput = 0;

    InitBackGround();
    ShowBackGround();

    int nRow = 10;
    int nCol = 10;

    ShowPlayer(nRow, nCol);

    while (1)
    {
        if (_kbhit() != 0)
        {
            chInput = _getch();
            switch (chInput)
            {
            case 'a':
                if (IsCanMove(nRow, nCol - 1))
                {
                    ClearPlayer(nRow, nCol);
                    nCol -= 1;
                    ShowPlayer(nRow, nCol);
                }
                break;
            case 'w':
                if (IsCanMove(nRow - 1, nCol))
                {
                    ClearPlayer(nRow, nCol);
                    nRow -= 1;
                    ShowPlayer(nRow, nCol);
                }
                break;
            case 's':
                if (IsCanMove(nRow + 1, nCol))
                {
                    ClearPlayer(nRow, nCol);
                    nRow += 1;
                    ShowPlayer(nRow, nCol);
                }
                break;
            case 'd':
                if (IsCanMove(nRow, nCol + 1))
                {
                    ClearPlayer(nRow, nCol);
                    //改变坐标并移动、打印
                    nCol += 1;
                    ShowPlayer(nRow, nCol);
                }
                break;
            default:
                break;
            }
        }

    }

    return 0;
}

运行结果:存在移动边界,但是人物不可以越过边界
在这里插入图片描述
3.学习视频地址:二维数组应用之游戏中的碰撞检测

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值