坦克大战游戏之经典源码

头像
C/C 班主任-魏少东
2017-01-10 19:53:42

 我相信这个游戏的话对于大家可能会比较难,在大学很少有接触这种类型的游戏,但是大家可以看看这个代码,如果基础好的话可以考试看完后尝试做一个类似的游戏,然后遇到不懂的地方可以多在社区讨论交流,没有基础的同学也不用担心,我每天晚上21:00-22:00都有C语言在线直播互动课哟,大家可以跟着我一起学习,我带大家一起学习,学习地址:

http://www.xsteach.com/live/course/view?id=304&spread_id=7612078

坦克大战之经典源码

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy

#include<iostream>

#include<stdlib.h>

#include<tchar.h>

#include<Windows.h>

#include<time.h>

#include<conio.h>

using namespace std;


HANDLE Mutex = CreateMutex(NULL, FALSE, NULL);//互斥对象


int GameOver = 0;

int level = 0;

int map[23][23];

//坦克种类,Normal为玩家坦克

#define Normal 0

#define Red 1

#define Blue 2

#define Green 3

//方向的宏定义

#define Up 0

#define Down 1

#define Left 2

#define Right 3

//地图标记的宏定义

#define Empty 0

#define Player 1

#define PlayerBullet 2

#define EnemyBullet 3

#define Enemy 4


int Kill;

int KillRed;

int KillGreen;

int EnemyExist;


void SetPos(int i, int j)//设定光标位置

{

COORD pos = { i, j };

HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);

SetConsoleCursorPosition(Out, pos);

}


void HideCurSor(void)//隐藏光标

{

CONSOLE_CURSOR_INFO info = { 1, 0 };

HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);

SetConsoleCursorInfo(Out, &info);

}


int sharp[4][12] =

{

{ 0, 1, 1, 0, 1, 1, 1, 2, 2, 0, 2, 2 },

{ 0, 0, 0, 2, 1, 0, 1, 1, 1, 2, 2, 1 },

{ 0, 1, 0, 2, 1, 0, 1, 1, 2, 1, 2, 2 },

{ 0, 0, 0, 1, 1, 1, 1, 2, 2, 0, 2, 1 },

};//此数组用来保存坦克各个方向的形状信息


DWORD WINAPI Bulletfly(LPVOID lpParameter);//子弹函数申明

void Updata();//更新界面信息函数申明


class Tank//坦克类

{

private:

int Direction;//方向

int hotpoint[2];//活动点

int Speed;//速度

int FirePower;//火力

public:

Tank(int dir, int hot1, int hot2, int typ, int spe, int firepow)//构造函数

{

Direction = dir;

hotpoint[0] = hot1;

hotpoint[1] = hot2;

Type = typ;

Speed = spe;

FirePower = firepow;

}

int Type;//坦克的种类(详见宏定义)

int ID;//坦克在MAP中的标记(详见宏定义)

int FireEnable;//是否可以开火

int Life;//生命值

void Running();//运行函数

int Judge(int x, int y, int ID);//判断是否可以绘制坦克

void DrawTank();//重绘坦克

void Redraw();//擦除坦克

int GetSpeed()//获取速度

{

return Speed;

}

int GetFire()//获取火力

{

return FirePower;

}

int GetDirection()//获取方向

{

return Direction;

}

int GetHotX()//获取活动点坐标

{

return hotpoint[0];

}

int GetHotY()

{

return hotpoint[1];

}

void IncreaseFire()//火力+

{

FirePower++;

}

void IncreaseSpeed()//速度+

{

Speed++;

}

void ChangeDirection(int newD)//改变方向

{

Direction = newD;

}

void ChangePos(int x, int y)//改变活动点

{

hotpoint[0] = x;

hotpoint[1] = y;

}

};


Tank player(Right, 0, 0, Normal, 1, 1);//玩家

Tank enemy(Left, 20, 0, Red, 1, 1);//敌人


void Tank::DrawTank()//绘制坦克

{

int i;

int nx, ny;

if (Type == Red)

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);

else if (Type == Blue)

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);

else if (Type == Green)

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);

else if (Type == Normal)

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

for (i = 0; i<6; i++)

{

nx = hotpoint[0] + sharp[Direction][i * 2];

ny = hotpoint[1] + sharp[Direction][i * 2 + 1];

SetPos((ny + 1) * 2, nx + 1);//利用sharp数组相对于点x,y绘制形状

map[nx][ny] = ID;

cout << "■";

}

}


void Tank::Redraw()//擦除坦克,原理同上

{

int i;

int nx, ny;

for (i = 0; i<6; i++)

{

nx = hotpoint[0] + sharp[Direction][i * 2];

ny = hotpoint[1] + sharp[Direction][i * 2 + 1];

map[nx][ny] = Empty;

SetPos((ny + 1) * 2, nx + 1);

cout << " ";

}

}


int Tank::Judge(int x, int y, int dir)//判断当前是否可以绘制坦克

{

int i;

int nx, ny;

for (i = 0; i<6; i++)

{

nx = x + sharp[dir][i * 2];

ny = y + sharp[dir][i * 2 + 1];

if (nx<0 || nx >= 23 || ny<0 || ny >= 23 || map[nx][ny] != Empty)//不能绘制,返回1

return 1;

}

return 0;

}



void Tank::Running()//坦克运行函数

{

int newD;

//坦克的运行

while (1)

{

if (Life == 0)

{

EnemyExist = 0;//敌人不存在

return;

}

if (GameOver == 1)

return;

if (FireEnable == 1 && GameOver == 0)//如果可以开火

{

WaitForSingleObject(Mutex, INFINITE);//线程拥有互斥对象

FireEnable = 0;//设为不可开火

HANDLE bullet = CreateThread(NULL, 0, Bulletfly, &ID, 0, NULL);//创建子弹线程

CloseHandle(bullet);

ReleaseMutex(Mutex);//释放互斥对象

Sleep(100);

}

WaitForSingleObject(Mutex, INFINITE);//线程拥有互斥对象

srand((int)time(0));

newD = rand() % 4;


if (newD == Up)//随机出新的方向并重新绘制坦克

{

Redraw();

if (Judge(hotpoint[0] - 1, hotpoint[1], newD) == 0)

{

hotpoint[0]--;

Direction = newD;

}

else

{

if (Judge(hotpoint[0], hotpoint[1], newD) == 0)

Direction = newD;

}

}

else if (newD == Down)

{

Redraw();

if (Judge(hotpoint[0] + 1, hotpoint[1], newD) == 0)

{

hotpoint[0]++;

Direction = newD;

}

else

{

if (Judge(hotpoint[0], hotpoint[1], newD) == 0)

Direction = newD;

}

}

else if (newD == Left)

{

Redraw();

if (Judge(hotpoint[0], hotpoint[1] - 1, newD) == 0)

{

hotpoint[1]--;

Direction = newD;

}

else

{

if (Judge(hotpoint[0], hotpoint[1], newD) == 0)

Direction = newD;

}

}

else if (newD == Right)

{

Redraw();

if (Judge(hotpoint[0], hotpoint[1] + 1, newD) == 0)

{

hotpoint[1]++;

Direction = newD;

}

else

{

if (Judge(hotpoint[0], hotpoint[1], newD) == 0)

Direction = newD;

}

}

if (GameOver == 0 && Life != 0)

DrawTank();

ReleaseMutex(Mutex);//释放互斥对象

Sleep(500 - 80 * Speed);

}

}


/*********************子弹线程函数*******************/

DWORD WINAPI Bulletfly(LPVOID lpParameter)

