【C++控制台实战】飞机大战控制台游戏源码

版权声明:本人菜鸟一只,如文章有错误或您有高见,请不吝赐教 https://blog.csdn.net/qq_41138935/article/details/82770987

之所以写这个游戏,是因为不服气,花了一天时间完成。

操作:上下左右键 移动,enter键(回车)发射子弹。

 1

111 是本机,Y是怪物(敌机),*O0是子弹。可以看下截图。

怪物随机移动,怪物子弹发射随机。

相互间的射击判断不是很完善。

代码:

#include<iostream>
#include<cstring>
#include<windows.h>
#include<cmath> 
#include<time.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>

#define WM_MYMSG	WM_USER+100	//线程消息 
using namespace std;

const char space=' ';
const int TOP=15;
const int LEFT=50;
const int X=0;		//	光标默认横坐标
const int Y=4;		//	光标默认纵坐标 
int randomFlag = 1; //随机数标志 

char arr[TOP][LEFT];	//地图

int gwArrTop[TOP];	//怪物纵坐标 
int gwArrLeft[TOP];	//怪物的横坐标 
int gwTot;	//怪物数 
int fjTOP;	//飞机的纵坐标 
int fjLeft; 	//飞机的横坐标 
int Score=0;	//得分
int Life=100;//生命 
int oldLife=100;//旧的生命
int oldScore=0;	//得分

extern "C"
{
	WINBASEAPI HWND WINAPI GetConsoleWindow();
}
 void SetPosition(int x,int y)	//设置光标位置 (列,行) 
{
    HANDLE winHandle;//句柄
    COORD pos = {x,y};
    winHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    //设置光标位置 
    SetConsoleCursorPosition(winHandle,pos); 
 }

int sjs(int a, int b) {			//返回[x,y]的随机数 
	if (randomFlag) {
		randomFlag = 0;
		srand((unsigned int)time(NULL));
	}
 
	return (int)((double)rand() / ((RAND_MAX + 1.0) / (b - a + 1.0)) + a);
}

void print(){			//打印地图 -边界内的 
	SetPosition(X,Y); 
	gwTot=0;//怪物统计
	int gw_i=0,gw_j=0;	 
	 
	for(int i=0;i<TOP;i++){	 
		for(int j=0;j<LEFT;j++){
			//计算 
			if(arr[i][j]=='N'){	//击中怪物 
				if(arr[i-1][j]=='Y'){
					Score++;
					arr[i-1][j]=space;
					gwTot--;
				}
			} 
			
			
			if(arr[i][j]=='*'){		// arr[t][l]
				if(arr[i+1][j]=='1')
					Life--;
			}else if(arr[i][j]=='O'){	//右斜线 
				if(arr[i+1][j+1]=='1')
					Life--; 
			}else if(arr[i][j]=='0'){
				if(arr[i+1][j-1]=='1')
					Life--;
			}else if(arr[i][j]=='Y'){
				if(arr[i+1][j]=='1'||arr[i+1][j+1]=='1'||arr[i+1][j-1]=='1'||arr[i][j+1]=='1'||arr[i][j-1]=='1'){
					arr[i][j]=space;
					Life--;
				}
			}
			 
			 //颜色控制
			if(arr[i][j]=='Y'){
				//红字黑底
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_RED);
				gwArrTop[gw_i++]=i;		//怪物坐标 
				gwArrLeft[gw_j++]=j;
				gwTot++;				//怪物数统计
				
				cout<<arr[i][j];
			}else if(arr[i][j]=='O'||arr[i][j]=='0'){
				//蓝色黑底
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_BLUE);
				cout<<arr[i][j]; 
			}else if(arr[i][j]=='*'){
				//黄字黑底
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_RED | FOREGROUND_GREEN); 
				cout<<arr[i][j];
			}
			else{
			//白色黑底
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY |FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
				cout<<arr[i][j];
			}
			
		} 
		cout<<endl;
	}
}

void print_border(){			//打印地图边界 

	SetPosition(0,0);
	cout<<"得分:"<<Score<<"\t"<<"剩余生命值:"<<Life<<endl;
	SetPosition(X,Y-1);
	cout<<"--------------------------------------------------"<<endl;

	SetPosition(X,Y); 
	  
	for(int i=0;i<TOP+2;i++){	 
		for(int j=0;j<LEFT+1;j++){
			//边界 
			if(i==TOP||j==LEFT){
				cout<<'-';
				continue;
			}
			if(i==TOP+1){
				cout<<"说明:上下左右键移动,回车键攻击"<<endl;
				break; 
			}
			cout<<arr[i][j];  
		}
		cout<<endl;
	}
}

