目录
前言
大家可以先关注一波,后续继续更新各种技术免费专栏,涉及数据结构与算法,c/c++ QT/duilib等客户端开发,服务器开发,音视频开发,驱动开发,逆向安全,游戏开发等等有关技术栈,还有各种热门编程技术如rust, java,go, javascript, python, php, c#等等,遍及各种平台如android, ios, windows, unix, linux等等,让新手从入门到实战,从IT学习者身份顺利过渡到职场人士 。
一、项目概述
1.1 项目目标
为了巩固之前学习的C语言知识点,提高C语言的实践能力,锻炼逻辑思维。相信大家都玩过坦克移动射击类游戏,本节我们一起来学习用C语言实现一个坦克大战小游戏。
1.2 游戏功能说明
游戏菜单选项:
1、开始游戏
2、自定义地图进行游戏
3、观看游戏操作说明
4、退出游戏
操作说明:
游戏中英文输入状态下w,s,a,d按键分别控制坦克的上下左右。
游戏中按f键攻击,按p键暂停,按空格键开始。
编辑地图中按四个箭头移动光标,t、g、r键分别创建土墙,钢墙和擦除,按空格键则结束编辑开始游戏。
游戏说明:
游戏中有土墙和钢墙,土墙可以被破坏,钢墙不能被破坏,我方坦克有生命值10,消灭一辆坦克积分加100,消灭10辆敌军坦克赢得游戏,或者自己生命值为零则结束游戏。敌军可以随机开炮移动,碰障碍物不能前进,子弹也可以互相碰撞等。详见游戏。
1.3 开发环境及工具
windows + vs + C语言
二、游戏逻辑设计
2.1 显示输出
我们一般使用printf打印字符出现显示,结合一些windows控制台API来控制窗口大小标题,鼠标的显示颜色样式位置,文本的颜色等。如下是一些可能用到的API,具体用处可以参考MSDN文档:
SetConsoleTitle 设置控制台窗口标题
GetStdHandle 获取控制台操作句柄
GetLargestConsoleWindowSize 获取最大控制台窗口大小
SetConsoleScreenBufferSize 设置控制台缓冲区大小
SetConsoleWindowlnfo 设置控制台窗口大小
SetConsoleScreenBufferSize 设置控制台缓冲区大小
SetConsoleCursorlnfo 设置光标信息
SetConsoleTextAttribute 设置控制台文本属性
SetConsoleCursorPosition 设置控制台光标位置
SetConsoleMode 设置控制台模式 支持鼠标或者键盘响应等
ReadConsoleInput 读取控制台输入信息 读取鼠标和键盘等输入信息
system("mode con cols=90 lines=45") windows命令提示符
mode
是一个Windows命令,用于获取或设置控制台窗口的属性。con
是控制台窗口的别名。cols
和 lines
分别用于设置窗口的列数和行数。
绘制功能 Draw.h
#pragma once
void WelcomeScreen();
void printBorder();
void printInstru();
void printBase();//打印基地
void printExist();//打印地图所有物
void printTank(Object* tank);//打印坦克
void clearTank(Object* tank);//清除坦克
void printBullet();//打印自己的子弹
void printBadBullet(Object* badBullet);//打印敌人子弹
void clearBullet(Object* object);//清除自己子弹
void clearBadBullet(int x, int y);//清除敌人坦克的子弹
void printScoreboard();
Draw.c
#include"stdio.h"
#include"stdlib.h"
#include"windows.h"
#include"TankGame.h"
#include"Utils.h"
#include"editMap.h"
#include"Draw.h"
void WelcomeScreen() {
setEnglish();
system("cls");
gotoXY(20,5);
color(14);
printf(" 〓██▄▄▄▄▄▄\n");
gotoXY(20, 6);
printf(" ▄▅██████▅▄▃▂\n");
gotoXY(20, 7);
printf("██████████████\n");
gotoXY(20, 8);
printf("◥⊙▲⊙▲⊙▲⊙▲⊙▲⊙▲◤\n");
gotoXY(20, 10);
printf("1、开始游戏\n");
gotoXY(20, 11);
printf("2、编辑地图\n");
gotoXY(20, 12);
printf("3、操作说明\n");
gotoXY(20, 13);
printf("4、退出游戏\n");
gotoXY(20, 14);
printf("请输入您的操作选项:");
int flag = 1;
char operate;
while(flag) {
operate = getchar();
switch (operate) {
case '1':startGame(); flag = 0; break;
case '2':edit_map(); flag = 0; break;
case '3':printInstru(); flag = 0; break;
case '4':exit(0); flag = 0; break;
default:printf("输入错误,请重新输入:");break;
}
}
}
//打印操作说明
void printInstru() {
system("cls");
gotoXY(20,10);
printf("游戏中wsad按键分别控制坦克的上下左右");
gotoXY(20, 12);
printf(" 游戏中f键攻击,p键暂停,空格键开始 ");
gotoXY(1, 14);
printf("编辑地图中按四个箭头移动光标,t、g、r键分别创建土墙,钢墙和擦除,空格键则结束编辑开始游戏");
gotoXY(20, 16);
system("pause");
getchar();
WelcomeScreen();
}
//打印围墙
void printBorder() {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),15);//白色
printf("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\n");
for (int i = 0; i<38; i++)
printf("■ ■\n");
printf("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\n");
}
void printBase() {
for (int i = 0; i < 3; i++) //打印基地
for (int j = 0; j < 3; j++)
{
if (base.Shape[i][j] == 2) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 9);
gotoXY(36 + 2 * j, 36 + i);
printf("■");
}
else {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
gotoXY(36 + 2 * j, 36 + i);
printf("■");
}
}
}
void printExist() {
for (int j = 0; j < 38; j++)
for (int i = 0; i < 38; i++)
if (existence[i][j] == 3)//土墙
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
gotoXY(2 + 2 * j, 1 + i);
printf("■");
}
else if (existence[i][j] == 4)钢墙
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
gotoXY(2 + 2 * j, 1 + i);
printf("■");
}
}
//打印坦克
void printTank(Object* tank) {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
if (tank->Shape[i][j] == 2 && tank->Camp == 2)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);// 红色
gotoXY(2 * tank->CoordX + 2 * j - 2, tank->CoordY + i - 1);
printf("■");
}
if (tank->Shape[i][j] == 2 && tank->Camp == 1)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 9);//淡蓝色
gotoXY(2 * tank->CoordX + 2 * j - 2, tank->CoordY + i - 1);
printf("■");
}
}
}
void clearTank(Object* tank) {
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
{
gotoXY(2 * tank->CoordX + 2 * j - 2, tank->CoordY + i - 1);
printf(" ");
}
}
//打印自己的子弹
void printBullet() {
for (int i = 0; i < 50; i++) {
if (ownBullet[i].CoordX != 0 && ownBullet[i].CoordY != 0) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 6);
gotoXY(ownBullet[i].CoordX * 2, ownBullet[i].CoordY);
ownBullet[i].ID = i;
printf("◎");
}
}
}
//打印敌人子弹
void printBadBullet(Object* badBullet) {
if (badBullet->CoordX != 0 && badBullet->CoordY != 0) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 6);
if (badBullet->CoordX * 2 < 80) {
gotoXY(badBullet->CoordX * 2, badBullet->CoordY);
printf(" ");
}
gotoXY(badBullet->CoordX * 2, badBullet->CoordY);
printf("◎");
}
}
//打印计分
void printScoreboard() {
gotoXY(5 * 2, 41);
printf(" ");
gotoXY(10 * 2, 41);
printf(" ");
gotoXY(5 * 2, 41);
printf("score: %d", score);
gotoXY(12 * 2, 41);
printf("HP: %d", ownTank.HealthPoint);
}
//清除自己的子弹
void clearBullet(Object* object) {
for (int i = 0; i < 50; i++) {
if (object[i].CoordX != 0 && object[i].CoordY != 0) {
gotoXY(object[i].CoordX * 2, object[i].CoordY);
printf(" ");
}
}
}
//清除敌方坦克子弹
void clearBadBullet(int x, int y) {
if (x != 0 && y != 0)
{
gotoXY(2 * x, y);
printf(" ");
}
}
工具类实现
Utils.h
#pragma once
void PrintChar(int Wide, int High, char* pszChar, int color);
void setEnglish();
void gotoXY(int x, int y);
void hideCursor();
void color(int a);
Utils.c
#include"stdio.h"
#include"stdlib.h"
#include"windows.h"
#include"string.h"
void PrintChar(int Wide, int High, char* pszChar, int color) {//定位光标位置并打印
CONSOLE_CURSOR_INFO cci;
cci.dwSize = 1;
cci.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
COORD loc;
loc.X = Wide * 2;
loc.Y = High;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), loc);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
printf(pszChar);
}
void setEnglish() { //输入法切换为英文输入状态
keybd_event(VK_SHIFT, 0, 0, 0);
Sleep(100);
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
}
void hideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void gotoXY(int x, int y) //设定输出位置
{
COORD c; //光标位置
c.X = x;
c.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);//获取句柄,设置位置
hideCursor();//取消光标闪烁
}
void color(int a) //颜色函数
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), a);
}
2.2 用户输入
可能使用 C 库函数接收键盘输入的函数如
kbhit 键盘按下返回1,否则 0
getchar() 从键盘缓冲区获取字符 回显到屏幕
_getwch() (unicode版本)从键盘缓冲区获取字符 不回显到屏幕
_getch() 多字节版本
控制台API
GetStdHandle 获取控制台操作句柄,有输入输出,错误等句柄
SetConsoleMode 设置控制台模式 支持鼠标或者键盘响应输入等
ReadConsoleInput 读取控制台输入信息 读取鼠标和键盘等输入信息
使用windows API 异步判断哪个键盘键按下
#define KEYDOWN(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?1:0)
#define KEYUP(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?0:1)
2.3 数据部分设计
使用结构体位段来设计数据对象,以及使用简单的二维数组存储地图数据等。
TankGame.h
#pragma once
typedef struct _OBJECT {
unsigned int CoordX : 6; //物体中心点横坐标 //坦克取右下角为中心坐标
unsigned int CoordY : 6; //物体中心点纵坐标
unsigned int HealthPoint : 6; //生命值
unsigned int Direction : 3; //运动方向 1上2下3左4右
//unsigned int Collide:2; //碰撞体积
unsigned int ID : 8; //编号
unsigned int Type : 4; //对象类型 0空 1炮弹节点 2坦克节点 3土墙节点 4钢墙节点
unsigned int Camp : 2; //阵营 0中立 1友方 2敌方
unsigned int Shape[3][3]; //显示形状
int speed;//速度
}Object, *pObject;
extern int score; //游戏分数
extern int enemyCount;//敌人数量
extern int gameMap[40][40];//游戏地图
extern int existence[38][38];//地图存在物
extern Object base;//基地
extern Object ownTank;//自己的坦克
extern Object enemyTank[3];//敌人的坦克
extern Object ownBullet[50];//自己的子弹
extern Object enemyBullet[3];//敌人坦克的子弹
void initGame();//初始化游戏
int allowGo(Object* tank);//监测某位置能不能走
void turnUp(Object* tank);//转上后刷新
void turnDown(Object* tank);//转下后刷新
void turnLeft(Object* tank);//转左后刷新
void turnRight(Object* tank);//转右后刷新
void existChange();//监测地图所有物的改变
void baseChange();//监测基地的改变
void gameOver();//游戏结束之后的操作
void checkGame();//监测游戏是否结束
void getExistMap();//获得初始化所有物地图
void renewMap(); //刷新地图
void startGame(); //开始游戏
void stopGame(); //停止游戏
int isNull();//判断地图障碍物数组是否为空
TankGame.c
#include"stdio.h"
#include"stdlib.h"
#include"conio.h"
#include"Utils.h"
#include"windows.h"
#include"time.h"
#include"TankGame.h"
#include"Draw.h"
#include"Bullet.h"
#include"Tank.h"
int score; //游戏分数
int enemyCount;//敌人数量
int gameMap[40][40];//游戏地图
int existence[38][38];//地图存在物
Object base;//基地
Object ownTank;//自己的坦克
Object enemyTank[3];//敌人的坦克
Object ownBullet[50];//自己的子弹
Object enemyBullet[3];//敌人坦克的子弹
void initGame() {
enemyCount = 10;
score = 0;
//自己坦克的初始化
ownTank.Camp = 1;
ownTank.speed = 100;
ownTank.CoordX = 6;
ownTank.CoordY = 37;
ownTank.Direction = 0;
ownTank.HealthPoint = 10;
//敌方坦克的初始化
for (int i = 0; i < 3; i++) {
enemyTank[i].CoordX = 2 + i * 15;
enemyTank[i].CoordY = 2;
enemyTank[i].Direction = 0;
enemyTank[i].speed = 400;
enemyTank[i].Camp = 2;
}
int _base[3][3] = { { 3,3,3 },{ 3,2,3 },{ 3,2,3 } };
for (int i = 0; i < 3; i++)//基地初始化
for (int j = 0; j < 3; j++)
base.Shape[i][j] = _base[i][j];
//自己子弹初始化
for (int i = 0; i < 50; i++) {
ownBullet[i].CoordX = 0;
ownBullet[i].CoordY = 0;
ownBullet[i].Direction = 0;
}
//敌方坦克子弹的初始化
for (int i = 0; i < 3;i++) {
enemyBullet[i].CoordX = 0;
enemyBullet[i].CoordY = 0;
enemyBullet[i].Direction = 0;
}
for (int i = 1; i < 39; i++)//地图清屏
for (int j = 1; j < 39; j++)
{
gotoXY(2 * i, j);
printf(" ");
}
if (isNull()==1) {
getExistMap();
}
renewMap();
printBase();
printExist();
printScoreboard();
turnUp(&ownTank);
turnDown(&enemyTank[0]);
turnDown(&enemyTank[1]);
turnDown(&enemyTank[2]);
}
int isNull() {
for (int i = 0; i < 38; i++) {
for (int j = 0; j < 38; j++) {
if (existence[i][j] != 0) {
return 0;
break;
}
}
}
return 1;
}
void stopGame() {
int flag = 0;
char key;
while (1)
{
for (int i = 0; i < 50; i++)
{
Sleep(2000);
if (_kbhit()) //检测
{
key = _getch();//捕获按键
if (key == 32)
{
flag = 1;
break;
}
}
if (flag)
break;
}
if (flag)
break;
}
}
//判断该方向能不能前进
int allowGo(Object* tank) {
switch (tank->Direction)
{
case 1:
if (gameMap[tank->CoordY - 2][tank->CoordX] == 0 &&
gameMap[tank->CoordY - 2][tank->CoordX - 1] == 0 &&
gameMap[tank->CoordY - 2][tank->CoordX + 1] == 0)
return 1;
else
return 0;
case 2:
if (gameMap[tank->CoordY + 2][tank->CoordX] == 0 &&
gameMap[tank->CoordY + 2][tank->CoordX - 1] == 0 &&
gameMap[tank->CoordY + 2][tank->CoordX + 1] == 0)
return 1;
else
return 0;
case 3:
if (gameMap[tank->CoordY][tank->CoordX - 2] == 0 &&
gameMap[tank->CoordY - 1][tank->CoordX - 2] == 0 &&
gameMap[tank->CoordY + 1][tank->CoordX - 2] == 0)
return 1;
else
return 0;
case 4:if (gameMap[tank->CoordY][tank->CoordX + 2] == 0 &&
gameMap[tank->CoordY - 1][tank->CoordX + 2] == 0 &&
gameMap[tank->CoordY + 1][tank->CoordX + 2] == 0)
return 1;
else
return 0;
}
return 0;
}
//向上后刷新
void turnUp(Object* tank1) {
int tankUp[3][3] = { { 0,2,0 },{ 2,2,2 },{ 2,0,2 } };
if (tank1->Direction == 1)
{
if (allowGo(tank1))
{
clearTank(tank1);
tank1->CoordY--;
printTank(tank1);
renewMap();
}
}
else
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
tank1->Shape[i][j] = tankUp[i][j];
clearTank(tank1);
printTank(tank1);
tank1->Direction = 1;
renewMap();
}
}
//向下后刷新
void turnDown(Object* tank2) {
int tankDown[3][3] = { { 2,0,2 },{ 2,2,2 },{ 0,2,0 } };
if (tank2->Direction == 2)
{
if (allowGo(tank2))
{
clearTank(tank2);
tank2->CoordY++;
printTank(tank2);
renewMap();
}
}
else
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
tank2->Shape[i][j] = tankDown[i][j];
clearTank(tank2);
printTank(tank2);
tank2->Direction = 2;
renewMap();
}
}
//向左后刷新
void turnLeft(Object* tank3) {
int tankLeft[3][3] = { { 0,2,2 },{ 2,2,0 },{ 0,2,2 } };
if (tank3->Direction == 3)
{
if (allowGo(tank3))
{
clearTank(tank3);
tank3->CoordX--;
printTank(tank3);
renewMap();
}
}
else
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
tank3->Shape[i][j] = tankLeft[i][j];
clearTank(tank3);
printTank(tank3);
tank3->Direction = 3;
renewMap();
}
}
//向右后刷新
void turnRight(Object* tank4) {
int tankRight[3][3] = { { 2,2,0 },{ 0,2,2 },{ 2,2,0 } };
if (tank4->Direction == 4)
{
if (allowGo(tank4))
{
clearTank(tank4);
tank4->CoordX++;
printTank(tank4);
renewMap();
}
}
else
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
tank4->Shape[i][j] = tankRight[i][j];
clearTank(tank4);
printTank(tank4);
tank4->Direction = 4;
renewMap();
}
}
//监测子弹对存在障碍物的改变,即是碰撞后的改变
void existChange() {
for (int i = 0; i < 50; i++) {
int m = ownBullet[i].CoordX;
int n = ownBullet[i].CoordY;
if (m > 0 && m < 39 && n>0 && n < 39) {//被我坦克子弹击中
if (existence[n - 1][m - 1] == 3)//打到土墙
{
existence[n - 1][m - 1] = 0;
gotoXY(2 * m, n);
printf(" ");
ownBullet[i].CoordX = 0, ownBullet[i].CoordY = 0;//子弹消失
printExist();
renewMap();
}
else if (existence[n - 1][m - 1] == 4)//打到钢墙
{
ownBullet[i].CoordX = 0, ownBullet[i].CoordY = 0;//子弹消失
}
}
}
for (int i = 0; i < 3;i++) {
int m1 = enemyBullet[i].CoordX;
int n1 = enemyBullet[i].CoordY;
if (m1 > 0 && m1 < 39 && n1>0 && n1 < 39) {//被敌方各坦克的各个子弹击中
if (existence[n1 - 1][m1 - 1] == 3)//打到土墙
{
existence[n1 - 1][m1 - 1] = 0;
gotoXY(2 * m1, n1);
printf(" ");
enemyBullet[i].CoordX = 0, enemyBullet[i].CoordY = 0;
printExist();
renewMap();
}
else if (existence[n1 - 1][m1 - 1] == 4)//打到钢墙
{
enemyBullet[i].CoordX = 0, enemyBullet[i].CoordY = 0;//子弹消失
}
else if (existence[n1 - 1][m1 - 1] == 2)//打到坦克
{
enemyBullet[i].CoordX = 0, enemyBullet[i].CoordY = 0;//子弹消失
}
}
else {
if (m1>40||m1<0||n1>40||n1<0) {
gotoXY(2 * m1, n1);
printf(" ");
enemyBullet[i].CoordX = 0, enemyBullet[i].CoordY = 0;
printExist();
renewMap();
}
}
}
}
//监测基地的变化
void baseChange() {
for (int i = 0; i < 50; i++) {
int m = ownBullet[i].CoordX;
int n = ownBullet[i].CoordY;
if (m == 37 && n == 38 || m == 38 && n == 38) {
gameOver();
break;
}
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {//自己子弹对基地的碰撞
if (m == 36 + 2 * a && n == 36 + b) {
if (base.Shape[a][b] == 3) {
base.Shape[a][b] = 0;
gotoXY(2 * m, n);
printf(" ");
ownBullet[i].CoordX = 0;
ownBullet[i].CoordY = 0;
printBase();
renewMap();
}
}
}
}
}
for (int i = 0; i < 3;i++) {
int m1 = enemyBullet[i].CoordX;
int n1 = enemyBullet[i].CoordY;//敌人子弹对基地的碰撞
if (m1 == 37 && n1 == 38 || m1 == 38 && n1 == 38) {
gameOver();
return;
}
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 3; b++) {
if (m1 == 36 + 2 * a && n1 == 36 + b) {
if (base.Shape[a][b] == 3) {
base.Shape[a][b] = 0;
gotoXY(2 * m1, n1);
printf(" ");
enemyBullet[i].CoordX = 0;
enemyBullet[i].CoordY = 0;
printBase();
renewMap();
}
}
}
}
}
}
//游戏结束的显示
void gameOver() {
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
gotoXY(30, 17);
printf(" 游戏结束 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
gotoXY(32, 23);
printf(" 按 空格键 重新开始或者按 n 返回主菜单 ");
while (1)
{
if (32 == _getch())
{
getExistMap();
renewMap();
startGame();
break;
}
if('n'== _getch()){
getExistMap();
renewMap();
WelcomeScreen();
break;
}
}
}
//监测游戏是否结束
void checkGame() {
if (ownTank.HealthPoint == 0)
gameOver();
if (enemyCount == 0) {
printf("您获得游戏的胜利!\n");
system("pause");
gameOver();
}
}
void getExistMap() {//制造障碍物
for (int j = 0; j < 38; j++) {
existence[19][j] = 3;//土墙
existence[20][j] = 3;
}
for (int i = 14; i < 28; i++) {
existence[21][i] = 4;//钢墙
}
}
void renewMap() {
for (int i = 0; i < 40; i++) //游戏地图初始化
for (int j = 0; j < 40; j++)
gameMap[i][j] = 0;
for (int i = 0; i < 40; i++) //围墙
{
gameMap[i][0] = 4;
gameMap[i][39] = 4;
}
for (int j = 0; j < 40; j++)
{
gameMap[0][j] = 4;
gameMap[39][j] = 4;
}
for (int i = 0; i < 38; i++) //地图所有物
for (int j = 0; j < 38; j++)
gameMap[i + 1][j + 1] = existence[i][j];
for (int i = 0; i < 3; i++) //基地
for (int j = 0; j < 3; j++)
gameMap[i + 36][j + 18] = base.Shape[i][j];
switch (ownTank.Direction) //坦克
{
case 1:
{
gameMap[ownTank.CoordY - 1][ownTank.CoordX - 1] = 0; gameMap[ownTank.CoordY - 1][ownTank.CoordX] = 2; gameMap[ownTank.CoordY - 1][ownTank.CoordX + 1] = 0;
gameMap[ownTank.CoordY][ownTank.CoordX - 1] = 2; gameMap[ownTank.CoordY][ownTank.CoordX] = 2; gameMap[ownTank.CoordY][ownTank.CoordX + 1] = 2;
gameMap[ownTank.CoordY + 1][ownTank.CoordX - 1] = 2; gameMap[ownTank.CoordY + 1][ownTank.CoordX] = 0; gameMap[ownTank.CoordY + 1][ownTank.CoordX + 1] = 2;
}break;
case 2:
{
gameMap[ownTank.CoordY - 1][ownTank.CoordX - 1] = 2; gameMap[ownTank.CoordY - 1][ownTank.CoordX] = 0; gameMap[ownTank.CoordY - 1][ownTank.CoordX + 1] = 2;
gameMap[ownTank.CoordY][ownTank.CoordX - 1] = 2; gameMap[ownTank.CoordY][ownTank.CoordX] = 0; gameMap[ownTank.CoordY][ownTank.CoordX + 1] = 2;
gameMap[ownTank.CoordY + 1][ownTank.CoordX - 1] = 0; gameMap[ownTank.CoordY + 1][ownTank.CoordX] = 2; gameMap[ownTank.CoordY + 1][ownTank.CoordX + 1] = 0;
}break;
case 3:
{
gameMap[ownTank.CoordY - 1][ownTank.CoordX - 1] = 0; gameMap[ownTank.CoordY - 1][ownTank.CoordX] = 2; gameMap[ownTank.CoordY - 1][ownTank.CoordX + 1] = 2;
gameMap[ownTank.CoordY][ownTank.CoordX - 1] = 2; gameMap[ownTank.CoordY][ownTank.CoordX] = 2; gameMap[ownTank.CoordY][ownTank.CoordX + 1] = 0;
gameMap[ownTank.CoordY + 1][ownTank.CoordX - 1] = 0; gameMap[ownTank.CoordY + 1][ownTank.CoordX] = 2; gameMap[ownTank.CoordY + 1][ownTank.CoordX + 1] = 2;
}break;
case 4:
{
gameMap[ownTank.CoordY - 1][ownTank.CoordX - 1] = 2; gameMap[ownTank.CoordY - 1][ownTank.CoordX] = 2; gameMap[ownTank.CoordY - 1][ownTank.CoordX + 1] = 0;
gameMap[ownTank.CoordY][ownTank.CoordX - 1] = 0; gameMap[ownTank.CoordY][ownTank.CoordX] = 2; gameMap[ownTank.CoordY][ownTank.CoordX + 1] = 2;
gameMap[ownTank.CoordY + 1][ownTank.CoordX - 1] = 2; gameMap[ownTank.CoordY + 1][ownTank.CoordX] = 2; gameMap[ownTank.CoordY + 1][ownTank.CoordX + 1] = 0;
}break;
}
for (int i = 0; i < 3; i++) {
switch (enemyTank[i].Direction) //敌方坦克
{
case 1://上
{
gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX - 1] = 0; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX + 1] = 0;
gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX - 1] = 2; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX + 1] = 2;
gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX - 1] = 2; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX] = 0; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX + 1] = 2;
}break;
case 2://下
{
gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX - 1] = 2; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX] = 0; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX + 1] = 2;
gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX - 1] = 2; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX] = 0; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX + 1] = 2;
gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX - 1] = 0; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX + 1] = 0;
}break;
case 3://左
{
gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX - 1] = 0; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX + 1] = 2;
gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX - 1] = 2; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX + 1] = 0;
gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX - 1] = 0; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX + 1] = 2;
}break;
case 4://右
{
gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX - 1] = 2; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY - 1][enemyTank[i].CoordX + 1] = 0;
gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX - 1] = 0; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY][enemyTank[i].CoordX + 1] = 2;
gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX - 1] = 2; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX] = 2; gameMap[enemyTank[i].CoordY + 1][enemyTank[i].CoordX + 1] = 0;
}break;
}
}
}
clock_t time1_start;
clock_t time1_end;
clock_t time2_start;
clock_t time2_end;
void startGame() {
system("mode con cols=90 lines=45");
system("title 坦克大战");
hideCursor();
printBorder();//打印围墙
initGame();//初始化数据
srand((unsigned int)time(NULL));
while (1) {
time1_end = clock();
if (time1_end - time1_start > ownTank.speed)
{
time1_start = time1_end;
tankMove();//自己坦克移动
ownBulletMove();//自己子弹移动
}
time2_end = clock();
if (time2_end - time2_start > enemyTank[0].speed)
{
time2_start = time2_end;
badTankMove(&enemyTank[0]);//敌军移动
badTankMove(&enemyTank[1]);
badTankMove(&enemyTank[2]);
badTankfire(&enemyTank[0], &enemyBullet[0]);//敌军开火
enemyBulletMove(&enemyBullet[0]);//敌军子弹移动
badTankfire(&enemyTank[1], &enemyBullet[1]);
enemyBulletMove(&enemyBullet[1]);
badTankfire(&enemyTank[2], &enemyBullet[2]);
enemyBulletMove(&enemyBullet[2]);
}
}
}
int main() {
WelcomeScreen();//游戏选项,主菜单
system("pause");
return 0;
}
2.4 其他逻辑部分设计
子弹逻辑设计
Bullet.h
#pragma once
#include"TankGame.h"
int checkBullet(int x, int y);//检测某位置能否打印子弹
void ownBulletMove(); //自己子弹自动移动
void enemyBulletMove(Object* badTankBullet);//敌人坦克子弹自由移动
void bulletChange();//监测子弹的改变
Bullet.c
#include"TankGame.h"
#include"Tank.h"
#include"Bullet.h"
#include"Draw.h"
int checkBullet(int x, int y)//检测能不能在此打印子弹
{
if (gameMap[y][x])
return 0;
return 1;
}
void ownBulletMove() {
for (int i = 0; i < 50; i++) {
int m = ownBullet[i].CoordX;
int n = ownBullet[i].CoordY;
if (m != 0 || n != 0)
if (gameMap[n][m] == 0)//先擦掉
clearBullet(ownBullet);
switch (ownBullet[i].Direction)
{
case 1:ownBullet[i].CoordY--; break;
case 2:ownBullet[i].CoordY++; break;
case 3:ownBullet[i].CoordX--; break;
case 4:ownBullet[i].CoordX++; break;
}
//检查是否击中障碍物
existChange();
//检查是否击中基地
baseChange();
//检查是否击中子弹
bulletChange();
//检查是否击中敌方坦克
badTankChange();
if (checkBullet(ownBullet[i].CoordX, ownBullet[i].CoordY))
printBullet();
else
ownBullet[i].CoordX = 0, ownBullet[i].CoordY = 0;
}
}
void enemyBulletMove(Object* badTankBullet) {
int m = badTankBullet->CoordX;
int n = badTankBullet->CoordY;
if (m != 0 || n != 0)
if (gameMap[n][m] == 0) {//先清除掉
clearBadBullet(m, n);
}
switch (badTankBullet->Direction)
{
case 1:badTankBullet->CoordY--; break;
case 2:badTankBullet->CoordY++; break;
case 3:badTankBullet->CoordX--; break;
case 4:badTankBullet->CoordX++; break;
}
//检查是否击中障碍物
existChange();
//检查是否击中基地
baseChange();
//检查是否击中子弹
bulletChange();
//检查是否击中我的坦克
ownTankChange();
if (badTankBullet->CoordX != 0 && badTankBullet->CoordY != 0) {
if (checkBullet(badTankBullet->CoordX, badTankBullet->CoordY))
printBadBullet(badTankBullet);
else
badTankBullet->CoordX = 0, badTankBullet->CoordY = 0;
}
}
//监测子弹碰撞的改变
void bulletChange() {
for (int i = 0; i < 50; i++) {
int m = ownBullet[i].CoordX;
int n = ownBullet[i].CoordY;
for (int i = 0; i < 3; i++) {//我的坦克子弹和敌人坦克子弹的碰撞
if (enemyBullet[i].CoordX == m && m != 0 && enemyBullet[i].CoordY == n && n != 0) {
clearBullet(&ownBullet[i]);//删除我坦克的子弹
ownBullet[i].CoordX = 0;
ownBullet[i].CoordY = 0;
clearBadBullet(enemyBullet[i].CoordX, enemyBullet[i].CoordY);//删除敌方坦克的子弹
enemyBullet[i].CoordX = 0;
enemyBullet[i].CoordY = 0;
}
}
}
}
坦克逻辑设计
Tank.h
#pragma once
#include"TankGame.h"
void ownTankChange(); //监测自己坦克的改变
void badTankChange(); //监测敌人坦克的改变
void tankMove();//自己的坦克移动
void badTankMove(Object* badTank);//敌人坦克移动
void ownTankfire();//自己坦克开火
void badTankfire(Object* badTank, Object* badTankBullet);//敌人坦克开火
Tank.c
#include"Tank.h"
#include"Draw.h"
#include"windows.h"
#include"conio.h"
#include"Utils.h"
#define KEYDOWN(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?1:0)
#define KEYUP(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?0:1)
//监测自己坦克状态的改变
void ownTankChange() {
int x = ownTank.CoordX;
int y = ownTank.CoordY;
switch (ownTank.Direction)
{
case 1: //当我的坦克方向向上时
{
for (int i = 0; i < 3; i++) {
int m1 = enemyBullet[i].CoordX;
int n1 = enemyBullet[i].CoordY;
if (x == m1 && (y - 1) == n1 || (x - 1) == m1&&y == n1 || x == m1&&y == n1 ||
(x + 1) == m1&&y == n1 || (x - 1) == m1 && (y + 1) == n1 || (x + 1) == m1 && (y + 1) == n1)
enemyBullet[i].CoordX = 0,
enemyBullet[i].CoordY = 0,
ownTank.HealthPoint--,
printScoreboard(),
checkGame(),
turnUp(&ownTank);
//坦克子弹消失,生命值减1,检查游戏是否结束,若没结束初始化方向
}
}break;
case 2:
{
for (int i = 0; i < 3; i++) {
int m1 = enemyBullet[i].CoordX;
int n1 = enemyBullet[i].CoordY;
if (x == m1 && (y + 1) == n1 || (x - 1) == m1&&y == n1 || x == m1&&y == n1 || (x + 1) == m1&&y == n1 ||
(x - 1) == m1 && (y - 1) == n1 || (x + 1) == m1 && (y - 1) == n1)
enemyBullet[i].CoordX = 0,
enemyBullet[i].CoordY = 0,
ownTank.HealthPoint--,
printScoreboard(),
checkGame(),
turnUp(&ownTank);
}
}break;
case 3:
{
for (int i = 0; i < 3; i++) {
int m1 = enemyBullet[i].CoordX;
int n1 = enemyBullet[i].CoordY;
if (x == m1 && (y - 1) == n1 || (x - 1) == m1&&y == n1 || x == m1&&y == n1 ||
(x + 1) == m1 && (y - 1) == n1 || x == m1 && (y + 1) == n1 || (x + 1) == m1 && (y + 1) == n1)
enemyBullet[i].CoordX = 0, enemyBullet[i].CoordY = 0, ownTank.HealthPoint--, printScoreboard(), checkGame(), turnUp(&ownTank);
}
}break;
case 4:
{
for (int i = 0; i < 3; i++) {
int m1 = enemyBullet[i].CoordX;
int n1 = enemyBullet[i].CoordY;
if (x == m1 && (y - 1) == n1 || (x - 1) == m1 && (y - 1) == n1 || x == m1&&y == n1 ||
(x - 1) == m1 && (y + 1) == n1 || x == m1 && (y + 1) == n1 || (x + 1) == m1&&y == n1)
enemyBullet[i].CoordX = 0,
enemyBullet[i].CoordY = 0,
ownTank.HealthPoint--,
printScoreboard(),
checkGame(),
turnUp(&ownTank);
}
}break;
}
}
//监测敌人坦克状态的改变
void badTankChange()
{
for (int i = 0; i < 50; i++) {
int m = ownBullet[i].CoordX;
int n = ownBullet[i].CoordY;
for (int j = 0; j < 3; j++) {
int x1 = enemyTank[j].CoordX;
int y1 = enemyTank[j].CoordY;
switch (enemyTank[j].Direction)
{
case 1:
{//以坦克中心点开始判断六个点是否与子弹坐标重合
if (x1 == m && (y1 - 1) == n || (x1 - 1) == m && y1 == n || x1 == m&&y1 == n ||
(x1 + 1) == m && y1 == n || (x1 - 1) == m && (y1 + 1) == n || (x1 + 1) == m && (y1 + 1) == n) {
//如果我的坦克子弹打到敌人
clearTank(&enemyTank[j]); //清除敌军坦克
enemyTank[j].CoordX = 2 + j * 10;//敌军坦克回到初始位置
enemyTank[j].CoordY = 2;
ownBullet[i].CoordX = 0;//我的坦克子弹消失
ownBullet[i].CoordY = 0;
enemyCount--; //敌人坦克数量减1
score = score + 100;//分数加100
printScoreboard();
checkGame();//检查游戏是否胜利
}
}break;
case 2:
{
if (x1 == m && (y1 + 1) == n || (x1 - 1) == m&&y1 == n || x1 == m&&y1 == n ||
(x1 + 1) == m&&y1 == n || (x1 - 1) == m && (y1 - 1) == n || (x1 + 1) == m && (y1 - 1) == n) {
clearTank(&enemyTank[j]);
enemyTank[j].CoordX = 2 + j * 10;
enemyTank[j].CoordY = 2;
ownBullet[i].CoordX = 0;
ownBullet[i].CoordY = 0;
enemyCount--;
score = score + 100;
printScoreboard();
checkGame();
}
}break;
case 3:
{
if (x1 == m && (y1 - 1) == n || (x1 - 1) == m&&y1 == n || x1 == m&&y1 == n ||
(x1 + 1) == m && (y1 - 1) == n || x1 == m && (y1 + 1) == n || (x1 + 1) == m && (y1 + 1) == n) {
clearTank(&enemyTank[j]);
enemyTank[j].CoordX = 2 + j * 10;
enemyTank[j].CoordY = 2;
ownBullet[i].CoordX = 0;
ownBullet[i].CoordY = 0;
enemyCount--;
score = score + 100;
printScoreboard();
checkGame();
}
}break;
case 4:
{
if (x1 == m && (y1 - 1) == n || (x1 - 1) == m && (y1 - 1) == n || x1 == m&&y1 == n ||
(x1 - 1) == m && (y1 + 1) == n || x1 == m && (y1 + 1) == n || (x1 + 1) == m&&y1 == n) {
clearTank(&enemyTank[j]);
enemyTank[j].CoordX = 2 + j * 10;
enemyTank[j].CoordY = 2;
ownBullet[i].CoordX = 0;
ownBullet[i].CoordY = 0;
enemyCount--;
score = score + 100;
printScoreboard();
checkGame();
}
}break;
}
}
}
}
void ownTankfire() {
for (int i = 0; i < 50; i++) {
int m = ownBullet[i].CoordX;
int n = ownBullet[i].CoordY;
if (m == 0 && n == 0)//第几个子弹没有,则重新生成子弹
{
switch (ownTank.Direction)
{
case 1:
{
ownBullet[i].CoordX = ownTank.CoordX;
ownBullet[i].CoordY = ownTank.CoordY - 2;
ownBullet[i].Direction = 1;
}break;
case 2:
{
ownBullet[i].CoordX = ownTank.CoordX;;
ownBullet[i].CoordY = ownTank.CoordY + 2;
ownBullet[i].Direction = 2;
}break;
case 3:
{
ownBullet[i].CoordX = ownTank.CoordX - 2;
ownBullet[i].CoordY = ownTank.CoordY;
ownBullet[i].Direction = 3;
}break;
case 4:
{
ownBullet[i].CoordX = ownTank.CoordX + 2;
ownBullet[i].CoordY = ownTank.CoordY;
ownBullet[i].Direction = 4;
}break;
}
break;
}
}
}
void badTankfire(Object* badTank, Object* badTankBullet) {
int m = badTankBullet->CoordX;
int n = badTankBullet->CoordY;
if (m == 0 && n == 0)//没有坦克的子弹,则重新发射子弹
{
switch (badTank->Direction)
{
case 1:
{
badTankBullet->CoordX = badTank->CoordX;
badTankBullet->CoordY = badTank->CoordY - 2;
badTankBullet->Direction = 1;
}break;
case 2:
{
badTankBullet->CoordX = badTank->CoordX;;
badTankBullet->CoordY = badTank->CoordY + 2;
badTankBullet->Direction = 2;
}break;
case 3:
{
badTankBullet->CoordX = badTank->CoordX - 2;
badTankBullet->CoordY = badTank->CoordY;
badTankBullet->Direction = 3;
}break;
case 4:
{
badTankBullet->CoordX = badTank->CoordX + 2;
badTankBullet->CoordY = badTank->CoordY;
badTankBullet->Direction = 4;
}break;
}
}
}
void tankMove() {
if (KEYDOWN('f') || KEYDOWN('F'))
{
ownTankfire();
return;
}
if (KEYDOWN('W') || KEYDOWN('w'))
{
turnUp(&ownTank);
return;
}
if (KEYDOWN('s') || KEYDOWN('S'))
{
turnDown(&ownTank);
return;
}
if (KEYDOWN('a') || KEYDOWN('A'))
{
turnLeft(&ownTank);
return;
}
if (KEYDOWN('d') || KEYDOWN('D'))
{
turnRight(&ownTank);
return;
}
if (KEYDOWN('p') || KEYDOWN('P'))
{
stopGame();
return;
}
if (KEYDOWN('o') || KEYDOWN('O'))
{
exit(0);
return;
}
}
void badTankMove(Object* badTank) {
int direction = (rand() % 4 + 1);
switch (direction)
{
case 1:turnUp(badTank); break;
case 2:turnDown(badTank); break;
case 3:turnLeft(badTank); break;
case 4:turnRight(badTank); break;
}
}
地图编辑逻辑
editMap.h
#pragma once
#include "windows.h"
#include "editMap.h"
void edit_map();
editMap.c
#include"stdio.h"
#include"stdlib.h"
#include"Utils.h"
#include"windows.h"
#include"conio.h"
#include"TankGame.h"
#include"Draw.h"
#include"editMap.h"
void edit_map() {
system("cls");
int x = 1, y = 4;//编辑地图光标的坐标
int map[38][38] = { 0 };//自定义的地图
char key;
for (int i = 0; i < 38; i++) //初始化
for (int j = 0; j < 38; j++)
existence[i][j] = 0; //置空
ownTank.CoordX = 6;//初始化坦克
ownTank.CoordY = 37;
ownTank.Camp = 1;
ownTank.Direction = 0;
//敌方坦克位置的初始化
for (int i = 0; i < 3; i++) {
enemyTank[i].CoordX = 2 + i * 15;
enemyTank[i].CoordY = 2;
enemyTank[i].Camp = 2;
enemyTank[i].Direction = 0;
}
printBorder();
int _base[3][3] = { { 3,3,3 },{ 3,2,3 },{ 3,2,3 } };
for (int i = 0; i < 3; i++)//基地位置初始化
for (int j = 0; j < 3; j++)
base.Shape[i][j] = _base[i][j];
printBase();//打印基地
int tankUp[3][3] = { { 0,2,0 },{ 2,2,2 },{ 2,0,2 } };
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
ownTank.Shape[i][j] = tankUp[i][j];
printTank(&ownTank);//编辑地图上打印一个我的坦克
int tankDown[3][3] = { { 2,0,2 },{ 2,2,2 },{ 0,2,0 } };
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
enemyTank[0].Shape[i][j] = tankDown[i][j];
enemyTank[1].Shape[i][j] = tankDown[i][j];
enemyTank[2].Shape[i][j] = tankDown[i][j];
}
printTank(&enemyTank[0]);//编辑地图上打印三个敌人坦克
printTank(&enemyTank[1]);
printTank(&enemyTank[2]);
// setEnglish();
int flag = 1;
while (flag)
{
gotoXY(2 * x, y);
switch (map[y - 1][x - 1])
{
case 0:
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),10);
printf("□");
}break;
case 3://土墙
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
printf("■");
}break;
case 4://钢墙
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15);
printf("■");
}break;
}
if (_kbhit()) //检测,如果有按键就执行if里面的
{
key = _getch();//捕获按键
switch (key)
{
case 72: //上箭头
{
if (map[y - 1][x - 1] == 0) {
gotoXY(2 * x, y);
printf(" ");
}
if (y > 4) y--;//编辑光标活动范围
}break;
case 75: //左箭头
{
if (map[y - 1][x - 1] == 0) {
gotoXY(2 * x, y);
printf(" ");
}
if (x > 1) x--;//编辑光标活动范围
}break;
case 77: //右箭头
{
if (map[y - 1][x - 1] == 0) {
gotoXY(2 * x, y);
printf(" ");
}
if (x < 38) x++;//编辑光标活动范围
}break;
case 80: //下箭头
{
if (map[y - 1][x - 1] == 0) {
gotoXY(2 * x, y);
printf(" ");
}
if (y < 38) y++;//编辑光标活动范围
}break;
case 32: //按空格开始游戏
{
if (map[y - 1][x - 1] == 0) {
gotoXY(2 * x, y);
printf(" ");
}
flag = 0;
}break;
case 116: //t键设置土墙
{
map[y - 1][x - 1] = 3;
}break;
case 103: //g 键设置钢墙
{
map[y - 1][x - 1] = 4;
}break;
case 114: //r 键清空位置
{
map[y - 1][x - 1] = 0;
}break;
default:;
}
}
}
for (int i = 0; i < 38; i++)
for (int j = 0; j < 38; j++)
existence[i][j] = map[i][j];//将自定义地图数据保存至地图所有物数组
renewMap();//刷新地图
startGame();//开始游戏
system("cls");
}
三、运行截图和参考代码
游戏运行界面
游戏界面
地图编辑
参考代码下载: