C++实现经典坦克大战(一)

简介

本项目是基于easyX库来实现的一个C++版本的经典坦克大战的游戏界面。

easyX库的下载及安装使用

easyX的全称为EasyX Graphics Library,是针对与Visual C++的免费绘图库,支持 VC6.0 ~ VC2019,简单易用,学习成本极低,应用领域广泛。
easyX的下载链接附上:
https://easyx.cn/download/EasyX_20210224.exe

  1. 双击打开可执行文件
    C++实现经典坦克大战(一)
  2. 按照提示进行
    C++实现经典坦克大战(一)
    C++实现经典坦克大战(一)
    选择需要安装的编译器,一般都会自动检测到。安装完毕之后可再编译器中检测一下,输入以下代码,若不出现报错,则安装成功
    #include<graphics.h>
    int main()
    {
    	initgraph(650, 650);//创建一个650 ×650 的画布
    	system("pause");
    }
    

总体思路

首先,在我们创建任何游戏之前必然会有一个总体思路,即实现游戏的过程。在实现本次坦克大战的过程中,作者我主要是一下思路:

  1. 首先,我们需要创建一个画布,来构造我们游戏所需要的基本界面。
  2. 齐次,在已构造的画布中布局相关菜单和地图,从而进行游戏界面初始化。
  3. 最后,进行游戏相关功能的实现。
  4. 所以,作者所写的代码中主要包括三个函数,分别是开始场景,初始化地图,以及游戏开始这三个函数。
#include<graphics.h>
int main()
{
	initgraph(650, 650);//创建一个650 ×650 的画布
	menu() //初始化菜单
	init_map(&map[0][0], 26, 26);//初始化地图
	play();//游戏开始
	system("pause");
}

实现初始化菜单

先上效果图
C++实现经典坦克大战(一)
为实现这个效果图,我将他分为三个部分:

  1. logo部分
  2. 说明 部分
  3. 开始 部分

实现logo部分

在网络上查找logo的效果图,
C++实现经典坦克大战(一)
将图片加载到画布上:

//显示logo
IMAGE logo_img; //定义一个IMAGE对象 logo_img
loadimage(&logo_img, _T("logo.bmp"), 433, 147);//将图片加载到logo_img里面去
putimage(110, 20, &logo_img); //显示图片

实现说明部分

说明部分包括外部的方框,以及其中的说明二字,可以直接使用easyX中自带的fillrectangle 函数以及outtextxy函数,直接上代码:

setlinecolor(WHITE);//设置方框边框线的颜色
setfillcolor(BLACK);//设置方框填充的颜色
fillrectangle(220, 200, 300, 240);
settextstyle(25, 0, _T("宋体"));//设置字体类型
outtextxy(230, 210, _T("说明"));//显示字体

实现开始部分

话不多说,直接上代码:

fillrectangle(350, 200, 430, 240);
outtextxy(360, 210, _T("开始"));

初始化界面的一些简单操作

如果你前面的代码内容都操作无误的话,现在运行之后应该已经得到这样的结果了:
C++实现经典坦克大战(一)
但是我们正常游戏界面并不希望是这样的,我们希望的是这样的效果:
C++实现经典坦克大战(一)
所以还进行鼠标信息的处理,来实现鼠标一到达说明所在的位置,即可出现说明菜单的内容。同时,我们还希望在点击开始按键的时候,可以直接打开一个新的界面,进行游戏操作。好了,话不多说,直接上代码:

MOUSEMSG mouse; //定义一个MOUSEMSG对象的mouse,用来获取鼠标信息
IMAGE illustrate_img;//定义一个IMAGE类
loadimage(&illustrate_img, _T("illustrate.jpg"), 300, 300);//加载图片
while (1) {
	mouse = GetMouseMsg();
	switch (mouse.uMsg) {
	case WM_MOUSEMOVE:
		if (mouse.x > 220 && mouse.x < 300 && mouse.y > 200 && mouse.y < 240) {
			putimage(150, 250, &illustrate_img);
		}
		else {
			solidrectangle(150, 250, 450, 550);
		}
		break;
	case WM_LBUTTONDOWN:
		if ((mouse.x > 350 && mouse.x < 430) && (mouse.y > 200 && mouse.y < 240)) {
			cleardevice();//清空
		}
		else
		{
			break;
		}
		return;
	}
}

