【C++】做一个飞机空战小游戏(六)——给两架飞机设置不同颜色(cout输出彩色字符、结构体使用技巧)

这篇具有很好参考价值的文章主要介绍了【C++】做一个飞机空战小游戏(六)——给两架飞机设置不同颜色(cout输出彩色字符、结构体使用技巧)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  [导读]本系列博文内容链接如下:

【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值

【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动
【C++】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动

【C++】做一个飞机空战小游戏(四)——给游戏添加背景音乐(多线程技巧应用)

【C++】做一个飞机空战小游戏(五)——getch()控制两个飞机图标移动(控制光标位置)

【C++】做一个飞机空战小游戏(六)——给两架飞机设置不同颜色(cout输出彩色字符、结构体使用技巧)

【C++】做一个飞机空战小游戏(七)——两组按键同时检测平滑移动(GetAsyncKeyState()函数应用)

【C++】做一个飞机空战小游戏(八)——生成敌方炮弹(rand()函数应用)

【C++】做一个飞机空战小游戏(九)——发射子弹的编程技巧

【C++】做一个飞机空战小游戏(十)——子弹击落炮弹、炮弹与飞机相撞 

在第五节【C++】做一个飞机空战小游戏(五)——getch()控制两个飞机图标移动(控制光标位置)中实现了通过键盘控制两架飞机的效果,但是两架飞机颜色造型一样,很难区分,所以需要给两架飞机选用不同的颜色、不同造型,这样就好辨别了。

本节之前飞机只有位置、造型两个属性,所以可以用独立的变量来声明即可。随着程序设计的深入,飞机的属性越来越多,就需要构造飞机的结构体,把各项属性都放到飞机结构体中。这样,可以减少声明变量的个数,减少自定义函数的形参。使程序的逻辑性更清晰,代码量更少。

目录

一、结构体

(一)定义

(二)使用结构体需要注意几点

1、结构体是一种数据类型

2、结构体需要先构造后使用

3、结构体的成员也可以是结构体类型数据

4、结构体是可以扩展的

(三)参考博文

二、本文用到的结构体

(一)位置坐标结构体

1、构造形式

2、功能

3、用途

(二)飞机结构体

1、构造形式

2、功能

3、用途

三、优化程序

(一)声明数据类型

1、声明全局结构体数组

2、优化按键指令存储枚举变量

(二)已有自定义函数的优化

1、形参数量减少

2、返回型函数类型减少

(三)新增自定义函数

1、新增获取按键键值线程函数

2、新增彩色字符输出函数

3、新增隐藏光标函数

(四)优化后的程序代码

1、主函数

2、头文件control_plane.h

3、库函数control_plane.cpp

五、运行效果


一、结构体

(一)定义

结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型。第二,相同结构的结构体变量是可以相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,它本身不是数据类型(而结构体是),数组名称是常量指针,所以不可以做为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同。

(二)使用结构体需要注意几点

1、结构体是一种数据类型

结构体就是把若干种数据类型的放到一起,构造了一个新的数据类型。所以关于结构体变量的操作和其他的数据类型有好多相似的地方。

声明变量的过程实际就是到内存中划分一片存储空间给这个变量使用,变量名就是这片空间的标记符号,不同的数据类型所占空间不同,所以声明变量的时候需要明确数据类型。结构体变量的声明后,其获得的空间就是结构体内所有成员所需的空间。

2、结构体需要先构造后使用

结构体是用户自己根据需求定制的一种数据类型,不是系统就有的数据类型,所以必须先构造一个结构体数据类型,然后再用这个结构体数据类型声明变量,再对变量进行其他的操作。

3、结构体的成员也可以是结构体类型数据

也就是结构体是可以嵌套的,还可以多层嵌套。

4、结构体是可以扩展的

结构体构造完成后,还可以进行增加、减少或者改变成员。

(三)参考博文

关于结构体基础知识介绍的博文有很多,本文不在详细介绍,具体内容可以参考以下博文:

c语言基础语法六——结构体(完结)_卖酒的小码农的博客-CSDN博客

二、本文用到的结构体

(一)位置坐标结构体

1、构造形式