void FJ(){		//飞机坐标初始化 
	int FJ_TOP=14; 
	int FJ_LEFT=24;
	
	fjTOP=FJ_TOP;
	fjLeft=FJ_LEFT;
	arr[FJ_TOP][FJ_LEFT]='1';
	arr[FJ_TOP-1][FJ_LEFT]='1';
	arr[FJ_TOP][FJ_LEFT+1]='1';
	arr[FJ_TOP][FJ_LEFT-1]='1';
}
void GW(){	//随机怪物初始化 
	int tot=sjs(1,4);	//随机一到四个个怪物
	int gwTOP;
	int gwLEFT;
	
	gwTot=tot;
	for(int i=0;i<tot;i++){
		gwTOP=sjs(0,5);
		gwLEFT=sjs(0,48);
		
		gwArrTop[i]=gwTOP;
		gwArrLeft[i]=gwLEFT;
		
		arr[gwTOP][gwLEFT]='Y';
		
	} 
}


int gwAct(){			//怪物随机动
	for(int i=0;i<gwTot;i++){
		int t1=gwArrTop[i];		//TOP
		int l1=gwArrLeft[i];	//Left
		arr[t1][l1]=space;
		int t=sjs(1,5);
		switch(t){
			case 1:
				if(t1<TOP-1){
					t1+=1;
					break;
				}
			case 2:
				if(l1<LEFT-1){
					l1+=1;
					break;
				}
			case 3:
				if(l1>0){
					l1-=1;
					break;
				}
			case 4:
				if(t1<TOP-1&&l1<LEFT-1){
					t1++;
					l1++;
					break;
				}
			case 5:
				if(t1<TOP-1&&l1>0){
					t1++;
					l1--;
					break;
				}
			default:
				if(t1<TOP-1){
					t1+=1;}
				break;
		}
		gwArrTop[i]=t1;
		gwArrLeft[i]=l1;
		arr[t1][l1]='Y';
		//怪物移动到边界的处理 
		if(t1>=TOP-2||l1<=0||l1==LEFT-1){
			arr[t1][l1]=space;
			gwTot--;
		}
		 
	}
}
int input(){			//处理键盘输入 
		int ch;
		ch=getch();	
			switch(ch)
			{
        		case 72:
					arr[fjTOP][fjLeft]=space;
					arr[fjTOP-1][fjLeft]=space;
					arr[fjTOP][fjLeft-1]=space;
					arr[fjTOP][fjLeft+1]=space;
					fjTOP-=1;
					arr[fjTOP][fjLeft]='1';
					arr[fjTOP-1][fjLeft]='1'; 
					arr[fjTOP][fjLeft-1]='1';
					arr[fjTOP][fjLeft+1]='1';
					break;//上 
        		case 80:
					arr[fjTOP][fjLeft]=space;
					arr[fjTOP-1][fjLeft]=space;
					arr[fjTOP][fjLeft-1]=space;
					arr[fjTOP][fjLeft+1]=space;
					fjTOP+=1;
					arr[fjTOP][fjLeft]='1';
					arr[fjTOP-1][fjLeft]='1'; 
					arr[fjTOP][fjLeft-1]='1';
					arr[fjTOP][fjLeft+1]='1';
				 	break;//下 
        		case 75:
					arr[fjTOP][fjLeft]=space;
					arr[fjTOP-1][fjLeft]=space;
					arr[fjTOP][fjLeft-1]=space;
					arr[fjTOP][fjLeft+1]=space;
					fjLeft-=1;
					arr[fjTOP][fjLeft]='1';
					arr[fjTOP-1][fjLeft]='1'; 
					arr[fjTOP][fjLeft-1]='1';
					arr[fjTOP][fjLeft+1]='1';
					break;//左 
        		case 77:
					arr[fjTOP][fjLeft]=space;
					arr[fjTOP-1][fjLeft]=space;
					arr[fjTOP][fjLeft-1]=space;
					arr[fjTOP][fjLeft+1]=space;
					fjLeft+=1;
					arr[fjTOP][fjLeft]='1';
					arr[fjTOP-1][fjLeft]='1'; 
					arr[fjTOP][fjLeft-1]='1';
					arr[fjTOP][fjLeft+1]='1';
					break;//右
				case 13:
					arr[fjTOP-2][fjLeft]='N'; 
					break;//enter  飞机子弹 
        		default:
               		return 0;
   			}	
   		return 1;
}
void sczd(){	//生成随机子弹 
	for(int i=0;i<gwTot;i++){
		int t1=gwArrTop[i];		//TOP
		int l1=gwArrLeft[i];	//Left
		int a=sjs(1,7);
		switch(a){			//随机子弹 
			case 1:
				arr[t1+1][l1]='*';		//直线 
				break;
			case 2:arr[t1+1][l1+1]='O';	//右斜线 
				break;
			case 3:arr[t1+1][l1-1]='0';	//左斜线
				break;
			case 4:arr[t1+1][l1]='*';		//直线 
				   arr[t1+1][l1+1]='O';	//右斜线
				break;
			case 5:arr[t1+1][l1]='*';		//直线
				   arr[t1+1][l1-1]='0';	//左斜线
				break;
			case 6:arr[t1+1][l1+1]='O';	//右斜线 
				   arr[t1+1][l1-1]='0';	//左斜线
				break;
			case 7:arr[t1+1][l1]='*';		//直线 
					arr[t1+1][l1+1]='O';	//右斜线 
					arr[t1+1][l1-1]='0';	//左斜线
				break;
			default:
				arr[t1+1][l1]='*';		//直线
				break;
		}
	}
	
}
void zddel(){	//子弹处理   
	for(int i=TOP-1;i>=0;i--){	 
		for(int j=LEFT-1;j>=0;j--){
			if(arr[i][j]=='*'&&arr[i+1][j]!='Y'){		//怪物直线子弹 
				if(i<TOP-1&&j>0&&j<LEFT-1){
					arr[i][j]=space;
					arr[i+1][j]='*';
				}else{				//子弹消失 
					arr[i][j]=space;
				}
			}else if(arr[i][j]=='O'&&arr[i+1][j+1]!='Y'){	//右斜线子弹 
				if(i<TOP-1&&j<LEFT-1){
					arr[i][j]=space;
					arr[i+1][j+1]='O';
				}else{				//子弹消失 
					arr[i][j]=space;
				}	
			}else if(arr[i][j]=='0'&&arr[i+1][j]!='Y')	//左斜线子弹
			{
				if(i<TOP-1&&j>0){
					arr[i][j]=space;
					arr[i+1][j-1]='0';
				}else{				//子弹消失 
					arr[i][j]=space;
				}
			}
		} 
	}
	for(int i=0;i<TOP;i++){	 
		for(int j=0;j<LEFT;j++){
			if(arr[i][j]=='N'){	//飞机子弹 
				if(i>1&&j>1&&j<LEFT-2){
					arr[i][j]=space;
					arr[i-1][j]='N';
				}else{				//子弹消失 
					arr[i][j]=space;
				}
			}
		} 
	}
}