{

int *ID = (int *)lpParameter;//ID用来获取发射子弹坦克的ID

int Pos[2];//子弹活动点

int direction;

int Speed;

int type;

int hit = 0;//击中标记

int oldx, oldy;//旧活动点

int flag = 0;//子弹是否有移动的标记

if (*ID == Player)//如果是玩家坦克

{

type = PlayerBullet;

direction = player.GetDirection();

Speed = player.GetFire();

Pos[0] = player.GetHotX();

Pos[1] = player.GetHotY();

}

else if (*ID == Enemy)//如果是敌人坦克

{

type = EnemyBullet;

direction = enemy.GetDirection();

Speed = enemy.GetFire();

Pos[0] = enemy.GetHotX();

Pos[1] = enemy.GetHotY();

}

if (direction == Up)//根据坦克的位置和方向确定子弹的初始坐标

{

Pos[0]--;

Pos[1]++;

}

else if (direction == Down)

{

Pos[0] += 3;

Pos[1]++;

}

else if (direction == Left)

{

Pos[0]++;

Pos[1]--;

}

else if (direction == Right)

{

Pos[0]++;

Pos[1] += 3;

}

//子弹的运行

while (1)

{

WaitForSingleObject(Mutex, INFINITE);//这个不再注释了。。。。。

if (flag == 1 && hit != 1)//擦除原位置

{

map[oldx][oldy] = Empty;

SetPos((oldy + 1) * 2, oldx + 1);

cout << " ";

}

if (GameOver == 1)

return 0;

if (hit == 1 || Pos[0]<0 || Pos[0]>22 || Pos[1]<0 || Pos[1]>22)//如果击中

{

ReleaseMutex(Mutex);

Sleep(500);

if (type == PlayerBullet)

player.FireEnable = 1;

else if (type = EnemyBullet)

enemy.FireEnable = 1;

break;

}

switch (map[Pos[0]][Pos[1]])//子弹经过的MAP的标记

{


case Empty://如果是空位置就绘制子弹

map[Pos[0]][Pos[1]] = type;

SetPos((Pos[1] + 1) * 2, Pos[0] + 1);

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

cout << "■";

break;

case Player://如果是玩家位置

if (type != PlayerBullet)

{

player.Life--;//生命减少

if (player.Life <= 0)

GameOver = 1;

}

Updata();

hit = 1;

break;

case Enemy://如果是敌人位置

if (type != PlayerBullet)

hit = 1;

else

{

hit = 1;

Kill++;

if (Kill % 20 == 0 && player.Life<5)//击杀数++

player.Life++;

if (enemy.Type == Red)//如果击杀红坦克

{

KillRed++;

if (KillRed % 10 == 0 && player.GetFire()<5)

player.IncreaseFire();

}

if (enemy.Type == Green)///如果击杀绿坦克

{

KillGreen++;

if (KillGreen % 10 == 0 && player.GetSpeed()<5)

player.IncreaseSpeed();

}

enemy.Redraw();//擦除敌人

enemy.Life = 0;//敌人死亡

}

Updata();

break;

}

oldx = Pos[0];

oldy = Pos[1];

if (direction == Up)//子弹移动

Pos[0]--;

else if (direction == Down)

Pos[0]++;

else if (direction == Left)

Pos[1]--;

else if (direction == Right)

Pos[1]++;

ReleaseMutex(Mutex);

flag = 1;

Sleep(60 - 10 * Speed);

}

return 0;

}



/*************************敌人线程函数***************************/

DWORD WINAPI TankRuning(LPVOID lpParameter)

{

Sleep(400);

int Pos;

int Start[2];//敌人起始地址

int typ;

int fire;

int spe;

while (1)

{

if (GameOver == 1)

return 0;

srand((int)time(0));//随机出敌人起始地址

Pos = rand() % 4;

if (Pos == 0)

{

Start[0] = 2;

Start[0] = 2;

}

else if (Pos == 1)

{

Start[0] = 2;

Start[1] = 18;

}

else if (Pos == 2)

{

Start[0] = 18;

Start[1] = 2;

}

else if (Pos == 3)

{

Start[0] = 18;

Start[1] = 18;

}

if (player.Judge(Start[0], Start[1], Down) == 0)

break;

}

WaitForSingleObject(Mutex, INFINITE);

srand((int)time(0));

typ = rand() % 3 + 1;//随机出敌人的种类

if (typ == Blue)

{

spe = 1 + level;

fire = 1 + level;

}

else if (typ == Red)

{

spe = 1 + level;

fire = 3 + level;

}

else if (typ == Green)

{

spe = 3 + level;

fire = 1 + level;

}

enemy = Tank(Down, Start[0], Start[1], typ, spe, fire);//重新生成敌人坦克

enemy.ID = Enemy;

enemy.Life = 1;

enemy.FireEnable = 1;

ReleaseMutex(Mutex);

enemy.Running();

return 0;

}



