C语言控制台简单坦克大战

首先是保存地图的文件

map.h头文件


#pragma once

#include<windows.h>

#define N 39
#define 边界 0
#define 空地 1
#define 土墙 2
#define 铁墙 3

int g_Map[N + 2][N + 2] ;

int g_Map1[N + 2][N + 2];

//初始化边界
void Init();

//打印地图
void PtfMap();

//绘制地图
void DrawMap();

map.c源文件

#include"map.h"

g_Map1[41][41] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 0
    , 0, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 0
    , 0, 3, 3, 3, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
    , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};


//初始化边界
void Init()
{
    memset(g_Map, 0, sizeof(g_Map));
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= N; j++)
        {
            g_Map[i][j] = 1;
        }
    }

    Color(0xF);
    for (int i = 0; i <= N + 1; i++)
    {
        Posxy(i, 0);
        printf("━");
        Posxy(i, N + 1);
        printf("━");
    }
    for (int i = 0; i <= N + 1; i++)
    {
        Posxy(0, i);
        printf("┃");
        Posxy(N + 1, i);
        printf("┃");
    }
    Posxy(0, 0);
    printf("┏");
    Posxy(N + 1, 0);
    printf("┓");
    Posxy(0, N + 1);
    printf("┗");
    Posxy(N + 1, N + 1);
    printf("┛");



}

//打印地图
void PtfMap()
{
    Posxy(0, 0);
    for (int i = 0; i <= N; i++)
    {
        for (int j = 0; j <= N; j++)
        {
            if (g_Map1[i][j] == 边界)
            {
                Color(0);
                printf("□");
            }
            else if (g_Map1[i][j] == 空地)
            {
                Color(0);
                printf("  ");
            }
            else if (g_Map1[i][j] == 土墙)
            {
                Color(6);
                printf("■");
            }
            else if (g_Map1[i][j] == 铁墙)
            {
                Color(7);
                printf("■");
            }
        }
        putchar('\n');
    }
}