//多线程
DWORD WINAPI func4(LPVOID LpParameter)	//即使用户不操作,也产生子弹 
{
	while(1)
	{
		sczd(); 
		Sleep(12000);	//12秒	 
	}
	
	return 0;
}

DWORD WINAPI func3(LPVOID LpParameter)	//怪物、子弹移动 
{
	while(1)
	{
		gwAct();//怪物随机动
		zddel();//子弹处理
		Sleep(800);		//怪物、子弹速度控制 
	}
	
	return 0;
}

DWORD WINAPI func2(LPVOID LpParameter)	//捕捉键盘 
{
	DWORD id = *(int*)LpParameter;
	while(1)
	{
		int ap=0;
		ap=input();
		if(ap==1)		//按键
		{
			PostThreadMessage(id, WM_MYMSG, 0, 0);	
		}
	}
	return 0;
}

DWORD WINAPI func1(LPVOID LpParameter)	//怪物、子弹生成 
{
	MSG msg;
	HWND hwnd = GetConsoleWindow();
	while(1)
	{
		GetMessage(&msg,NULL,0,0);
		sczd();	//生成子弹
		if (msg.message == WM_MYMSG)	//按键  添加怪物
		{
			int t=0;
			for(int i=0;i<TOP;i++){	 
				for(int j=0;j<LEFT;j++){
					if(arr[i][j]=='Y')
						t++;
				}
			}
			if(t<=1){
				GW();
			} 		
		}
		Sleep(1000);
	}
	
	return 0;
}


//多线程 
int contrl(){
	DWORD id;
	HANDLE hthrd1 = CreateThread(NULL, 0, func1, NULL, 0, &id);
	HANDLE hthrd2 = CreateThread(NULL, 0, func2, &id, 0, 0);
	HANDLE hthrd3 = CreateThread(NULL, 0, func3, NULL, 0, 0);
	HANDLE hthrd4 = CreateThread(NULL, 0, func4, NULL, 0, 0);
	
	while(1){		
		print();//打印地图
		if(oldScore!=Score){
			oldScore=Score;
			print_border();
			continue;
		}
		if(oldLife!=Life){
			oldLife=Life;
			print_border();
			continue;
		} 
		if(Life<=0){
			break;
		}
		if(fjTOP<=0||fjTOP>TOP-1||fjLeft<=0||fjLeft>=LEFT-1){
			system("cls");//清空屏幕
			cout<<"你自杀了!"<<"\t"<<"生命值:"<<Life<<endl;
			Sleep(3000);
			return 0; 
		} 
		Sleep(1);		//速度控制 
	} 
}
int main(){
	memset(arr,space,sizeof(arr));	//地图初始化
	 
	FJ();//飞机坐标初始化 
	GW(); //随机怪物初始化
	sczd();//生成子弹 
	print_border();//边界 
	contrl();//总体控制 
	system("cls");//清空屏幕
	cout<<"游戏结束!得分:"<<Score<<endl;
	Sleep(6000);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41138935/article/details/82770987