本篇在上篇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.学习视频地址:二维数组应用之游戏中的碰撞检测