//定义坐标结构体 
typedef struct{
	int x;
	int y;
} Location;

2、功能

这个结构体数据类型的功能是用来存放屏幕上点的坐标。Location为结构体类型名称,其有两个整形的成员:x,y,分别代表x坐标和y坐标。

3、用途

可以用来存储飞机、炮弹、和其他字符信息要显示的位置。

(二)飞机结构体

1、构造形式

//定义飞机结构体 
typedef struct{
	Location location;	
	int color;
	int icon;
	direction_cmd keycmd;
}Plane;

2、功能

这个结构体数据类型的功能是用来存储飞机属性信息的。Plane为结构体类型名称,其有1个Location类型的成员location,用来存储飞机坐标;1个int型的成员color,用来存储飞机的颜色;1个int型的成员icon,用来存储飞机的造型;1个direction_cmd形的成员keycmd,用来存储飞机接收到的键盘指令。

注意:direction_cmd是本例定义的一个枚举型的数据类型,其内部暂时存储了飞机所能接受的"上、下、左、右"和“无”4个键盘指令名称。

typedef  enum {none_cmd,up_cmd,down_cmd,left_cmd,right_cmd} direction_cmd; 

3、用途

这个结构体的用途就是声明飞机,声明后可以通过改变其成员(属性)的值,定制出风格不同的飞机。还可以在程序里根据属性值的不同做出不同的反应,呈现不同的状态,具有不同的信息,做出不同的动作。

三、优化程序

声明了飞机结构体之后,位置信息、按键指令信息、飞机图标信息、颜色信息都在结构体之内了,以上4个信息都不用单独声明了,声明一个结构体就都包含了。另外,两个飞机就可以用一个结构体数组来表示,飞机的序号可以用数组的角标区分。

(一)声明数据类型

1、声明全局结构体数组

声明全局Plane plane[num_plane],用于存放和传递各种信息。采用数组方式,给赋值带了很大便利,减少代码量。

#define num_plane 2	//飞机架数
extern Plane plane[num_plane];

2、优化按键指令存储枚举变量

typedef  enum {none_cmd,up_cmd,down_cmd,left_cmd,right_cmd} direction_cmd; 

枚举变量里增加“none_cmd”选项,方向指令只保留一组,不再区分是哪个飞机的指令,使指令更加通用。

(二)已有自定义函数的优化

1、形参数量减少

目前形参只有Plane一个结构体类型了。

//声明刷新飞机位置函数
void show_plane(Plane plane);
 
//获取键盘指令
void key(void);
 
//更新每架飞机的坐标
void plane_location_update(void); 

//初始化函数(设置飞机的颜色、形状) 
void init(void);

2、返回型函数类型减少

因为函数运行后的结果都存在全局Plane结构体中了,所以函数不需要各种返回结果。

(三)新增自定义函数

1、新增获取按键键值线程函数

之前的按键获取函数在主线程中,按键按下后再执行位置更新和画面更新,如果没有按键按下,主程序就一直处于等待按键按下的状态,后边的程序都执行不了。游戏后边需要增加炮弹的功能,需要一直更新炮弹的位置,所以需要把按键程序单放到一个线程里。主线程里只保留位置更新和画面更新功能。

//定义获取按键线程函数
void* thread_key(void* arg);
void getkey();

2、新增彩色字符输出函数

//输出有颜色字符函数
template<typename T>	//T表示任何可以被cout输出的类型 
void ColorCout(T t, const int ForeColor = 7, const int BackColor = 0);

3、新增隐藏光标函数

//隐藏光标函数
HANDLE han = GetStdHandle(-11);
void hide(){
	CONSOLE_CURSOR_INFO cursor;
	cursor.bVisible = 0;
	cursor.dwSize = 1;
	SetConsoleCursorInfo(han,&cursor);
}

隐藏光标函数,可以不再界面上不显示光标所在位置,更新画面时不会出现光标,减少闪烁感。

(四)优化后的程序代码

1、主函数

#include "control_plane.h"
using namespace std; 

Plane plane[num_plane];
 