void Init()//初始化函数

{

Kill = 0;

KillRed = 0;

KillGreen = 0;

player = Tank(Left, 0, 0, Normal, 1, 1);

enemy = Tank(Left, 0, 0, Red, 1, 1);

player.Life = 2;

player.FireEnable = 1;

enemy.Life = 0;

enemy.FireEnable = 1;

player.ID = Player;

enemy.ID = Enemy;

EnemyExist = 0;

}


void Updata()//更新界面信息

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

int i;

SetPos(53, 0);

cout << "生命值:";

SetPos(53, 1);

for (i = 0; i<5; i++)

{

if (i<player.Life)

cout << "■";

else

cout << " ";

}

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);

SetPos(53, 3);

cout << "移动速度:";

SetPos(53, 4);

for (i = 0; i<5; i++)

{

if (i<player.GetSpeed())

cout << "■";

else

cout << " ";

}

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);

SetPos(53, 5);

cout << "火力:";

SetPos(53, 6);

for (i = 0; i<5; i++)

{

if (i<player.GetFire())

cout << "■";

else

cout << " ";

}

SetPos(53, 8);

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

cout << "杀敌数:" << Kill;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);

SetPos(53, 9);

cout << "杀死红坦克:" << KillRed;

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);

SetPos(53, 10);

cout << "杀死绿坦克:" << KillGreen;


}

void DrawMap()//画界面

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

system("cls");

int i;

for (i = 0; i<25; i++)

{

SetPos(i * 2, 0);

cout << "■";

}

for (i = 1; i<25; i++)

{

SetPos(0, i);

cout << "■";

SetPos(24 * 2, i);

cout << "■";

}

for (i = 0; i<25; i++)

{

SetPos(i * 2, 24);

cout << "■";

}


Updata();


}


void Welcome()//欢迎界面

{

int x;

system("cls");

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);

SetPos(10, 5);

cout << "■■■■■■■■■■■■■■■■■■■■■■■■";

SetPos(10, 6);

cout << "■        坦克大战控制台版                    ■";

SetPos(10, 7);

cout << "■■■■■■■■■■■■■■■■■■■■■■■■";

SetPos(10, 8);

cout << "■       方向键移动,空格键射击               ■";

SetPos(10, 9);

cout << "■       敌人分为3种,蓝色为普通敌人          ■";

SetPos(10, 10);

cout << "■     红色敌人高射速,绿色敌人高机动性       ■";

SetPos(10, 11);

cout << "■ 每杀死10个红坦克,玩家射速提高(最高五级)  ■";

SetPos(10, 12);

cout << "■ 每杀死10个绿坦克,玩家移动性提高(最高五级)■";

SetPos(10, 13);

cout << "■   每杀死20个坦克,玩家生命+1(最高五格)   ■";

SetPos(10, 14);

cout << "■■■■■■■■■■■■■■■■■■■■■■■■";

SetPos(10, 15);

cout << "■    魏少东作(想学习加我qq2557171836)             ■";

SetPos(10, 16);

cout << "■           按1-3选择难度                    ■";

SetPos(10, 17);

cout << "■■■■■■■■■■■■■■■■■■■■■■■■";

while (1)

{

x = _getch();

if (x <= '3'&&x >= '1')

break;

}

level = x - '0' - 1;

}