//绘制地图
void DrawMap()
{
    int tEND = 1;//判断是否结束画墙
    memset(g_Map1, 0, sizeof(g_Map1));
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= N; j++)
        {
            g_Map1[i][j] = 1;
        }
    }
    int Arr[3] = { 土墙,铁墙 };
    int nColor = 6;
    int List = 0;
    system("cls");
    Init();
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    INPUT_RECORD stcRecord = { 0 };
    DWORD dwRead;
    SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);//sxq
    Posxy(42, 3);
    printf("按1切换为土墙");
    Posxy(42, 5);
    printf("按2切换为铁墙");
    Posxy(42, 7);
    printf("右键清除为空地");
    Posxy(42, 9);
    printf("按B保存地图");

    while (tEND)
    {
        ReadConsoleInput(hStdin, &stcRecord, 1, &dwRead);
        if (stcRecord.EventType == KEY_EVENT)
        {
            KEY_EVENT_RECORD ker = stcRecord.Event.KeyEvent;
            //键盘事件
            if (ker.bKeyDown)
            {
                switch (ker.wVirtualKeyCode)
                {
                case '1':
                    List = 0;
                    nColor = 6;
                    break;
                case '2':
                    List = 1;
                    nColor = 7;
                    break;
                case 'b':case 'B':
                    tEND = 0;
                    break;
                }
            }
        }

        if (stcRecord.EventType == MOUSE_EVENT)
        {
            //鼠标事件
            MOUSE_EVENT_RECORD mer = stcRecord.Event.MouseEvent;

            if (mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
            {
                if (mer.dwMousePosition.X / 2 < N + 1 && mer.dwMousePosition.Y < N + 1)
                {
                    if (mer.dwMousePosition.X / 2 != 0 && mer.dwMousePosition.Y != 0)
                    {
                        Posxy(mer.dwMousePosition.X / 2, mer.dwMousePosition.Y);
                        Color(nColor);
                        printf("■");
                        g_Map1[mer.dwMousePosition.Y ][mer.dwMousePosition.X/2] =Arr[List];
                    }
                }
            }
            else if (mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
            {
                if (mer.dwMousePosition.X / 2 < N + 1 && mer.dwMousePosition.Y < N + 1)
                {
                    if (mer.dwMousePosition.X / 2 != 0 && mer.dwMousePosition.Y != 0)
                    {
                        Posxy(mer.dwMousePosition.X / 2, mer.dwMousePosition.Y);
                        printf("  ");
                        g_Map1[mer.dwMousePosition.Y ][mer.dwMousePosition.X/2] = 1;
                    }
                }
            }
        }
    }
    //system("pause");
}

tank.h头文件

#pragma once

#include<windows.h>
#include"map.h"

#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4


typedef struct
{

    COORD Pos;
    int Direction;         //坦克方向
    unsigned int BulletCD; //判断发射CD
    char IfMe;
    char Life;
    int HP;
}Tank;


int TankAINum ;
Tank TankAI[80];


//打印坦克并将对应数据写入地图
void TankPtfA(Tank tank);

//擦除坦克并将对应数据从地图中擦除
void ErasureTank(Tank tank);

//判断坦克移动是否有效,如果无效则将坦克坐标返回
void IfMove(Tank* tank);

//坦克移动
void TankMove(Tank* tank);

//创建坦克AI
int CreatTankAI(Tank *tank);

//坦克AI移动
void TankAIMove(Tank *tank);

tank.c文件

#include"tank.h"

TankAINum = 0;

//打印坦克并将对应数据写入地图
void TankPtfA(Tank tank)
{
    if (tank.IfMe)
    {
        Color(0xF);
    }
    else
    {
        Color(10);
    }

    if (tank.Direction == 1)
    {
        Posxy(tank.Pos.X - 1, tank.Pos.Y - 1);
        printf("┏ ↑┓");//←→↓
        Posxy(tank.Pos.X - 1, tank.Pos.Y);
        printf("┃ ○┃");
        Posxy(tank.Pos.X - 1, tank.Pos.Y + 1);
        printf("┗ ━ ┛");
    }
    else if (tank.Direction == 2)
    {
        Posxy(tank.Pos.X - 1, tank.Pos.Y - 1);
        printf("┏ ━ ┓");//←→↓
        Posxy(tank.Pos.X - 1, tank.Pos.Y);
        printf("┃ ○┃");
        Posxy(tank.Pos.X - 1, tank.Pos.Y + 1);
        printf("┗ ↓┛");
    }
    else if (tank.Direction == 3)
    {
        Posxy(tank.Pos.X - 1, tank.Pos.Y - 1);
        printf("┏ ━ ┓");//←→↓
        Posxy(tank.Pos.X - 1, tank.Pos.Y);
        printf("←○┃");
        Posxy(tank.Pos.X - 1, tank.Pos.Y + 1);
        printf("┗ ━ ┛");
    }
    else if (tank.Direction == 4)
    {
        Posxy(tank.Pos.X - 1, tank.Pos.Y - 1);
        printf("┏ ━ ┓");//←→↓
        Posxy(tank.Pos.X - 1, tank.Pos.Y);
        printf("┃ ○→");
        Posxy(tank.Pos.X - 1, tank.Pos.Y + 1);
        printf("┗ ━ ┛");
    }
    g_Map1[tank.Pos.Y][tank.Pos.X - 1] = 9;
    g_Map1[tank.Pos.Y][tank.Pos.X] = 9;
    g_Map1[tank.Pos.Y][tank.Pos.X + 1] = 9;
    g_Map1[tank.Pos.Y - 1][tank.Pos.X - 1] = 9;
    g_Map1[tank.Pos.Y - 1][tank.Pos.X] = 9;
    g_Map1[tank.Pos.Y - 1][tank.Pos.X + 1] = 9;
    g_Map1[tank.Pos.Y + 1][tank.Pos.X - 1] = 9;
    g_Map1[tank.Pos.Y + 1][tank.Pos.X] = 9;
    g_Map1[tank.Pos.Y + 1][tank.Pos.X + 1] = 9;


}

//擦除坦克并将对应数据从地图中擦除
void ErasureTank(Tank tank)
{
    Posxy(tank.Pos.X - 1, tank.Pos.Y - 1);
    printf("      ");
    Posxy(tank.Pos.X - 1, tank.Pos.Y);
    printf("      ");
    Posxy(tank.Pos.X - 1, tank.Pos.Y + 1);
    printf("      ");
    g_Map1[tank.Pos.Y][tank.Pos.X - 1] = 1;
    g_Map1[tank.Pos.Y][tank.Pos.X] = 1;
    g_Map1[tank.Pos.Y][tank.Pos.X + 1] = 1;
    g_Map1[tank.Pos.Y - 1][tank.Pos.X - 1] = 1;
    g_Map1[tank.Pos.Y - 1][tank.Pos.X] = 1;
    g_Map1[tank.Pos.Y - 1][tank.Pos.X + 1] = 1;
    g_Map1[tank.Pos.Y + 1][tank.Pos.X - 1] = 1;
    g_Map1[tank.Pos.Y + 1][tank.Pos.X] = 1;
    g_Map1[tank.Pos.Y + 1][tank.Pos.X + 1] = 1;
}

//判断坦克移动是否有效,如果无效则将坦克坐标返回
void IfMove(Tank* tank)
{
    COORD TPos = tank->Pos;
    switch (tank->Direction)
    {
    case UP:
    {
        if (g_Map1[TPos.Y - 1][TPos.X - 1] != 1 || g_Map1[TPos.Y - 1][TPos.X] != 1 || g_Map1[TPos.Y - 1][TPos.X + 1] != 1)
            tank->Pos.Y++;

        break;
    }
    case DOWN:
    {
        if (g_Map1[TPos.Y + 1][TPos.X - 1] != 1 || g_Map1[TPos.Y + 1][TPos.X] != 1 || g_Map1[TPos.Y + 1][TPos.X + 1] != 1)
            tank->Pos.Y--;

        break;
    }
    case LEFT:
    {
        if (g_Map1[TPos.Y - 1][TPos.X - 1] != 1 || g_Map1[TPos.Y][TPos.X - 1] != 1 || g_Map1[TPos.Y + 1][TPos.X - 1] != 1)
            tank->Pos.X++;

        break;
    }
    case RIGHT:
    {
        if (g_Map1[TPos.Y - 1][TPos.X + 1] != 1 || g_Map1[TPos.Y][TPos.X + 1] != 1 || g_Map1[TPos.Y + 1][TPos.X + 1] != 1)
            tank->Pos.X--;

        break;
    }
    }
}

//坦克移动
void TankMove(Tank* tank)
{
    ErasureTank(*tank);
    switch (tank->Direction)
    {
    case UP:tank->Pos.Y--; break;
    case DOWN:tank->Pos.Y++; break;
    case LEFT:tank->Pos.X--; break;
    case RIGHT:tank->Pos.X++; break;
    }
    IfMove(tank);
    TankPtfA(*tank);

}

//创建坦克AI
int CreatTankAI(Tank *tank)
{
    switch (rand() % 3)
    {
    case 0:
    {
        tank->Pos.X = 3;
        tank->Pos.Y = 2;
        break;
    }
    case 1:
    {
        tank->Pos.X = 38;
        tank->Pos.Y = 2;
        break;
    }
    case 2:
    {
        tank->Pos.X = 20;
        tank->Pos.Y = 2;
        break;
    }

    }
    tank->Direction = rand() % 4 + 1;
    tank->IfMe = 0;
    tank->Life = 1;
    tank->BulletCD = 0;
    tank->HP = 1;

    if (g_Map1[tank->Pos.Y][tank->Pos.X] == 1
        && g_Map1[tank->Pos.Y - 1][tank->Pos.X - 1] == 1
        && g_Map1[tank->Pos.Y - 1][tank->Pos.X] == 1
        && g_Map1[tank->Pos.Y - 1][tank->Pos.X + 1] == 1
        && g_Map1[tank->Pos.Y][tank->Pos.X - 1] == 1
        && g_Map1[tank->Pos.Y][tank->Pos.X + 1] == 1
        && g_Map1[tank->Pos.Y + 1][tank->Pos.X + 1] == 1
        && g_Map1[tank->Pos.Y + 1][tank->Pos.X - 1] == 1
        && g_Map1[tank->Pos.Y + 1][tank->Pos.X] == 1)
    {
        g_Map1[tank->Pos.Y][tank->Pos.X] = 9;
        g_Map1[tank->Pos.Y - 1][tank->Pos.X - 1] = 9;
        g_Map1[tank->Pos.Y - 1][tank->Pos.X] = 9;
        g_Map1[tank->Pos.Y - 1][tank->Pos.X + 1] = 9;
        g_Map1[tank->Pos.Y][tank->Pos.X - 1] = 9;
        g_Map1[tank->Pos.Y][tank->Pos.X + 1] = 9;
        g_Map1[tank->Pos.Y + 1][tank->Pos.X + 1] = 9;
        g_Map1[tank->Pos.Y + 1][tank->Pos.X - 1] = 9;
        g_Map1[tank->Pos.Y + 1][tank->Pos.X] = 9;
        return 1;
    }
    else
    {
        return 0;
    }


}

//坦克AI移动
void TankAIMove(Tank *tank)
{
    ErasureTank(*tank);

    switch (tank->Direction)
    {
    case UP:tank->Pos.Y--; break;
    case DOWN:tank->Pos.Y++; break;
    case LEFT:tank->Pos.X--; break;
    case RIGHT:tank->Pos.X++; break;
    }
    IfMove(tank);
    if (rand() % 5 == 0)
    {
        switch (rand() % 5)
        {
        case UP:tank->Direction = UP; break;
        case DOWN:tank->Direction = DOWN; break;
        case LEFT:tank->Direction = LEFT; break;
        case RIGHT:tank->Direction = RIGHT; break;
        default:break;
        }
    }
    TankPtfA(*tank);
}

void CreatPlayer(Tank *Player)
{
    Player->Pos.X = 14;
    Player->Pos.Y = 38;
    Player->Direction = 1;
    Player->BulletCD = 0;
    Player->IfMe = 1;
    Player->Life = 1;
}

bullet.h

#pragma once

#include<windows.h>
#include"tank.h"

typedef struct
{
    COORD Pos;
    int Direction;
    char IfMe;
}Bullet;

int g_BulletNum ;
Bullet g_BulletArr[20];

//子弹移动
void BulletMove(Bullet* bullet);

//创建子弹
void CreatBullet(Tank *tank);

//判断子弹碰撞箱
int Box(COORD BoxA, COORD BoxB);

//子弹碰撞判断
void BulletTest(Tank* tank);

bullet.c

#include"bullet.h"

g_BulletNum = 0;

//子弹移动
void BulletMove(Bullet* bullet)
{
    Posxy(bullet->Pos.X, bullet->Pos.Y);
    printf(" ");
    switch (bullet->Direction)
    {
    case UP:bullet->Pos.Y--; break;
    case DOWN:bullet->Pos.Y++; break;
    case LEFT:bullet->Pos.X--; break;
    case RIGHT:bullet->Pos.X++; break;
    }
    Posxy(bullet->Pos.X, bullet->Pos.Y);
    if (bullet->IfMe == 1)
    {
        Color(0xF);
    }
    else
    {
        Color(10);
    }
    printf("*");
}

//创建子弹
void CreatBullet(Tank *tank)
{
    g_BulletArr[g_BulletNum].Direction = tank->Direction;
    g_BulletArr[g_BulletNum].IfMe = tank->IfMe;
    if (tank->IfMe == 0)
    {
        tank->BulletCD += 15;
    }
    switch (tank->Direction)
    {
    case UP:
        if (tank->Pos.Y - 2 > 0)
        {
            g_BulletArr[g_BulletNum].Pos.X = tank->Pos.X;
            g_BulletArr[g_BulletNum].Pos.Y = tank->Pos.Y - 2;
            g_BulletNum++;
        }
        break;
    case DOWN:
        if (tank->Pos.Y + 2 < N + 1)
        {
            g_BulletArr[g_BulletNum].Pos.X = tank->Pos.X;
            g_BulletArr[g_BulletNum].Pos.Y = tank->Pos.Y + 2;
            g_BulletNum++;
        }
        break;
    case LEFT:
        if (tank->Pos.X - 2 > 0)
        {
            g_BulletArr[g_BulletNum].Pos.X = tank->Pos.X - 2;
            g_BulletArr[g_BulletNum].Pos.Y = tank->Pos.Y;
            g_BulletNum++;
        }
        break;
    case RIGHT:
        if (tank->Pos.X + 2 < N + 1)
        {
            g_BulletArr[g_BulletNum].Pos.X = tank->Pos.X + 2;
            g_BulletArr[g_BulletNum].Pos.Y = tank->Pos.Y;
            g_BulletNum++;
        }
        break;
    }


}


//判断子弹碰撞箱
int Box(COORD BoxA, COORD BoxB)
{
    if (BoxA.X == BoxB.X || BoxA.X == BoxB.X - 1 || BoxA.X == BoxB.X + 1)
    {
        if (BoxA.Y == BoxB.Y || BoxA.Y == BoxB.Y - 1 || BoxA.Y == BoxB.Y + 1)
        {
            return 1;
        }
    }
    return 0;
}


//子弹碰撞判断
void BulletTest(Tank* tank)
{
    int IfMove = 1;

    if (GetAsyncKeyState(VK_SHIFT) && tank->BulletCD <= 1)
    {
        CreatBullet(tank);
        tank->BulletCD += 7;
    }


    for (int i = 0; i < g_BulletNum; i++)                                        //遍历子弹坐标
    {
        if (g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X] == 2)             //判断子弹击中土墙
        {
            switch (g_BulletArr[i].Direction)                                    //判断子弹方向
            {
            case UP:
            case DOWN:                                                           
            {
                g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X] = 1;          //如果为上下则判断击中土墙左右是否为土墙
                Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);               //如果是土墙则清除
                printf("  ");
                if (g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X - 1] == 2)
                {
                    g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X - 1] = 1;
                    Posxy(g_BulletArr[i].Pos.X - 1, g_BulletArr[i].Pos.Y);
                    printf("  ");
                }
                if (g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X + 1] == 2)
                {
                    g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X + 1] = 1;
                    Posxy(g_BulletArr[i].Pos.X + 1, g_BulletArr[i].Pos.Y);
                    printf("  ");
                }

                break;
            }
            case LEFT:
            case RIGHT:
            {
                g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X] = 1;            //如果方向为左右则判断土墙上下是否为土墙
                Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);                 //如果有土墙则清除
                printf("  ");
                if (g_Map1[g_BulletArr[i].Pos.Y - 1][g_BulletArr[i].Pos.X] == 2)
                {
                    g_Map1[g_BulletArr[i].Pos.Y - 1][g_BulletArr[i].Pos.X] = 1;
                    Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y - 1);
                    printf("  ");
                }

                if (g_Map1[g_BulletArr[i].Pos.Y + 1][g_BulletArr[i].Pos.X] == 2)
                {
                    g_Map1[g_BulletArr[i].Pos.Y + 1][g_BulletArr[i].Pos.X] = 1;
                    Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y + 1);
                    printf("  ");
                }
                break;
            }
            }
            for (int j = i; j < g_BulletNum - 1; j++)                          //最后将该子弹清除
            {
                g_BulletArr[j] = g_BulletArr[j + 1];
            }
            g_BulletNum--;
            IfMove = 0;
        }
        else if (g_Map1[g_BulletArr[i].Pos.Y][g_BulletArr[i].Pos.X] == 3)      //判断击中铁墙
        {
            Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);                 //将铁墙打印出来后,清除该子弹
            Color(7);
            printf("■");
            for (int j = i; j < g_BulletNum - 1; j++)
            {
                g_BulletArr[j] = g_BulletArr[j + 1];
            }
            g_BulletNum--;
            IfMove = 0;
        }
        if (IfMove)
        { 
            BulletMove(&g_BulletArr[i]);                            //子弹根据方向移动
        }

        for (int j = 0; j < g_BulletNum; j++)                       //再次遍历所有子弹坐标
        {
            if (j == i)                                             //如果i==j则判断是同一个子弹数据
            {
                continue;
            }
                                                                     //判断两个子弹的坐标相同
            if (g_BulletArr[i].Pos.X == g_BulletArr[j].Pos.X&&g_BulletArr[i].Pos.Y == g_BulletArr[j].Pos.Y)
            {
                if (g_BulletArr[i].IfMe != g_BulletArr[j].IfMe)     //坐标相同子弹的敌我判定,决定是否清除
                {
                    Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);
                    printf("  ");                                   //先将对应坐标图案擦除

                    if (j > i)                                      //判断子弹在数组中的先后决定清除顺序
                    {                                               //防止清除靠前的数据后,靠后的数据清除错误
                        for (int t = j; t < g_BulletNum - 1; t++)
                        {
                            g_BulletArr[t] = g_BulletArr[t + 1];
                        }
                        g_BulletNum--;

                        for (int t = i; t < g_BulletNum - 1; t++)
                        {
                            g_BulletArr[t] = g_BulletArr[t + 1];
                        }
                        g_BulletNum--;
                    }
                    else
                    {
                        for (int t = i; t < g_BulletNum - 1; t++)
                        {
                            g_BulletArr[t] = g_BulletArr[t + 1];
                        }
                        g_BulletNum--;

                        for (int t = j; t < g_BulletNum - 1; t++)
                        {
                            g_BulletArr[t] = g_BulletArr[t + 1];
                        }
                        g_BulletNum--;

                    }
                    return 0;
                }
            }
        }


        if (g_BulletArr[i].IfMe == 1)                                             //判断子弹为我方
        {
            for (int Temp = 0; Temp < TankAINum; Temp++)                          //遍历AI坦克坐标
            {
                if (Box(g_BulletArr[i].Pos, TankAI[Temp].Pos))                    //如果我方子弹击中AI坦克碰撞箱
                {
                    TankAI[Temp].HP = 0;
                    ErasureTank(TankAI[Temp]);
                    for (int TempB = Temp; TempB < TankAINum - 1; TempB++)
                    {
                        TankAI[TempB] = TankAI[TempB + 1];
                    }
                    TankAINum--;
                    Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);
                    printf("  ");
                    for (int j = i; j < g_BulletNum - 1; j++)                     //该子弹清除
                    {
                        g_BulletArr[j] = g_BulletArr[j + 1];
                    }
                    g_BulletNum--;
                    return 0;
                }
            }
        }
        else                                                                      //判断子弹为敌方
        {
            if (Box(g_BulletArr[i].Pos, tank->Pos))                               //判断子弹是否击中玩家坦克碰撞箱
            {
                tank->HP--;
                tank->Life = 0;
                ErasureTank(*tank);
                Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);
                printf("  ");
                for (int j = i; j < g_BulletNum - 1; j++)                         //清除该子弹
                {
                    g_BulletArr[j] = g_BulletArr[j + 1];
                }
                g_BulletNum--;
                return 0;
            }
        }

        if (g_Map[g_BulletArr[i].Pos.X][g_BulletArr[i].Pos.Y] == 0)            //如果子弹打到边界
        {
            if (g_BulletArr[i].Pos.X == 0 || g_BulletArr[i].Pos.X == N + 1)
            {
                Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);
                Color(0xF);
                printf("┃");
            }
            else
            {
                Posxy(g_BulletArr[i].Pos.X, g_BulletArr[i].Pos.Y);
                Color(0xF);
                printf("━");
            }

            for (int j = i; j < g_BulletNum - 1; j++)                         //将子弹数组依次覆盖当前被消除的下标
            {
                g_BulletArr[j] = g_BulletArr[j + 1];
            }
            g_BulletNum--;                                                    //子弹总数自减1
        }

    }
}