//注释: while循环中的内容主要为获取并分析鼠标的操作,因为鼠标经常性移动,多以创建的MOUSEMSG 类别的变量mouse必须时刻更新鼠标状态。switch语句用来分析鼠标状态:

  1. WM_MOUSEMOVE语句用来判断鼠标移动位置
  2. WM_LBUTTONDOWN语句用来判断鼠标点击情况

至此,我们就可以实现一个基本的坦克大战初始化界面了。

实现游戏界面

实现游戏地图

玩过坦克大战游戏的都知道,我们进入游戏之后首先进入我们目光的就是游戏地图,而不同关卡的一个很大区别也是地图的不同。
所以如何实现地图显得至关重要。
如果想实现花里胡哨的游戏界面,那么图片必然是不可或缺的,所以卑微作者我的思路也就是通过加载地图图片来实现游戏的地图,话不多说,先上代码为敬:

void init_map2(int* map, int rows, int cols)
{
	IMAGE img_home, img_wall_1, img_wall_2;
	loadimage(&img_home, _T("home.jpg"), 50, 50);
	loadimage(&img_wall_1, _T("wall1.jpg"), 25, 25);//不可消除的墙
	loadimage(&img_wall_2, _T("wall2.jpg"), 25, 25);//可消除的墙

	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			if (*(map + i * cols + j) == 1)
			{
				putimage(25 * j, 25 * i, &img_wall_2);
			}
			else if (*(map + i * cols + j) == 2)
			{
				putimage(25 * j, 25 * i, &img_wall_1);
			}
			else if (*(map + i * cols + j) == 3)
			{
				putimage(25 * j, 25 * i, &img_home);

				*(map + i * cols + j) = 4;
				*(map + i * cols + j + 1) = 4;
				*(map + (i + 1) * cols + j) = 4;
				*(map + (i + 1) * cols + j + 1) = 4;
			}
		}
	}
}

*//注释:*因为在游戏中背景地图应该是包括三个部分,即老鹰和两种墙(可消除墙和不可消除墙),则本项目中就通过构造三个IMAGE对象:

img_home
img_wall_1
img_wall_2

来实现老巢(老鹰)可消除墙、和不可消除墙的图片加载。
而加载后的图片应该如何展示出来呢,又应该在哪些位置展示呢,这就是后序循环中所实现的功能。通过两重循环,来扫描在最初我们所定义的map数组,来进行判断某一坐标是否应该展示图片,卑微作者在线献上map数组代码:

int map[26][26] = {
	{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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1},
	{2, 2, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 2},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

};

至此,如果以上步骤都运行成功的话,那么恭喜你,我们已经得到了这样的一个效果
C++实现经典坦克大战(一)

实现坦克的初始化

接下来,地图界面实现之后我们就要开始实现游戏中最重要的部分了,坦克之间的对决。
首先,我们创建一个描述坦克的结构体:

struct tank_s {
	int x;//坦克所处位置的列
	int y;//坦克所处位置的行
	DIRECTION direction;//坦克的方向:上下左右
	int live; //是否生存:1-活着,0-挂了
};

有坦克必然就会有子弹,然后我们定义一个子弹的结构体:

//子弹结构体
struct bullet_s {
	int pos_x;
	int pos_y;
	DIRECTION direction;
	int status;
};

接下来就是坦克和子弹的移动,即play函数的实现。
这之后的一些内容,我们将在后续坦克大战中为大家分享,学生党,更新速度有限,还请大家谅解…

上一篇:Linux 字符处理之【grep】


下一篇:C# 模拟鼠标移动和点击