int _tmain(int argc, TCHAR* argv[]) {

Init();

HideCurSor();

Welcome();

DrawMap();

HANDLE temp;

int newD;

player.DrawTank();

while (GameOver == 0)

{

if (GetAsyncKeyState(VK_UP))//按键上

{

WaitForSingleObject(Mutex, INFINITE);

newD = Up;

player.Redraw();

if (player.Judge(player.GetHotX() - 1, player.GetHotY(), newD) == 0)//移动玩家坦克,原理和敌人函数一样

{

player.ChangePos(player.GetHotX() - 1, player.GetHotY());

player.ChangeDirection(newD);

}

else

{

if (player.Judge(player.GetHotX(), player.GetHotY(), newD) == 0)

player.ChangeDirection(newD);

}

if (GameOver == 0)

player.DrawTank();

ReleaseMutex(Mutex);

Sleep(200 - player.GetSpeed() * 20);//按键延迟,决定玩家坦克的速度

}

else if (GetAsyncKeyState(VK_DOWN))//按键下,同上

{

WaitForSingleObject(Mutex, INFINITE);

newD = Down;

player.Redraw();

if (player.Judge(player.GetHotX() + 1, player.GetHotY(), newD) == 0)

{

player.ChangePos(player.GetHotX() + 1, player.GetHotY());

player.ChangeDirection(newD);

}

else

{

if (player.Judge(player.GetHotX(), player.GetHotY(), newD) == 0)

player.ChangeDirection(newD);

}

if (GameOver == 0)

player.DrawTank();

ReleaseMutex(Mutex);

Sleep(200 - player.GetSpeed() * 20);

}

else if (GetAsyncKeyState(VK_RIGHT))//按键右,同上

{

WaitForSingleObject(Mutex, INFINITE);

newD = Right;

player.Redraw();

if (player.Judge(player.GetHotX(), player.GetHotY() + 1, newD) == 0)

{

player.ChangePos(player.GetHotX(), player.GetHotY() + 1);

player.ChangeDirection(newD);

}

else

{

if (player.Judge(player.GetHotX(), player.GetHotY(), newD) == 0)

player.ChangeDirection(newD);

}

if (GameOver == 0)

player.DrawTank();

ReleaseMutex(Mutex);

Sleep(200 - player.GetSpeed() * 20);

}

老师QQ:2557171836

else if (GetAsyncKeyState(VK_LEFT))//按键左,同上

{

WaitForSingleObject(Mutex, INFINITE);

newD = Left;

player.Redraw();

if (player.Judge(player.GetHotX(), player.GetHotY() - 1, newD) == 0)

{

player.ChangePos(player.GetHotX(), player.GetHotY() - 1);

player.ChangeDirection(newD);

}

else

{

if (player.Judge(player.GetHotX(), player.GetHotY(), newD) == 0)

player.ChangeDirection(newD);

}

if (GameOver == 0)

player.DrawTank();

ReleaseMutex(Mutex);

Sleep(110 - player.GetSpeed() * 10);

}

else if (GetAsyncKeyState(VK_SPACE))//按键空格,发射子弹

{

WaitForSingleObject(Mutex, INFINITE);

if (player.FireEnable == 1)//如果可以发射

{

HANDLE bullet = CreateThread(NULL, 0, Bulletfly, &(player.ID), 0, NULL);//创建玩家子弹进程

CloseHandle(bullet);

player.FireEnable = 0;

}

ReleaseMutex(Mutex);

}

if (EnemyExist == 0 && GameOver == 0)//如果敌人不存在生成新敌人

{

WaitForSingleObject(Mutex, INFINITE);

EnemyExist = 1;

temp = CreateThread(NULL, 0, TankRuning, NULL, 0, NULL);//创建敌人线程

CloseHandle(temp);

ReleaseMutex(Mutex);

}

}

system("cls");

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);

SetPos(20, 10);

cout << "游戏结束" << endl;

SetPos(20, 11);

cout << "杀敌数:" << Kill;

SetPos(20, 12);

cout << "杀死红坦克" << KillRed;

SetPos(20, 13);

cout << "杀死绿坦克" << KillGreen << endl;

return 0;

}

关注***公众号:编程语言

有更多(C/C++语言,linux,JAVA语言)高手帮助你解决难题,一起互动,提高大家的编程水平

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy


全部回复
正序查看
空数据
暂无评论