control.h

#pragma once

#include<windows.h>
#include<stdio.h>
#include"tank.h"
#include"bullet.h"

//隐藏光标
void ShowCursorA();

//移动光标
void Posxy(int x, int y);

//更改输出颜色
void Color(int color);

//设置控制台窗口及缓冲区大小
int SetWindowsSize(char *pszWindowTitle, int nX, int nY);


//获取键盘输入
void GetPlayerInput(Tank* tank);

//控制游戏进行
void Game(int IfLoad);

//菜单
void Menu();

//暂停
void Pause();

//存档
void Save(Tank *tank);

//读档
void Load(Tank *tank);

control.c

#include"control.h"


void ShowCursorA()
{
    HANDLE hOutStd = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO cci;
    cci.dwSize = 1;
    cci.bVisible = 0;
    SetConsoleCursorInfo(hOutStd, &cci);
}

void Posxy(int x, int y)
{
    COORD Pos;
    HANDLE hOus = GetStdHandle(STD_OUTPUT_HANDLE);
    Pos.X = x * 2;
    Pos.Y = y;
    SetConsoleCursorPosition(hOus, Pos);
}

void Color(int color)
{
    HANDLE hOutstd = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hOutstd, color);
}

//设置控制台窗口及缓冲区大小
int SetWindowsSize(char *pszWindowTitle,int nX,int nY)
{
    //设置控制台标题
    SetConsoleTitleA(pszWindowTitle);
    HANDLE hStdin, hStdout;
    hStdin = GetStdHandle(STD_INPUT_HANDLE);
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    //获取最大控制台窗口大小
    COORD pos = GetLargestConsoleWindowSize(hStdout);
    COORD BufferSize = { pos.X + 1, pos.Y + 1 };
    //设置控制台缓冲区大小
    if (!SetConsoleScreenBufferSize(hStdout, BufferSize))
    {
        //设置控制台缓冲区失败
        printf("buffer err(%d %d) %d\n", BufferSize.X, BufferSize.Y, GetLastError());
        return 0;
    }
    SMALL_RECT srctWindow = { 0, 0, nX, nY };
    if (!SetConsoleWindowInfo(hStdout, 1, &srctWindow))
    {
        //设置控制台窗口大小
        printf("size err %d\n", GetLastError());
        return 0;
    }
    COORD Buffer = { nX + 1, nY + 1 };
    //设置控制台缓冲区大小
    if (!SetConsoleScreenBufferSize(hStdout, Buffer))
    {
        //设置控制台窗口缓冲区失败
        printf("buffer err(%d %d) %d\n", BufferSize.X, BufferSize.Y, GetLastError());
        return 0;
    }
    return 1;

}

