太原网站建设开发公司,游戏源码买卖平台,大连零基础网站建设教学公司,做网站多少钱一个月[导读]本系列博文内容链接如下#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞… [导读]本系列博文内容链接如下 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞机空战小游戏(四)——给游戏添加背景音乐(多线程技巧应用) 【C】做一个飞机空战小游戏(五)——getch()控制两个飞机图标移动(控制光标位置) 目录
一、控制光标的位置
二为什么要控制光标位置
1、避免控制多个图标移动相互影响
2、消除光标的闪烁现象
二如何控制光标的输出位置
二、控制两个飞机图标移动程序
一头文件control_plane.h
1、更新键盘指令枚举内容
2、增加一个飞机的结构体类型坐标
3、更新飞机坐标计算函数声明
二控制函数库control_plane.cpp
1、增加光标控制函数
2、更新显示飞机图标函数
3、初始化函数
4、更新获取键盘指令函数
5、更新了飞机获取指令后位置计算函数的定义
(二)最终程序
1、主函数
2、头文件control_plane.h
3、库函数control_plane.cpp
三、运行效果 飞机空战游戏一般都是两个飞机今天介绍一下如何用getch()通过不同的方向键组控制两个飞机移动。
一、控制光标的位置
二为什么要控制光标位置
1、避免控制多个图标移动相互影响
本例中本节之前的代码对飞机位置的控制是通过cout函数输出空格和换行来确定飞机图标x和y坐标这种方式对于游戏中只有一个被控制图标是可行的但是要控制多个图标移动就行不通了因为输出换行和空格时会对另外的图标产生影响。
2、消除光标的闪烁现象
输出换行和空格时光标会不断移动所以在移动飞机图标时会有光标闪烁的情况游戏的体验感不好。
而通过控制光标把光标直接移动到要显示飞机图标的位置就避免了频繁输出换行和空格的操作不会对屏幕上其他的图标产生影响也消除了光标闪烁的情况。
二如何控制光标的输出位置
对光标位置的控制本文参考了以下博文
C移动输出端的光标代码实现_c光标_我行我素向往自由的博客-CSDN博客
代码如下所示需要引入头文件windows.h并自定义一个gotoxy(x,y)函数xy就是光标输出的位置。 #includewindows.h
void gotoxy(int x, int y) {COORD pos { x,y };HANDLE hOut GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄SetConsoleCursorPosition(hOut, pos);//两个参数分别指定哪个窗口具体位置
} 二、控制两个飞机图标移动程序
要想实现对两架飞机的控制需要对代码进行部分更新更新内容包括以下几方面。
一头文件control_plane.h
1、更新键盘指令枚举内容
增加一组控制飞机移动的指令更新后的内容如下 //定义移动方向命令枚举类型
typedef enum {up_cmd,down_cmd,left_cmd,right_cmd,up_cmd2,down_cmd2,left_cmd2,right_cmd2} direction_cmd; up_cmd2,down_cmd2,left_cmd2,right_cmd2四项为新增加的内容。
2、增加一个飞机的结构体类型坐标 extern location plocation,plocation2; //声明第二架飞机坐标 3、更新飞机坐标计算函数声明
因为有两架飞机需要计算两组坐标所以在函数声明中增加了标识飞机序号的参量int n具体代码如下 //计算出接收指令后的飞机坐标
location plane_locate(int n,location plct,direction_cmd dircmd); 二控制函数库control_plane.cpp
1、增加光标控制函数 void gotoxy(int x, int y) {COORD pos { x,y };HANDLE hOut GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄SetConsoleCursorPosition(hOut, pos);//两个参数分别指定哪个窗口具体位置
}2、更新显示飞机图标函数
有了控制光标函数之后就可以把显示飞机图标的函数进行调整了具体代码如下所示。 //飞机图标刷新函数
void show_plane(location plct) //预先定义字符定位显示函数x是列坐标y是行坐标原点(x0,y0)位于屏幕左上角
{int x,y;int i,j; int rowssizeof(icon_plane)/sizeof(icon_plane[0]);xplct.x;yplct.y;for(i0;irows;i) //图标每行前输出x个空格 {gotoxy(x,yi); //将光标移动到(xyi)位置couticon_plane[i]endl; //按行输出飞机图标}
} 3、初始化函数
初始化函数中增加另外一架飞机的初始位置具体代码如下所示。 //初始化函数
void init(void)
{plocation.x2*r_b/3; //初始化飞机1图标的x坐标为屏幕横轴最大值的2/3 plocation.yb_b; //初始化飞机1图标的y坐标为屏幕纵轴最大值plocation2.xr_b/3; //初始化飞机2图标的x坐标为屏幕横轴最大值的1/3 plocation2.yb_b; //初始化飞机2图标的y坐标为屏幕纵轴最大值
}4、更新获取键盘指令函数
因为两架飞机需要有两组控制飞机移动方向的控制键组合第一组为双码按键“↑、↓、←、→”四个键第二组为单码键w、s、a、d四个键。所以函数中增加了第二组键的返回值。 //获取键盘指令函数
direction_cmd key(void)
{int key_value1,key_value2; //声明两个变量存放键值 key_value1getch(); //先获取第一个码值 if(key_value1224) //如果第一个码值为224则进行第二个码值的判断 {key_value2getch(); //先获取第二个码值switch(key_value2){case 72: //向上方向键 return up_cmd;case 80: //向下方向键return down_cmd;case 75: //向左方向键return left_cmd;case 77: //向右方向键return right_cmd;}}else{switch(key_value1){case 119: //向上方向键 return up_cmd2;case 115: //向下方向键return down_cmd2;case 97: //向左方向键return left_cmd2;case 100: //向右方向键return right_cmd2;}}
} 5、更新了飞机获取指令后位置计算函数的定义
参量n代表飞机的序号不同的飞机响应不同的指令dircmd然后再根据不同的指令分别计算两架飞机位置。 //计算获得移动指令后飞机的坐标
location plane_locate(int n,location plct,direction_cmd dircmd)
{int x,y;xplct.x;yplct.y;if(n1){switch(dircmd){case up_cmd:y--; //字符上移一行行值y减1if(yt_b) //限定y值最小值为0{yt_b;}break;case down_cmd:y; //字符下移一行行值y加1if(yb_b) //限定y高度 {yb_b;}break;case left_cmd:x--; //字符左移一列列值x减1if(xl_b){xl_b; //限定x最小值为0; }break;case right_cmd:x; //字符右移一列列值x加1if(xr_b){xr_b; //限定x宽度}break;}}else if(n2){switch(dircmd){case up_cmd2:y--; //字符上移一行行值y减1if(yt_b) //限定y值最小值为0{yt_b;}break;case down_cmd2:y; //字符下移一行行值y加1if(yb_b) //限定y高度 {yb_b;}break;case left_cmd2:x--; //字符左移一列列值x减1if(xl_b){xl_b; //限定x最小值为0; }break;case right_cmd2:x; //字符右移一列列值x加1if(xr_b){xr_b; //限定x宽度}break;}}plct.xx;plct.yy;return plct;} (二)最终程序
1、主函数 #include control_plane.h
using namespace std;location plocation;
location plocation2;int main(int argc, char** argv) { init(); //初始化 bgmusic();//播放背景音乐while(1) //循环等待键盘指令 {system(cls); //清屏show_plane(plocation); //刷新飞机1图标show_plane(plocation2); //刷新飞机2图标 dir_cmdkey(); //获取按键指令 //计算收到键盘指令后的两架飞机坐标 plocationplane_locate(1,plocation,dir_cmd);plocation2plane_locate(2,plocation2,dir_cmd); }return 0;
} 2、头文件control_plane.h #ifndef CONTROL_PLANE_H
#define CONTROL_PLANE
#include iostream
#include string
#includestdlib.h
#includewindows.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 //图形显示区域下侧边界//定义飞机造型
const string icon_plane[]{ ■ ,■ ■ ■,■■■■■,■ ■ ■, ■ , ■■■ };//定义图标坐标结构体
typedef struct{int x;int y;
} location;//定义移动方向命令枚举类型
typedef enum {up_cmd,down_cmd,left_cmd,right_cmd,up_cmd2,down_cmd2,left_cmd2,right_cmd2} direction_cmd;extern location plocation,plocation2; //声明飞机坐标
static direction_cmd dir_cmd; //声明存放按键码值的两个变量//声明刷新飞机位置函数
void show_plane(location plct);//获取键盘指令
direction_cmd key(void);//计算出接收指令后的飞机坐标
location plane_locate(int n,location plct,direction_cmd dircmd);//计算出接收指令后的飞机坐标
location plane_locate2(location plct,direction_cmd dircmd);void init(void);void* thread_bgmusic(void* arg);
void play_bgmusic();
void bgmusic();#endif 3、库函数control_plane.cpp #include iostream
#include conio.h
#include string
#include control_plane.h
#includewindows.h
using namespace std;//初始化函数
void init(void)
{plocation.x2*r_b/3; //初始化飞机图标的x坐标为屏幕横轴最大值的一半 plocation.yb_b; //初始化飞机图标的y坐标为屏幕纵轴最大值plocation2.xr_b/3; //初始化飞机图标的x坐标为屏幕横轴最大值的一半 plocation2.yb_b; //初始化飞机图标的y坐标为屏幕纵轴最大值
}//********************************************************************************//以下三个函数为播放背景音乐功能
//********************************************************************************//播放一遍背景音乐 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(location plct) //预先定义字符定位显示函数x是列坐标y是行坐标原点(x0,y0)位于屏幕左上角
{int x,y;int i,j; int rowssizeof(icon_plane)/sizeof(icon_plane[0]);xplct.x;yplct.y;for(i0;irows;i) //图标每行前输出x个空格 {gotoxy(x,yi);couticon_plane[i]endl;}
}//获取键盘指令函数
direction_cmd key(void)
{int key_value1,key_value2; //声明两个变量存放键值 key_value1getch(); //先获取第一个码值 if(key_value1224) //如果第一个码值为224则进行第二个码值的判断 {key_value2getch(); //先获取第二个码值switch(key_value2){case 72: //向上方向键 return up_cmd;case 80: //向下方向键return down_cmd;case 75: //向左方向键return left_cmd;case 77: //向右方向键return right_cmd;}}else{switch(key_value1){case 119: //向上方向键 return up_cmd2;case 115: //向下方向键return down_cmd2;case 97: //向左方向键return left_cmd2;case 100: //向右方向键return right_cmd2;}}
}//计算获得移动指令后飞机的坐标
location plane_locate(int n,location plct,direction_cmd dircmd)
{int x,y;xplct.x;yplct.y;if(n1){switch(dircmd){case up_cmd:y--; //字符上移一行行值y减1if(yt_b) //限定y值最小值为0{yt_b;}break;case down_cmd:y; //字符下移一行行值y加1if(yb_b) //限定y高度 {yb_b;}break;case left_cmd:x--; //字符左移一列列值x减1if(xl_b){xl_b; //限定x最小值为0; }break;case right_cmd:x; //字符右移一列列值x加1if(xr_b){xr_b; //限定x宽度}break;}}else if(n2){switch(dircmd){case up_cmd2:y--; //字符上移一行行值y减1if(yt_b) //限定y值最小值为0{yt_b;}break;case down_cmd2:y; //字符下移一行行值y加1if(yb_b) //限定y高度 {yb_b;}break;case left_cmd2:x--; //字符左移一列列值x减1if(xl_b){xl_b; //限定x最小值为0; }break;case right_cmd2:x; //字符右移一列列值x加1if(xr_b){xr_b; //限定x宽度}break;}}plct.xx;plct.yy;return plct;}//计算获得移动指令后飞机的坐标
location plane_locate2(location plct,direction_cmd dircmd)
{int x,y;xplct.x;yplct.y;switch(dircmd){case up_cmd2:y--; //字符上移一行行值y减1if(yt_b) //限定y值最小值为0{yt_b;}break;case down_cmd2:y; //字符下移一行行值y加1if(yb_b) //限定y高度 {yb_b;}break;case left_cmd2:x--; //字符左移一列列值x减1if(xl_b){xl_b; //限定x最小值为0; }break;case right_cmd2:x; //字符右移一列列值x加1if(xr_b){xr_b; //限定x宽度}break;}plct.xx;plct.yy;return plct;} 三、运行效果
未完待续