int main(int argc, char** argv) {	
	init();	//初始化					 
 
	bgmusic();//播放背景音乐
	getkey();
	
	while(1)					//循环等待键盘指令 
	{
		for(int i=0;i<num_plane;i++)
		{
			show_plane(plane[i]);	//刷新飞机1图标
		}
		if(plane[0].keycmd!=none_cmd ||plane[1].keycmd!=none_cmd)
		{
			system("cls");
		}
		
		plane_location_update();	
	}
	return 0; 	
}

2、头文件control_plane.h

#ifndef CONTROL_PLANE_H
#define CONTROL_PLANE
#include <iostream>
#include <string>
#include<stdlib.h>
#include<windows.h>
#include <pthread.h>//导入线程头文件库
#include <mmsystem.h> //导入声音头文件库
#pragma comment(lib,"winmm.lib")//导入声音的链接库
#define _CRT_SECURE_NO_WARNINGS 
using namespace std;
 
#define t_b 0  	//图形显示区域上侧边界 
#define l_b 0	//图形显示区域左侧边界
#define r_b 100	//图形显示区域右侧边界
#define b_b 20	//图形显示区域下侧边界

#define num_plane 2	//飞机架数 

 
//定义飞机造型 
const string icon_plane1[]={"    ■","■  ■  ■","■■■■■","■  ■  ■","    ■","  ■■■"};
const string icon_plane2[]={"    ■","■  ■  ■","■■■■■","    ■","  ■■■","■■■■■"};
 
//定义坐标结构体 
typedef struct{
	int x;
	int y;
} Location;

 
//定义移动方向命令枚举类型 
typedef  enum {none_cmd,up_cmd,down_cmd,left_cmd,right_cmd} direction_cmd; 

//定义飞机结构体 
typedef struct{
	Location location;
	int color;
	int icon;
	direction_cmd keycmd;
}Plane;

extern Plane plane[num_plane];
 
//声明刷新飞机位置函数
void show_plane(Plane plane);
 
//获取键盘指令 
void key(void);
 
//更新所有飞机坐标
void plane_location_update(void);
 
//初始化函数 
void init(void);

//播放背景音乐线程 
void* thread_bgmusic(void* arg);
void play_bgmusic();
void bgmusic();

//获取按键指令线程
void* thread_key(void* arg);
void getkey();

//输出彩色字符函数
template<typename T>	//T表示任何可以被cout输出的类型 
void ColorCout(T t, const int ForeColor = 7, const int BackColor = 0);
 
#endif

3、库函数control_plane.cpp

#include <iostream>
#include "conio.h"
#include <string>
#include "control_plane.h"
#include<windows.h>
using namespace std;


//彩色输出函数
template<typename T>	//T表示任何可以被cout输出的类型
void ColorCout(T t, const int ForeColor = 7, const int BackColor = 0)
{
	//	0 = 黑色	1 = 蓝色	 2 = 绿色	 3 = 浅绿色		 4 = 红色	 5 = 紫色	 6 = 黄色	 7 = 白色
	//	8 = 灰色	9 = 淡蓝色	10 = 淡绿色	11 = 淡浅绿色	12 = 淡红色	13 = 淡紫色	14 = 淡黄色	15 = 亮白色
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ForeColor + BackColor * 0x10);
	cout << t;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}


//隐藏光标函数
HANDLE han = GetStdHandle(-11);
void hide(){
	CONSOLE_CURSOR_INFO cursor;
	cursor.bVisible = 0;
	cursor.dwSize = 1;
	SetConsoleCursorInfo(han,&cursor);
}
 
//初始化函数 
void init(void)
{
	plane[0].location={2*r_b/3,b_b};
	plane[1].location={r_b/3,b_b};
	
	plane[0].color=1;
	plane[1].color=2;
	
	plane[0].icon=1;
	plane[1].icon=2;
	
	for(int i=0;i<num_plane;i++)
		{

			system("cls");
			show_plane(plane[i]);	//刷新飞机图标
			plane[i].keycmd=none_cmd;		
		}
	hide();//隐藏光标
}
 


//********************************************************************************
 //以下三个函数为获得按键指令线程函数 
//********************************************************************************