//获取键盘输入
void GetPlayerInput(Tank* tank)
{
    COORD A = { 30, 30 };
    if (GetAsyncKeyState(VK_SPACE))
    {
        Save(tank);
        Pause();
    }
    else if (GetAsyncKeyState(VK_DOWN))
    {
        tank->Direction = 2;
        TankMove(tank);
    }
    else if (GetAsyncKeyState(VK_LEFT))
    {
        tank->Direction = 3;
        TankMove(tank);
    }
    else if (GetAsyncKeyState(VK_RIGHT))
    {
        tank->Direction = 4;
        TankMove(tank);
    }
    else if (GetAsyncKeyState(VK_ESCAPE))
    {
        exit(0);
    }
    else if (GetAsyncKeyState(VK_UP))
        {
            tank->Direction = 1;
            TankMove(tank);
        }
}

//控制游戏进行
void Game(int IfLoad)
{
    int nCount = 0;               //计数器,防止坦克移动过快

    Tank Player;                  //坦克初始化
    if (IfLoad == 1)
    {

        Player.HP = 3;
        CreatPlayer(&Player);


    }
    else
    {
        Load(&Player);
        /*for (int i = 0; i < TankAINum; i++)
        {
            TankPtfA(TankAI[i]);
        }*/
    }
    PtfMap();                //打印地图
    Init();                  //初始化边界

    TankPtfA(Player);

    while (1)
    {


        if (Player.HP > 0)
        {
            if (Player.Life == 0)
            {
                if (g_Map1[38][14] == 1
                    && g_Map1[37][13] == 1
                    && g_Map1[37][14] == 1
                    && g_Map1[37][15] == 1
                    && g_Map1[38][13] == 1
                    && g_Map1[38][15] == 1
                    && g_Map1[39][13] == 1
                    && g_Map1[39][15] == 1
                    && g_Map1[39][14] == 1)

                {
                    CreatPlayer(&Player);
                    TankPtfA(Player);
                }
            }
        }
        else
        {
            Posxy(0, 43);
            printf("Game Over!");
            system("pause");
            break;
        }
        if (TankAINum == 0)
        {
            if (CreatTankAI(&TankAI[TankAINum]))
            {
                TankPtfA(TankAI[TankAINum]);
                TankAINum++;
            }
        }
        if (nCount %  1 == 0)
        {
            if (TankAINum < 80)
            {
                if (CreatTankAI(&TankAI[TankAINum]))
                {
                    TankPtfA(TankAI[TankAINum]);
                    TankAINum++;
                }
            }
        }
        if (nCount % 2 == 0)
        {
            for (int i = 0; i < TankAINum; i++)
            {
                TankAIMove(&TankAI[i]);
                if (TankAI[i].BulletCD >= 1)
                    TankAI[i].BulletCD--;
                if (TankAI[i].BulletCD <= 1)
                {
                    CreatBullet(&TankAI[i]);
                }

            }

        }

        BulletTest(&Player);
        if (Player.BulletCD != 0)
            Player.BulletCD--;


        nCount++;
        if (nCount % 2 == 0 && Player.Life == 1)                  //每循环两次才能移动
        {
            GetPlayerInput(&Player);
        }
        Sleep(60);

        Posxy(43, 7);
        Color(0xF);
        printf("HP:%3d", Player.HP);
    }
}