void* thread_key(void* arg)
{
	while(1)
	{
		key();			//获取按键指令
	}
}
void getkey()
{
	pthread_t tid; 
  	pthread_create(&tid, NULL, thread_key, NULL);
}

//获取键盘指令函数
void key(void)
{
	int key_value1,key_value2;			//声明两个变量,存放键值 
	key_value1=getch();					//先获取第一个码值 
	
	
	if(key_value1==224)					//如果第一个码值为224,则进行第二个码值的判断 
		{
			key_value2=getch();			//先获取第二个码值
			
			switch(key_value2)
			{
				case 72:				//向上方向键 
					plane[0].keycmd=up_cmd;
					break;
				case 80:				//向下方向键
					plane[0].keycmd=down_cmd;
					break;
				case 75:				//向左方向键
					plane[0].keycmd=left_cmd;
					break;
				case 77:				//向右方向键
					plane[0].keycmd=right_cmd;
					break;
			}
			
		}
		else
		{
			switch(key_value1)
			{
				case 119:				//向上方向键 
					plane[1].keycmd=up_cmd;
					break;
				case 115:				//向下方向键
					plane[1].keycmd=down_cmd;
					break;
				case 97:				//向左方向键
					plane[1].keycmd=left_cmd;
					break;
				case 100:				//向右方向键
					plane[1].keycmd=right_cmd;
					break;
			}
		}		
}


//********************************************************************************
 //以下三个函数为播放背景音乐功能 
//********************************************************************************
 
 //播放一遍背景音乐 
 void play_bgmusic() {  
 
	mciSendString(TEXT("open hero.mp3 alias s1"),NULL,0,NULL);
	mciSendString(TEXT("play s1"),NULL,0,NULL);
 
	Sleep(153*1000);//153*1000意思是153秒,是整首音乐的时长 
	mciSendString(TEXT("close S1"),NULL,0,NULL); 
  
}
 
//循环播放音乐线程函数 
void* thread_bgmusic(void* arg) //
{ 
  while(1)
  {  	
  	play_bgmusic();
  }
} 
 
//创建音乐播放线程,开始循环播放音乐 
void bgmusic()
{
	pthread_t tid; 
  	pthread_create(&tid, NULL, thread_bgmusic, NULL);
}
 
 
void gotoxy(int x, int y) {
	COORD pos = { x,y };
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别指定哪个窗口,具体位置
}
 
 
//飞机图标刷新函数 
void show_plane(Plane plane)		//预先定义字符定位显示函数,x是列坐标,y是行坐标,原点(x=0,y=0)位于屏幕左上角 
{
	int x,y;
	int i,j;
	int rows;
	x=plane.location.x;
	y=plane.location.y;
	
	switch(plane.icon)
	{
		case 1://第一种造型 
			rows=sizeof(icon_plane1)/sizeof(icon_plane1[0]);
			for(i=0;i<rows;i++)				 
			{
				gotoxy(x,y+i);				
				ColorCout(icon_plane1[i],plane.color);
			}
			break;
		case 2://第二种造型 
			rows=sizeof(icon_plane2)/sizeof(icon_plane2[0]);
			for(i=0;i<rows;i++)				
			{
				gotoxy(x,y+i);				
				ColorCout(icon_plane2[i],plane.color);
			}
			break;				
	}
}


 
 
//更新两个飞机的坐标 
void plane_location_update(void)
{ 	
	for(int i=0;i<2;i++)
	{
		if(plane[i].keycmd!=none_cmd) 
		{
			int x,y;
 			x=plane[i].location.x;
 			y=plane[i].location.y;
 			switch(plane[i].keycmd)
			{
				case up_cmd:
					y--;				//字符上移一行,行值y减1
					if(y<t_b)			//限定y值最小值为0
					{
						y=t_b;
					}
					break;
				case down_cmd:
					y++;				//字符下移一行,行值y加1
					if(y>b_b)			//限定y高度 
					{
						y=b_b;
					}
					break;
				case left_cmd:
					x--;				//字符左移一列,列值x减1
					if(x<l_b)
					{
						x=l_b;			//限定x最小值为0; 
					}
					break;
				case right_cmd:
					x++;				//字符右移一列,列值x加1
					if(x>r_b)
					{
						x=r_b;			//限定x宽度
					}
					break;
				
			}
			plane[i].location.x=x;
 			plane[i].location.y=y;
 			plane[i].keycmd=none_cmd;	
		}
					
	} 		
} 