//菜单
void Menu()
{
    while (1)
    {
        system("cls");
        Color(0xF);
        printf("1.开始游戏\n");
        printf("2.读取存档\n");
        printf("3.绘制地图\n");
        printf("4.退出游戏\n");
        char ch = getchar();
        switch (ch)
        {
        case '1':
            system("cls");
            Game(1); 
            break;
            case '2':
                system("cls");
                Game(0);
                break;
            case '3':
                system("cls");
                DrawMap();

                break;
            case '4':exit(0); break;
        }

    }
}

//暂停
void Pause()
{
    //Posxy(0, 44);
    //printf("再次按下空格回到游戏");
    while (1)
    {
        Sleep(200);
        if (GetAsyncKeyState(VK_SPACE))break;
    }
}

void Save(Tank *tank)
{
    FILE *fp;
    for (int i = 0; i < TankAINum; i++)
    {
        ErasureTank(TankAI[i]);
    }
    ErasureTank(*tank);
    if (fopen_s(&fp, "INFO.txt", "wb"))printf("error");
    fwrite(g_Map1, sizeof(g_Map1), 1, fp);
    fwrite(&g_BulletNum, sizeof(int), 1, fp);
    fwrite(g_BulletArr, sizeof(g_BulletArr), 1, fp);
    fwrite(&TankAINum, sizeof(int), 1, fp);
    fwrite(TankAI, sizeof(TankAI), 1, fp);
    fwrite(tank, sizeof(Tank), 1, fp);
    fclose(fp);
    for (int i = 0; i < TankAINum; i++)
    {
        TankPtfA(TankAI[i]);
    }
    TankPtfA(*tank);
    //Posxy(0, 43);
    //printf("OK");

}

void Load(Tank *tank)
{

    FILE *fp;
    if (fopen_s(&fp, "INFO.txt", "rb"))printf("error");
    fread(g_Map1, sizeof(g_Map1), 1, fp);
    fread(&g_BulletNum, sizeof(int), 1, fp);
    fread(&g_BulletArr[0], sizeof(g_BulletArr), 1, fp);
    fread(&TankAINum, sizeof(int), 1, fp);
    fread(TankAI, sizeof(TankAI), 1, fp);
    fread(tank, sizeof(Tank), 1, fp);
    fclose(fp);
}

main.c

#include<windows.h>
#include<time.h>
#include"Map.h"
#include"control.h"
#include"tank.h"
#include"bullet.h"




int main()
{
    srand((unsigned)time(NULL));
    //system("mode con cols=100 lines=43");
    SetWindowsSize("坦克小战", 100, 43);
    ShowCursorA();
    Menu();
    return 0;
}
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值