五、运行效果

【C++】做一个飞机空战小游戏(六)——给两架飞机设置不同颜色(cout输出彩色字符、结构体使用技巧),程序与算法,C与C++,c++,开发语言,游戏

(未完待续) 文章来源地址https://www.toymoban.com/news/detail-633091.html

到了这里,关于【C++】做一个飞机空战小游戏(六)——给两架飞机设置不同颜色(cout输出彩色字符、结构体使用技巧)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值

     [导读]本系列博文内容链接如下: 【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动 【C++】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C++】做一个飞

    2024年02月15日
    浏览(27)
  • 【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动

     [导读]本系列博文内容链接如下: 【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动 【C++】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C++】做一个飞

    2024年02月15日
    浏览(29)
  • 【C++】做一个飞机空战小游戏(八)——生成敌方炮弹(rand()和srand()函数应用)

     [导读]本系列博文内容链接如下: 【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动 【C++】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C++】做一个飞

    2024年02月12日
    浏览(50)
  • 【C++】做一个飞机空战小游戏(七)——两组按键同时检测平滑移动(GetAsyncKeyState()函数应用)

     [导读]本系列博文内容链接如下: 【C++】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C++】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动 【C++】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C++】做一个飞

    2024年02月13日
    浏览(25)
  • C++控制台打飞机小游戏

    我终于决定还是把这个放出来。 视频在这:https://v.youku.com/v_show/id_XNDQxMTQwNDA3Mg==.html 具体信息主界面上都有写。 按空格暂停,建议暂停后再升级属性。 记录最高分的文件进行了加密。 有boss(上面视频2分47秒)。 挺好玩的。 可能有bug,不想改了,整体体验不错就行了。 更多

    2024年02月05日
    浏览(35)
  • Python开发小游戏:写一个飞机大战只需要500行代码!

    ‘’’ :param background_image_path: 背景图片的路径地址 :param size: 游戏窗口的大小 :param title: 游戏窗口的标题 :param font_name: 指定字体 :param font_size: 指定字体大小 :param speed: 背景图滚动整个窗口一次所用时间,单位为ms ‘’’ self.size = size self.screen = pygame.display.set_mode(size) self.tit

    2024年04月11日
    浏览(35)
  • 超好玩C++控制台打飞机小游戏,附源码

    我终于决定还是把这个放出来。 视频在这:https://v.youku.com/v_show/id_XNDQxMTQwNDA3Mg==.html 具体信息主界面上都有写。 按空格暂停,建议暂停后再升级属性。 记录最高分的文件进行了加密。 有boss(上面视频2分47秒)。 挺好玩的。 可能有bug,不想改了,整体体验不错就行了。 更多

    2024年02月05日
    浏览(34)
  • python——飞机大战小游戏

    目录 1、导入模块 2、窗口操作 3、事件操作 4、长按事件 5、添加游戏背景 6、添加英雄飞机 7、获取飞机的图片矩形 8、基本游戏窗口 9、添加游戏窗口图片 10、英雄飞机登场 11、英雄飞机装备子弹并发射 1、enemy_plane 2、game_main 3、game_map 4、game_score 5、hero_plane 6、plane_bullet 先安

    2024年02月03日
    浏览(50)
  • Python飞机大战小游戏

    游戏规则:键盘上下左右键控制飞机移动 游戏展示图片: 源码: 第一个py命名为:plane_main.py 第二py命名为:plane_sprites.py 素材图片image关注私信我获取!!!

    2024年02月10日
    浏览(33)
  • python小游戏开发(飞机大战)

    目录 一:背景       1. pygame 模块初识 二.项目设计内容 开发一款飞机大战游戏,要求: (1)实现飞机的移动、子弹发射,对本次游戏有一个初步的编写及认识。 (2)飞机的持续按键移动和飞机自爆优化。 (3)进行基类的抽取,使代码更具有层次性和简化重复代码。 (

    2024年02月16日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包