DS

C++大作业代码(3)-雷电战机游戏等

C++大作业代码(3)-雷电战机游戏等

Posted by xuepro on June 14, 2019

雷电战机游戏


//-------------方梦成-雷电战机.基于国人开发的easyx 图形游戏平台------------------------------------

#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<windows.h>
#include<iostream>
#include<queue>
#include<string>
#include<time.h>
#include<stack>
#include <fstream> 
#include<math.h>
using namespace std;
#include "Mmsystem.h"
#pragma comment(lib,"Winmm.lib")
struct Node{
	int x,y;
	int cind,dis;
	int key;
	int plane_sign;
}; 
struct Pao{
int x,y,dp;
};
queue<Node>fire;
queue<Node>monsters,mon_fires;
queue<Pao>paohui;
int x,y,life,score,tim;
int shoot_po,music_ans;
int xx,yy,zhiyuan_dp,zhiyuan_sign,help_ans;
int come_time;
bool zhiyuan_come;
void Print_zhiyuan(int co)
{
	if(co==1)
	{
		if(yy>=400)
		yy-=5;
	}
	else if(co==2)
	{
		if(yy>=600)
			return;
		yy+=5;
	}
	IMAGE img1,img2;
	if(zhiyuan_dp<=0)
	{
		if(xx>x)
		zhiyuan_sign=1;
		else zhiyuan_sign=2;
		zhiyuan_dp=200;
	}
	zhiyuan_dp-=2;
	if(zhiyuan_sign==2)
		xx+=2;
	else if(zhiyuan_sign==1)
		xx-=2;
	if(xx>=950)
		xx-=2;
	if(xx<=0)
		xx+=2;
	loadimage(&img1,_T("pictures\\zhiyuan.jpg"),50,60);//
	loadimage(&img2,_T("pictures\\zhiyuana.jpg"),50,60);//
	putimage(xx,yy,&img2, SRCAND);
	putimage(xx,yy,&img1, SRCPAINT);
	if(tim%20==0)
	{
		Node zhiyuan_fire;
		zhiyuan_fire.x=xx;
		zhiyuan_fire.y=yy-70;
		zhiyuan_fire.key=2;
		fire.push(zhiyuan_fire);
	}
}
void Print_fire()
{
	
	int len1=fire.size();
	for(int i=1;i<=len1;i++)
	{
		Node t1=fire.front();
		fire.pop();
		if(tim%2==0)
		t1.y-=10;
		if(t1.y<=10)
		{
			continue;
		}
		IMAGE img1,img2;
		if(t1.key==1)
		{
			
			loadimage(&img1,_T("pictures\\shoot2.jpg"),150,30);//
			loadimage(&img2,_T("pictures\\shoot2a.jpg"),150,30);//
			putimage(t1.x-50,t1.y,&img2, SRCAND);
			putimage(t1.x-50,t1.y,&img1, SRCPAINT);
		}
		else if(t1.key==0)
		{
		
			loadimage(&img1,_T("pictures\\fire1.jpg"),50,60);//
			loadimage(&img2,_T("pictures\\fire2.jpg"),50,60);//WWWW
			putimage(t1.x,t1.y,&img2, SRCAND);
			putimage(t1.x,t1.y,&img1, SRCPAINT);
		}
		else if(t1.key==2)
		{
			loadimage(&img1,_T("pictures\\zhiyuan_fire.jpg"),50,60);//
			loadimage(&img2,_T("pictures\\zhiyuan_firea.jpg"),50,60);//WWWW
			putimage(t1.x,t1.y,&img2, SRCAND);
			putimage(t1.x,t1.y,&img1, SRCPAINT);
		}
		fire.push(t1);
	}
}
int lf,rf,down,cind;
void Print_monster()
{
	int len2=monsters.size();
	IMAGE img1,img2;
	for(int i=1;i<=len2;i++)
	{
		Node t2=monsters.front();
		monsters.pop();

		if(t2.cind==0)
		{
			int find=rand()%100+1;
			if(find%7==0)
			{
				t2.dis=100;
				t2.cind=7;
			}
			else if(find%5==0)
			{
				t2.dis=100;
				t2.cind=5;
			}
			else{
				t2.dis=50;
				t2.cind=2;
			}
		}
		if(t2.cind==2)
		{
			if(t2.dis<=0)
				t2.cind=0;
			else{
				t2.dis--;
				t2.y++;
			}
		}
		else if(t2.cind==7)
		{
			if(t2.dis<=0)
				t2.cind=0;
			else{
				t2.dis--;
				t2.x+=2;
				t2.y++;
			}
		}
		else if(t2.cind==5)
		{
			if(t2.dis<=0)
				t2.cind=0;
			else{
				t2.dis--;
				t2.x-=2;
				t2.y++;
			}
		}
		if(t2.x<=10)continue;
		if(t2.x>=940)continue;
		if(t2.y>540)continue;
		if(t2.plane_sign==1)
		{
			loadimage(&img1,_T("pictures\\monsters1.jpg"),50,60);//
			loadimage(&img2,_T("pictures\\monsters2.jpg"),50,60);//
		}
		else if(t2.plane_sign==2)
		{
			loadimage(&img1,_T("pictures\\monsters3.jpg"),50,60);//
			loadimage(&img2,_T("pictures\\monsters3a.jpg"),50,60);//
		}
		putimage(t2.x,t2.y,&img2, SRCAND);
		putimage(t2.x,t2.y,&img1, SRCPAINT);
		monsters.push(t2);
		if(tim%20==0)
		{
			int sign=rand()%30+1;
			if(sign%8==0)
			{
				Node paodan;
				paodan.x=t2.x;
				paodan.y=t2.y+70;
				mon_fires.push(paodan);
			}		
		}
	}
}
int lifes;
void Life()
{
	int len2=monsters.size();
	int len3=mon_fires.size();
	int i;
	IMAGE img;
	for(i=1;i<=len2;i++)
	{
		Node t2=monsters.front();
		monsters.pop();
		if(abs(x-t2.x)<=50&&abs(y-t2.y)<=60)
		{
			//paohui
			Pao pao;
			pao.x=t2.x-20;
			pao.y=t2.y-10;
			pao.dp=1;
			paohui.push(pao);
			life-=5;

			char list[100];
			sprintf(list,"open musics\\paohui.mp3 alias BackMusic%d",music_ans);
			mciSendString(list, NULL, 0, NULL); // 打开音乐
			sprintf(list,"setaudio BackMusic%d volume to 300",music_ans);
			mciSendString(list,NULL,0,NULL);		//设置音量大小
			sprintf(list,"play BackMusic%d from 0",music_ans);
			mciSendString(list, NULL, 0, NULL);	
			music_ans++;
			music_ans%=1000;

			break;
		}
		else monsters.push(t2);
	}
	for(i=1;i<=len3;i++)
	{
		Node t3=mon_fires.front();
		mon_fires.pop();
		if(abs(x-t3.x)<=45&&y-t3.y<=60)
		{
			life-=10;
			char list[100];
			sprintf(list,"open musics\\paohui.mp3 alias BackMusic%d",music_ans);
			mciSendString(list, NULL, 0, NULL); // 打开音乐
			sprintf(list,"setaudio BackMusic%d volume to 300",music_ans);
			mciSendString(list,NULL,0,NULL);		//设置音量大小
			sprintf(list,"play BackMusic%d from 0",music_ans);
			mciSendString(list, NULL, 0, NULL);	
			music_ans++;
			music_ans%=1000;
			
			//paohui
			Pao pao;
			pao.x=t3.x-20;
			pao.y=t3.y-10;
			pao.dp=1;
			paohui.push(pao);	
			break;
		}
		else mon_fires.push(t3);
	}
}
int huoyan_ans;
bool up_check,zy_check;
void Plane(int x,int y)
{
	IMAGE img1,img2;
	
	loadimage(&img1,_T("pictures\\plane1.jpg"),50,60);//
	loadimage(&img2,_T("pictures\\plane2.jpg"),50,60);//
	putimage(x,y,&img2, SRCAND);
	putimage(x,y,&img1, SRCPAINT);	
	huoyan_ans++;

	IMAGE img3,img4;
	int width=30;
	if(huoyan_ans<=10)
	{
		if(up_check)
		{
			loadimage(&img3,_T("pictures\\huoyan3.jpg"),30,50);//
			loadimage(&img4,_T("pictures\\huoyan3a.jpg"),30,50);//
		}
		else
		{
			if(zy_check)
				width=40;
			else width=30;
			loadimage(&img3,_T("pictures\\huoyan1.jpg"),30,width);//
			loadimage(&img4,_T("pictures\\huoyan1a.jpg"),30,width);//
		}
		putimage(x+10,y+50,&img4, SRCAND);
		putimage(x+10,y+50,&img3, SRCPAINT);
	}
	else if(huoyan_ans>10&&huoyan_ans<=20)
	{
		if(up_check)
		{
			loadimage(&img3,_T("pictures\\huoyan4.jpg"),30,50);//
			loadimage(&img4,_T("pictures\\huoyan4a.jpg"),30,50);//
		}
		else
		{
			if(zy_check)
				width=40;
			else width=30;
			loadimage(&img3,_T("pictures\\huoyan2.jpg"),30,width);//
			loadimage(&img4,_T("pictures\\huoyan2a.jpg"),30,width);//
		}
		putimage(x+10,y+50,&img4, SRCAND);
		putimage(x+10,y+50,&img3, SRCPAINT);
	}
	huoyan_ans%=21;
}
void Print_mon_fires()
{
	int len3=mon_fires.size();
	int i;
	IMAGE img1,img2;
	for(i=1;i<=len3;i++)
	{
		Node t3=mon_fires.front();
		mon_fires.pop();
		if(tim%2==0)
		t3.y+=10;
		if(t3.y>540)
		{
			continue;
		}
		loadimage(&img1,_T("pictures\\mon_fire1.jpg"),50,60);//
		loadimage(&img2,_T("pictures\\mon_fire2.jpg"),50,60);//
		putimage(t3.x,t3.y,&img2, SRCAND);
		putimage(t3.x,t3.y,&img1, SRCPAINT);

		mon_fires.push(t3);
	}
}
void Change()
{
	int len1,len2,len3;
	int i,j;
	len1=fire.size();
	for(i=1;i<=len1;i++)
	{
		Node t1;
		t1=fire.front();
		fire.pop();
		bool check=false;

		len2=monsters.size();
		
		for(j=1;j<=len2;j++)
		{
			Node t2=monsters.front();
			monsters.pop();
			bool shoot_go=false;
			if(t1.key==0)
			{
				if(t1.y-t2.y>=0&&t1.y-t2.y<=60&&abs(t1.x-t2.x)<=45)
					shoot_go=true;
			}
			else if(t1.key==1)
			{
				if(t1.y-t2.y>=0&&t1.y-t2.y<=45&&abs(t1.x-t2.x)<=100)
					shoot_go=true;
			}
			else if(t1.key==2)
			{
				if(t1.y-t2.y>=0&&t1.y-t2.y<=45&&abs(t1.x-t2.x)<=40)
					shoot_go=true;
			}
			if(shoot_go)
			{
				if(zhiyuan_come==false)
					help_ans+=10;
				char list[100];
				sprintf(list,"open musics\\paohui.mp3 alias BackMusic%d",music_ans);
				mciSendString(list, NULL, 0, NULL); // 打开音乐
				sprintf(list,"setaudio BackMusic%d volume to 300",music_ans);
				mciSendString(list,NULL,0,NULL);		//设置音量大小
				sprintf(list,"play BackMusic%d from 0",music_ans);
				mciSendString(list, NULL, 0, NULL);	
				music_ans++;
				music_ans%=1000;
				
				//paohui
				Pao pao;
				pao.x=t2.x-20;
				pao.y=t2.y-10;
				pao.dp=1;
				paohui.push(pao);				
				score++;
				check=true;
				break;
			}
			else monsters.push(t2);
		}
		if(check==false)
		fire.push(t1);
	}
	len1=fire.size();
	for(i=1;i<=len1;i++)
	{
		Node t1=fire.front();
		fire.pop();
		bool check=false;

		len3=mon_fires.size();

		for(j=1;j<=len3;j++)
		{
			Node t3=mon_fires.front();
			mon_fires.pop();

			bool shoot_go=false;
			if(t1.key==0)
			{
				if(t1.y-t3.y<=60&&abs(t1.x-t3.x)<=45)
					shoot_go=true;
			}
			else if(t1.key==1)
			{
				if(t1.y-t3.y<=45&&abs(t1.x-t3.x)<=100)
					shoot_go=true;
			}
			if(shoot_go)
			{
				check=true;
				break;
			}
			else mon_fires.push(t3);
		}
		if(check==false)
		fire.push(t1); 
	}
}
void Score_Life()
{
	char HPtext[50],MPtext[50],HELPtext[50];
	sprintf(HPtext,"HP       %d/%d",life,100);
	sprintf(MPtext,"SCORE    %d",score*100);
	sprintf(HELPtext,"HELP");

	rectangle(7,11,120,31);
	rectangle(7,32,120,52);
	rectangle(800,11,980,31);
	setfillcolor(BLUE);
	solidrectangle(802,12,826+help_ans,30);
	setfillcolor(RED);
	solidrectangle(9,12,18+life,30);
	setfillcolor(BLACK);
	solidrectangle(9,33,119,51);
	outtextxy(9,13,HPtext);
	outtextxy(9,35,MPtext);
	outtextxy(802,13,HELPtext);
}
void Paohui()
{
	int len=paohui.size();
	int x0,y0;
	x0=100,y0=120;
	IMAGE img1,img2;
	for(int i=1;i<=len;i++)
	{
		Pao pao=paohui.front();
		paohui.pop();
		if(pao.dp==1)
		{
				loadimage(&img1,_T("pictures\\hui1.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui1a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp==2)
		{
				loadimage(&img1,_T("pictures\\hui2.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui2a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp==3)
		{
				loadimage(&img1,_T("pictures\\hui3.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui3a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp==4)
		{
				loadimage(&img1,_T("pictures\\hui4.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui4a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp==5)
		{
				loadimage(&img1,_T("pictures\\hui5.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui5a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp==6)
		{
				loadimage(&img1,_T("pictures\\hui6.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui6a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp==7)
		{
				loadimage(&img1,_T("pictures\\hui7.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui7a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp==8)
		{
				loadimage(&img1,_T("pictures\\hui8.jpg"),x0,y0);
				loadimage(&img2,_T("pictures\\hui8a.jpg"),x0,y0);//
				putimage(pao.x,pao.y,&img2, SRCAND);
				putimage(pao.x,pao.y,&img1, SRCPAINT);
		}
		else if(pao.dp>8)continue;



		if(tim%10==0)
		pao.dp++;
		paohui.push(pao);
	}
}
int shoot_ans;
bool zanting;
bool light_check;
void GetCommand()
{
	if(GetAsyncKeyState(VK_ESCAPE) & 0x8000) {exit(0);}	
	if(GetAsyncKeyState('W') & 0x8000)
	{
		y-=3;
		up_check=true;
	}
	else up_check=false;
	if(GetAsyncKeyState('S') & 0x8000) y+=3;
	if(GetAsyncKeyState('A') & 0x8000)
	{
		x-=3;
		zy_check=true;
	}
	if(GetAsyncKeyState('D') & 0x8000)
	{
		x+=3;
		zy_check=true;
	}
	if((GetAsyncKeyState('D') & 0x8000)==false &&(GetAsyncKeyState('A') & 0x8000)==false)
		zy_check=false;

	if(GetAsyncKeyState('Z') & 0x8000)
	{
			zanting=true;
	}
	if(GetAsyncKeyState('X') & 0x8000)
	{
			zanting=false;
	}
	if(GetAsyncKeyState('Q') & 0x8000) 
	{
		shoot_po=0;
	}
	if(GetAsyncKeyState('E') & 0x8000)
	{
		shoot_po=1;
	}
	if(GetAsyncKeyState('P') & 0x8000)
	{
		if(tim%5==0)
		{
			Node t;
			t.x=x,t.y=y-60;
			t.key=shoot_po;
			fire.push(t);
			char list[100];
			sprintf(list,"open musics\\shoot.mp3 alias shoot%d",shoot_ans);
			mciSendString(list, NULL, 0, NULL); // 打开音乐
			sprintf(list,"setaudio shoot%d volume to 300",shoot_ans);
			mciSendString(list,NULL,0,NULL);		//设置音量大小
			sprintf(list,"play shoot%d from 0",shoot_ans);
			mciSendString(list, NULL, 0, NULL);	
			shoot_ans++;
			shoot_ans%=1000;
		}
	}
	if(GetAsyncKeyState('L') & 0x8000)
		light_check=true;
}
int light_dp;
void Init()
{
	x=450;
	y=540;
	while(!fire.empty())
	fire.pop();
	while(!monsters.empty())
	monsters.pop();
	while(!mon_fires.empty())
	mon_fires.pop();
	tim=0;
	score=0;
	life=100;
	cind=0;
	music_ans=0;
	shoot_ans=0;
	shoot_po=0;
	zanting=false;
	huoyan_ans=0;
	up_check=false;
	zy_check=false;
	light_check=false;
	light_dp=0;
	xx=500;
	yy=600;
	zhiyuan_dp=0;
	help_ans=0;
	come_time=0;
	zhiyuan_come=false;
}
bool GameOver()				//游戏结束
{

	char gameovertext[256];
	int highest_score=0;
	ifstream cinfile("scores.txt"); 
    if (!cinfile.is_open()) 
    { 
        cout << "未成功打开文件" << endl; 
        return 0;
    }
	cinfile>>highest_score;
	if(score>highest_score) 
	{
		sprintf(gameovertext,"Game Over!\nScore:%d\nNew High Score!(Yes to Retry,No to Exit)",score);
		highest_score=score;
	}
	else 
	{
		sprintf(gameovertext,"Game Over!\nScore:%d\nHighest Score:%d\n(Yes to Retry,No to Exit)",score,highest_score);		
	}
	cinfile.close();
	ofstream coutfile("scores.txt"); 
	coutfile<<highest_score;
	coutfile.close();
	if(MessageBox(GetHWnd(),gameovertext,"Game Over",MB_YESNO)==IDYES)
		return true;
	else
		return false;
}
int main(int argc, _TCHAR* argv[])
{
	initgraph(1000,600);	
	mciSendString("open musics\\bgm.mp3 alias BackMusic", NULL, 0, NULL); // 打开音乐
	mciSendString("setaudio BackMusic volume to 600",NULL,0,NULL);		//设置音量大小
	mciSendString("play BackMusic repeat", NULL, 0, NULL);	
read:
	Init();
			//循环播放
	IMAGE bg;
	loadimage(&bg,_T("pictures\\bgphoto.jpg"),1000,600);
	while(true)
	{
		GetCommand();
		if(zanting)continue;
		BeginBatchDraw();
		if(monsters.size()<5)
		{
			int check=rand()%20+1;
			if(check%5==0)continue;
			Node t;
			int x0=rand()%800+2;
			if(x0<=0||x0>=950)continue;
			int plane_sign=rand()%10+1;
			if(plane_sign%2==0)
				t.plane_sign=1;
			else if(plane_sign%2==1)
				t.plane_sign=2;
			t.x=x0;
			t.y=1;
			t.cind=0;
			monsters.push(t);
		}
		putimage(0,0,&bg);
		Plane(x,y);
		if(help_ans>=150)
			zhiyuan_come=true;
		if(zhiyuan_come)
		{	
			Print_zhiyuan(1);
			if(tim%5==0)
			help_ans-=1;
		}
		else
		{
			Print_zhiyuan(2);
		}
		if(help_ans<=0)
		{
			help_ans=0;
			zhiyuan_come=false;
		}
		Print_fire();
		Change();
		Print_monster();
		Print_mon_fires();
		Life();
		Paohui();
		Score_Life();
		if(lifes>=100)
		{
			char ch[20]="GAME_OVER!!!";
			outtextxy(800,400,ch);
			break;
		}
		EndBatchDraw(); 
		Sleep(5);
		tim++;
		tim%=10000;
		if(life<=0)
		{
			if(GameOver())
				goto read;
			else return 0;
		}
	}
	closegraph();
	return 0;
}

//------------------梁子轩-雷电战机------------------------
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<windows.h>
#include<conio.h>
#include<chrono>
#include<stdlib.h>
#include<string>

#define KEY_UP  38
#define KEY_DOWN  40
#define KEY_LEFT  37
#define KEY_RIGHT  39
#define bullet_color '|'
#define player_color '+'
#define enemy_color  '@'
#define Explode_color '.'
#define player_bullet_color '●'
#define Boss_color 'V'
using ElemType = char;
class Window {
	int width, height;
	char bg_color = ' ';
	char* frame_buffer = nullptr;
	int* explode_time = nullptr;
	const int extend = 30;	
public:
	Window(int w, int h, char bgColor) {
		width = w, height = h, bg_color = bgColor,
			frame_buffer = new char[(w + extend) * h], explode_time = new int[(w + extend) * h];
		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++) {
				frame_buffer[i * (width + extend) + j] = bg_color;
				explode_time[i * (width + extend) + j] = 0;
			}
			for (int t = width; t < extend + width; t++) {
				frame_buffer[i * (width + extend) + t] = '|';
				explode_time[i * (width + extend) + t] = 0;
			}
		}
	}
	~Window() {
		delete[] frame_buffer;
	}
	void set_pixel(int x, int y, char color, int time) {
		if (y * (width + extend) + x < height * (width + extend)) {
			int i = y * (width + extend) + x;
			frame_buffer[i] = color;
			explode_time[i] = time;
		}
	}
	void printAnswer() {
		int x = width / 2;
		int y = height / 2;
		int t = 0;
		std::string str = " You Lose!";
		for (int i = 0; i < height / 3 * 2; i++) {
			for (int j = 0; j < width; j++)
				std::cout << " ";
			std::cout << '\n';
		}
		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++)
				if (i * width + j <= y * width + x - str.size() / 2 || i * width + j >= y * width + x + str.size() / 2 + 1)
					std::cout << " ";
				else {
					std::cout << str[t];
					t++;
				}
			std::cout << '\n';
		}

	}
	char get_pixel(int x, int y) {
		int i = y * (width + extend) + x;
		return frame_buffer[i];
	}
	void clear() {
		for (int i = 0; i < height; i++) {
			for (int j = 0; j < (width + extend); j++) {
				if (explode_time[i * (width + extend) + j] == 0) {
					frame_buffer[i * (width + extend) + j] = bg_color;
				}
				else {
					explode_time[i * (width + extend) + j]--;
				}
			}
		}
	}
	void show() {
		for (int i = 0; i < height; i++) {
			for (int j = 0; j < (width + extend); j++)
				std::cout << frame_buffer[i * (width + extend) + j];
			std::cout << '\n';
		}
	}
	int get_width() {
		return width;
	}
	int get_height() {
		return height;
	}
	int get_extend() {
		return extend;
	}
	char get_bg_color() {
		return bg_color;
	}
};
class Position {
	int x = 0, y = 0;
public:
	Position(int i = 0, int j = 0) {
		x = i;
		y = j;
	}

	void set_x(int i) {
		this->x = i;
	}

	void set_y(int j) {
		this->y = j;
	}
	int get_x() {
		return x;
	}
	int get_y() {
		return y;
	}
	int operator[](const int num)const {
		if (num == 0)
			return x;
		if (num == 1)
			return y;
		else throw "下标非法";
	}
	int& operator[](const int num) {
		if (num == 0)
			return x;
		if (num == 1)
			return y;
		else throw "下标非法";
	}
};
class BackGround {
	char top_boundary_color = ' ', bottom_boundary_color = '_';
	char left_right_boundary_color = '|';
	std::string str = " You Lose!";
	std::string score = "Your Score:";
	std::string live = "Your lives:";
	int tmp = 0;
public:
	void draw(Window& window) {
		int right = window.get_width() - 1;
		int bottom = window.get_height() - 1;
		for (int x = 0; x < window.get_width() + window.get_extend(); x++) {
			window.set_pixel(x, 0, top_boundary_color, 0);
			window.set_pixel(x, bottom, bottom_boundary_color, 0);
		}
		for (int y = 0; y < window.get_height(); y++) {
			window.set_pixel(0, y, left_right_boundary_color, 0);
			window.set_pixel(right, y, left_right_boundary_color, 0);
			window.set_pixel(right + window.get_extend(), y, left_right_boundary_color, 0);
		}
		tmp = 0;
		for (int x = right + window.get_extend() / 3, y = window.get_height() / 2 + 7; 
			x < score.size() + right + window.get_extend() / 3; x++) {
			window.set_pixel(x, y, score[tmp], 0);
			tmp++;
		}
		tmp = 0;
		for (int x = right + window.get_extend() / 3, y = window.get_height() / 2 - 10;
			x < live.size() + right + window.get_extend() / 3; x++) {
			window.set_pixel(x, y, live[tmp], 0);
			tmp++;
		}

	}
};

class Rect {
public:
	Position pos, size;
	Rect(Position p, Position s) {
		pos = p, size = s;
	}
	Rect(const int x, const int y, const int w, const int h) {
		pos = Position(x, y), size = Position(w, h);
	}

	bool collide(const Rect& other) {
		return(
			(pos[0] < other.pos[0] + other.size[0]) &&
			(pos[0] + size[0] > other.pos[0]) &&
			(pos[1] < other.pos[1] + other.size[1]) &&
			(pos[1] + size[1] > other.pos[1])
			);
	}
};


class Sprite {
protected:
	Window* window{ nullptr };
	Position pos, vel, size_;
	char color;
	int lives{ 1 };
	Rect rect;
public:
	Sprite(Window* window, const char c, const Position p,
		const Position v = Position{ 0, 0 }, const Position s = Position{ 1, 1 },
		const int lives = 1)
		:window{ window }, pos{ p }, vel{ v }, size_{ s },
		color{ c }, lives{ lives }, rect{ Position(pos[0] - s[0] / 2, pos[1] - s[1] / 2), s }
	{
	}
	virtual void update() {
		pos[0] += vel[0];
		pos[1] += vel[1];
		rect.pos[0] = (pos[0] - rect.size[0] / 2);
		rect.pos[1] = (pos[1] - rect.size[1] / 2);
	}
	virtual void draw() {}
	virtual bool is_dead() {
		return lives <= 0;
	}
	virtual Rect get_rect() {
		return rect;
	}
	virtual bool collide(const Rect & other)
	{
		return rect.collide(other);
	}
	virtual int get_pos_y() {
		return pos[1];
	}
	virtual int get_pos_x() {
		return pos[0];
	}
	int get_lives() {
		return lives;
	}

};

class Score :public Sprite {
protected:
	int score = 0;
	int lives = 0;
	int tmp = 0;
	std::string str1, str2;
public:
	std::string to_String(int n)
	{
		int m = n;
		int tmp = n;
		int cap = 1;
		while (tmp / 10) {
			tmp /= 10;
			cap++;
		}
		char s[100];
		char ss[100];
		int i = 0, j = 0;
		if (n < 0)// 处理负数
		{
			m = 0 - m;
			j = 1;
			ss[0] = '-';
		}
		while (m > 0)
		{
			s[i++] = m % 10 + '0';
			m /= 10;
		}
		s[i] = '\0';
		i = i - 1;
		while (i >= 0)
		{
			ss[j++] = s[i--];
		}
		ss[j] = '\0';
		return ss;
	}
	Score(Window* window, const char c, const Position p, const Position v = Position(0, 0),
		const Position s = Position{ 1, 1 },
		const int lives = 1) :
		Sprite(window, c, p, v, s, lives) {}
	int get_score() {
		return score;
	}
	void score_plus() {
		score++;
	}
	void score_reduce() {
		score--;
	}
	virtual void draw() {
		str1 = to_String(score);
		str2 = to_String(lives);
		tmp = 0;
		int x = window->get_width() + window->get_extend() / 3 + 3;
		int y = window->get_height() / 2 + 10;
		for (; x < str1.size() + window->get_width() + window->get_extend() / 3 + 3; x++) {
			window->set_pixel(x, y, str1[tmp], 0);
			tmp++;
		}
		tmp = 0;
		x = window->get_width() + window->get_extend() / 3 + 3;
		y = window->get_height() / 2 - 8;
		for (; x < str2.size() + window->get_width() + window->get_extend() / 3 + 3; x++) {
			window->set_pixel(x, y, str2[tmp], 0);
			tmp++;
		}


	}
	void set_lives(int n) {
		lives = n;
	}

};

class Bullet :public Sprite {
public:
	Bullet(Window* window, const char c, const Position p,
		const Position v = Position(0, 0)) :Sprite(window, c, p, v) {
	}
	virtual void draw() {
		auto x = pos[0], y = pos[1];
		window->set_pixel(x, y, color, 0);

	}

	virtual bool hitted() {
		lives--;
		return true;
	}
};

class Flighter :public Sprite {
protected:
	Bullet* bullet{ nullptr };
	int Explode = 0;
public:
	Flighter(Window* window, const char c, const Position p, const Position v = Position(0, 0),
		const Position s = Position{ 1, 1 },
		const int lives = 1) :
		Sprite(window, c, p, v, s, lives) {}

	virtual Bullet* shot(const Position& vel) {
		auto x = pos[0];
		auto y = pos[1] - rect.size[1] / 2;
		bullet = new Bullet(window, bullet_color, Position(x, y), vel);
		return bullet;
	}
	virtual void move(Position vel) {
		auto x = pos[0] + vel[0];
		auto y = pos[1] + vel[1];
		if (x >= rect.size[0] / 2 && x < window->get_width() - rect.size[0] / 2 - 1) {
			pos[0] = x;
		}
		if (y >= rect.size[1] / 2 && y < window->get_height() - rect.size[1] / 2 - 1) {
			pos[1] = y;
		}
	}
	void set_explode(int x) {
		Explode = x;
	}
	int get_explode() {
		return Explode;
	}
};


class Vector {
	Sprite** data{ nullptr };
	int capacity{ 0 }, n{ 0 };
public:
	Vector(const int cap = 10) :capacity{ cap }, data{ new Sprite * [cap] }{}
	bool insert(const int i, Sprite*& e) {
		if (i < 0 || i >= n)return false;
		if (n == capacity && !add_capacity())
			return false;
		for (auto j = n; j > i; j--)
			data[j] = data[j - 1];
		data[i] = e;
		return true;
	}
	bool erase(const int i) {
		if (i < 0 || i >= n)return false;
		for (auto j = i; j < n - 1; j++)
			data[j] = data[j + 1];
		n--;
		return true;
	}
	bool push_back(Sprite * e) {
		if (n == capacity && !add_capacity())
			return false;
		data[n++] = e;
		return true;
	}
	bool pop_back() {
		if (n == 0)return false;
		n--;
		return true;
	}
	Sprite* get(const int i) {
		if (i >= 0 && i < n)
			return data[i];
		throw "下标非法!\n";
	}
	Sprite* get(const int i, Sprite * &e) {
		if (i >= 0 && i < n)
			return data[i] = e;
	}
	Sprite*& operator[](int i) {
		if (i >= 0 && i < n)return data[i];
	}
	Sprite* operator[](const int i) const {
		if (i >= 0 && i < n)return data[i];
	}
	bool add_capacity() {
		Sprite** temp = new Sprite * [2 * capacity];
		if (!temp)return false;
		for (auto i = 0; i < n; i++) {
			temp[i] = data[i];
		}
		delete[] data;
		data = temp;
		capacity *= 2;
		return true;
	}
	int size() const { return n; }
	int set_size(int x) {
		n = x;
		return true;
	}
};

class Player :public Flighter {
public:
	Player(Window* window, const char c, const Position p, const Position v = Position(0, 0),
		const Position s = Position{ 1, 1 },
		const int lives = 3) :Flighter(window, c, p, v, s, lives) {}
	virtual void move(Position vel) {
		auto x = pos[0] + vel[0];
		auto y = pos[1] + vel[1];
		if (x >= rect.size[0] / 2 && x < window->get_width() - rect.size[0] / 2 - 1) {
			pos[0] = x;
		}
		if (y >= rect.size[1] / 2 && y < window->get_height() - rect.size[1] / 2 - 1) {
			pos[1] = y;
		}
	}
	virtual Bullet* shot(const Position& vel) {
		auto x = pos[0];
		auto y = pos[1] - rect.size[1] / 2;
		bullet = new Bullet(window, '\6', Position(x, y), vel);
		return bullet;
	}
	virtual void draw() {
		auto x = pos[0], y = pos[1];

		if (Explode != 0) {
			window->set_pixel(x, y - 1, Explode_color, 5);
			window->set_pixel(x - 1, y, Explode_color, 5);
			window->set_pixel(x - 1, y + 1, Explode_color, 5);
			window->set_pixel(x, y, Explode_color, 5);
			window->set_pixel(x - 1, y + 1, Explode_color, 5);
			window->set_pixel(x + 1, y, Explode_color, 5);
			window->set_pixel(x + 1, y + 1, Explode_color, 5);
		}
		else {

			window->set_pixel(x, y - 1, player_color, 0);
			window->set_pixel(x - 1, y, player_color, 0);
			window->set_pixel(x - 1, y + 1, player_color, 0);
			window->set_pixel(x, y, player_color, 0);
			window->set_pixel(x - 1, y + 1, player_color, 0);
			window->set_pixel(x + 1, y, player_color, 0);
			window->set_pixel(x + 1, y + 1, player_color, 0);
		}
	}
	virtual bool hitted() {
		lives--;
		return true;
	}
};
class SpecialBullet :public Flighter {
public:
	SpecialBullet(Window* window, const char c, const Position p, const Position v = Position(0, 0),
		const Position s = Position{ 3, 3 },
		const int lives = 1) :Flighter(window, c, p, v, s, lives) {}
	virtual void move(Position vel) {
		auto x = pos[0] + vel[0];
		auto y = pos[1] + vel[1];
		if (x >= rect.size[0] / 2 && x < window->get_width() - rect.size[0] / 2 - 1) {
			pos[0] = x;
		}
		if (y >= rect.size[1] / 2 && y < window->get_height() - rect.size[1] / 2 - 1) {
			pos[1] = y;
		}
	}
	virtual Bullet* shot(const Position& vel) {
		auto x = pos[0];
		auto y = pos[1] - rect.size[1] / 2;
		bullet = new Bullet(window, '*', Position(x, y), vel);
		return bullet;
	}
	virtual void draw() {
		auto x = pos[0], y = pos[1];

		if (Explode != 0) {

			//window->set_pixel(x, y, Explode_color, 5);
		}
		else {

			//window->set_pixel(x, y, '*', 0);
			window->set_pixel(x + 1, y, '*', 0);
			window->set_pixel(x - 1, y, '*', 0);
			window->set_pixel(x, y + 1, '*', 0);
			window->set_pixel(x, y - 1, '*', 0);

		}
	}
	virtual bool hitted() {
		lives--;
		return true;
	}
	Bullet* get_bullet() {
		Bullet* p = bullet;
		bullet = 0;
		return p;
	}
};
class Enemy :public Flighter {
public:
	Enemy(Window* window, const char c, const Position p, const Position v = Position(0, 0),
		const Position s = Position{ 1, 1 },
		const int lives = 1) :Flighter(window, c, p, v, s, lives) {
	}
	virtual void draw() {
		auto x = pos[0], y = pos[1];
		if (Explode != 0) {
			window->set_pixel(x - 1, y, Explode_color, 5);
			window->set_pixel(x - 1, y - 1, Explode_color, 5);
			window->set_pixel(x - 1, y + 1, Explode_color, 5);
			window->set_pixel(x, y - 1, Explode_color, 5);
			window->set_pixel(x, y, Explode_color, 5);
			window->set_pixel(x, y + 1, Explode_color, 5);
			window->set_pixel(x + 1, y - 1, Explode_color, 5);
			window->set_pixel(x + 1, y, Explode_color, 5);
			window->set_pixel(x + 1, y + 1, Explode_color, 5);
			window->set_pixel(x - 2, y, Explode_color, 5);
			window->set_pixel(x + 2, y, Explode_color, 5);
			window->set_pixel(x, y - 2, Explode_color, 5);
			window->set_pixel(x, y + 2, Explode_color, 5);
			Explode--;
		}
		else {
			window->set_pixel(x, y, enemy_color, 0);
			window->set_pixel(x - 1, y, enemy_color, 0);
			window->set_pixel(x - 1, y - 1, enemy_color, 0);
			window->set_pixel(x, y + 1, enemy_color, 0);
			window->set_pixel(x, y - 1, enemy_color, 0);
			window->set_pixel(x + 1, y, enemy_color, 0);
			window->set_pixel(x + 1, y - 1, enemy_color, 0);
		}
	}
	virtual bool hitted() {
		lives--;
		return true;
	}
	int random_int(int x, int y) {
		static bool is_seeded1 = false;
		if (!is_seeded1) {
			srand((unsigned)time(0));
			is_seeded1 = true;
		}
		return rand() % (y - x) + x;
	}
	virtual void update() {
		static int bullet_num = 5;
		static auto shot_start = std::chrono::high_resolution_clock::now();
		auto shot_last = shot_start;
		auto now = std::chrono::high_resolution_clock::now();
		auto dur = now - shot_start;
		auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
		if (ms > 2000) {
			bullet_num = 5;
			shot_start = now;
		}
		if (bullet_num > 0) {
			auto dur2 = now - shot_last;
			auto ms2 = std::chrono::duration_cast<std::chrono::milliseconds>(dur2).count();
			if (ms2 > 100) {
				shot_last = now;
				shot(Position(0, 1));
				bullet_num--;
			}
		}

		static auto move_start = std::chrono::high_resolution_clock::now();
		auto dur_move = now - move_start;
		auto ms_move = std::chrono::duration_cast<std::chrono::milliseconds>(dur_move).count();
		if (ms_move > 300) {
			auto a = random_int(0, 5);
			if (a > 0) {
				if (a == 1) {
					move(Position(-1, 0));
					if (window->get_pixel(pos[0] - 3, pos[1]) != ' ')
						move(Position(1, 0));
				}
				else if (a == 2) {
					move(Position(1, 0));
					if (window->get_pixel(pos[0] + 3, pos[1]) != ' ')
						move(Position(-1, 0));

				}
				else if (a == 3) {
					move(Position(0, 1));
					if (window->get_pixel(pos[0], pos[1] + 3) != ' ')
						move(Position(0, -1));
				}
				else if (a == 4) {
					move(Position(0, -1));
					if (window->get_pixel(pos[0], pos[1] - 3) != ' ')
						move(Position(0, 1));
				}
			}
		}

		Flighter::update();
	}
	Bullet* get_bullet() {
		Bullet* p = bullet;
		bullet = 0;
		return p;
	}
};
class Boss :public Flighter {
	SpecialBullet* special_bullet = nullptr;
public:
	Boss(Window* window, const char c, const Position p, const Position v = Position(0, 0),
		const Position s = Position{ 1, 1 },
		const int lives = 5) :Flighter(window, c, p, v, s, lives) {
	}
	virtual void draw() {
		auto x = pos[0], y = pos[1];

		if (Explode != 0) {

			window->set_pixel(x, y, Explode_color, 5);
			window->set_pixel(x - 1, y, Explode_color, 5);
			window->set_pixel(x + 1, y, Explode_color, 5);
			window->set_pixel(x - 2, y - 1, Explode_color, 5);
			window->set_pixel(x - 1, y - 1, Explode_color, 5);
			window->set_pixel(x, y - 1, Explode_color, 5);
			window->set_pixel(x + 1, y - 1, Explode_color, 5);
			window->set_pixel(x + 2, y - 1, Explode_color, 5);
			window->set_pixel(x, y + 1, Explode_color, 5);

			Explode--;
		}
		else {
			window->set_pixel(x, y + 1, Boss_color, 0);
			window->set_pixel(x, y, Boss_color, 0);
			window->set_pixel(x - 1, y, Boss_color, 0);
			window->set_pixel(x + 1, y, Boss_color, 0);
			window->set_pixel(x - 2, y - 1, Boss_color, 0);
			window->set_pixel(x - 1, y - 1, Boss_color, 0);
			window->set_pixel(x, y - 1, Boss_color, 0);
			window->set_pixel(x + 1, y - 1, Boss_color, 0);
			window->set_pixel(x + 2, y - 1, Boss_color, 0);
			window->set_pixel(x - 3, y - 2, Boss_color, 0);
			window->set_pixel(x - 2, y - 2, Boss_color, 0);
			window->set_pixel(x - 1, y - 2, Boss_color, 0);
			window->set_pixel(x, y - 2, Boss_color, 0);
			window->set_pixel(x + 1, y - 2, Boss_color, 0);
			window->set_pixel(x + 2, y - 2, Boss_color, 0);
			window->set_pixel(x + 3, y - 2, Boss_color, 0);


		}
	}
	SpecialBullet* SpecialShot(const Position& vel) {
		auto x = pos[0];
		auto y = pos[1] - rect.size[1] / 2;
		special_bullet = new SpecialBullet(window, '*', Position(x, y+3), vel);
		return special_bullet;
	}
	virtual bool hitted() {
		lives--;
		return true;
	}

	int random_int(int x, int y) {
		static bool is_seeded1 = false;
		if (!is_seeded1) {
			srand((unsigned)time(0));
			is_seeded1 = true;
		}
		return rand() % (y - x) + x;
	}
	virtual void update() {
		static int boss_bullet_num = 6;
		static int special_bullet_num = 1;
		static auto boss_shot_start = std::chrono::high_resolution_clock::now();
		auto shot_last = boss_shot_start;
		auto now = std::chrono::high_resolution_clock::now();
		auto dur = now - boss_shot_start;
		auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
		if (ms > 8000) {
			boss_bullet_num = 5;
			special_bullet_num = 1;
			boss_shot_start = now;
		}
		if (boss_bullet_num > 0) {
			auto dur2 = now - shot_last;
			auto ms2 = std::chrono::duration_cast<std::chrono::milliseconds>(dur2).count();
			if (ms2 > 100) {
				shot_last = now;
				shot(Position(0, 1));
				boss_bullet_num--;
			}
		}
		if (special_bullet_num > 0) {
			SpecialShot(Position(0, 1));
			special_bullet_num--;
		}

		static auto move_start = std::chrono::high_resolution_clock::now();
		auto dur_move = now - move_start;
		auto ms_move = std::chrono::duration_cast<std::chrono::milliseconds>(dur_move).count();
		if (ms_move > 300) {
			//auto a = ms_move % 6;
			auto a = random_int(0, 5);
			if (a > 0) {
				if (a == 1) {
					move(Position(-1, 0));
					if (window->get_pixel(pos[0] - 5, pos[1]) != ' ')
						move(Position(1, 0));
				}
				else if (a == 2) {
					move(Position(1, 0));
					if (window->get_pixel(pos[0] + 5, pos[1]) != ' ')
						move(Position(-1, 0));

				}
				else if (a == 3 && pos[1] < window->get_height() / 3) {
					move(Position(0, 1));
					if (window->get_pixel(pos[0], pos[1] + 5) != ' ')
						move(Position(0, -1));
				}
				else if (a == 4) {
					move(Position(0, -1));
					if (window->get_pixel(pos[0], pos[1] - 5) != ' ')
						move(Position(0, 1));
				}
			}
		}

		Flighter::update();
	}

	SpecialBullet* get_Special_bullet() {
		SpecialBullet* p = special_bullet;
		special_bullet = 0;
		return p;
	}
	Bullet* get_bullet() {
		Bullet* p = bullet;
		bullet = 0;
		return p;
	}
};
class GameEngine {
protected:
	Window* window;
	Vector sprites;
	BackGround* bg{ new BackGround() };
	bool running = true;

public:
	GameEngine(int w = 80, int h = 40) {
		window = new Window(w, h, ' ');
		window->clear();
		hideCursor();
	}
	~GameEngine() {
		delete window;
	}
	void gotoxy(int x, int y) {
		COORD coord = { x, y };
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	}

	void hideCursor() {
		CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
		SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
	}
	virtual void collosion() {
	}

	virtual void render() {
		gotoxy(0, 0);						//将画面固定在左上角
		hideCursor();						//隐藏光标
		window->clear();					//重置画面
		draw_scene();						//每个精灵绘制自己(执行精灵自身draw()函数)
		window->show();						//显示画面
		if (!running)return;
	}
	virtual void draw_scene() {
		bg->draw(*window);
		for (auto j = 0; j < sprites.size(); j++)
			sprites[j]->draw();
	}
	int random_int(int x, int y) {
		static bool is_seeded1 = false;
		if (!is_seeded1) {
			srand((unsigned)time(0));
			is_seeded1 = true;
		}
		return rand() % (y - x) + x;
	}
	virtual void processEvent() {
		char key;
		if (_kbhit()) {
			key = _getch();
			if (key == 27)
				running = false;
		}
	}
	virtual void update() {
		for (auto j = 0; j < sprites.size(); j++)
			sprites[j]->update();
	}
	virtual void run() {
		while (running) {
			processEvent();					//键盘控制
			update();						//游戏内容更新(每个精灵都运行一遍其update()函数)
			collosion();					//检测碰撞
			render();						//重新绘制游戏
			Sleep(10);
		}
		window->printAnswer();				//显示游戏结束画面
		system("pause");
	}

};
class SpaceInvander :public GameEngine {
protected:
	Player* player;
	Vector enemies;
	Score* score;
	Vector bullets, enemy_bullets;
	Vector BOSS, special;

public:
	SpaceInvander(int w = 80, int h = 40) :GameEngine(w, h) {
		auto player_w{ 3 }, player_h{ 3 };

		player = new Player(window, player_color,
			Position(window->get_width() / 2, window->get_height() - player_h - 1),
			Position(0, 0), Position(player_w, player_h));
		sprites.push_back(player);
		score = new Score(window, enemy_color, Position(0, 0), Position(0, 0), Position(player_w, player_h));
		score->set_lives(player->get_lives());
		sprites.push_back(score);
	}
	void add_enemies() {

		if (enemies.size() <= 3 && BOSS.size() == 0) {
			int x_off = 10, y_off = 5;
			auto x_min{ x_off }, x_max{ window->get_width() - x_off },
				y_min{ 1 }, y_max{ y_off };
			auto x = random_int(x_min, x_max);
			auto y = random_int(y_min, y_max);
			Enemy* enemy = new Enemy(window, enemy_color, Position(x, y), Position(0, 0), Position(3, 3));
			sprites.push_back(enemy);
			enemies.push_back(enemy);
		}
		if (score->get_score() == 10) {
			if (BOSS.size() == 0) {
				for (auto i = 0; i < enemies.size(); i++) {
					static_cast<Enemy*>(enemies[i])->hitted();
					score->score_reduce();
				}
				int x_off = 10, y_off = 5;
				auto x_min{ x_off }, x_max{ window->get_width() - x_off },
					y_min{ 1 }, y_max{ y_off };
				auto x = random_int(x_min, x_max);
				auto y = random_int(y_min, y_max);
				Boss* boss = new Boss(window, Boss_color, Position(x, y), Position(0, 0), Position(4, 4));
				sprites.push_back(boss);
				BOSS.push_back(boss);
			}
		}
	}
	void update() {
		add_enemies();
		for (auto i = 0; i < enemies.size(); i++) {
			auto enemy = enemies[i];
			Bullet* bullet = static_cast<Enemy*>(enemy)->get_bullet();
			if (bullet) {
				enemy_bullets.push_back(bullet);
				sprites.push_back(bullet);
			}
		}
		for (auto i = 0; i < BOSS.size(); i++) {
			static auto Boss_shot_start = std::chrono::high_resolution_clock::now();
			auto shot_last = Boss_shot_start;
			auto now = std::chrono::high_resolution_clock::now();
			auto dur = now - Boss_shot_start;
			auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
			if (ms > 2000) {
				auto boss = BOSS[i];
				//static_cast<Boss*>(boss)->SpecialShot(Position(0, 1));
				SpecialBullet* SpecialBullet = static_cast<Boss*>(boss)->get_Special_bullet();
				if (SpecialBullet) {
					enemies.push_back(SpecialBullet);
					special.push_back(SpecialBullet);
					sprites.push_back(SpecialBullet);
				}
				static_cast<Boss*>(boss)->shot(Position(0, 1));
				Bullet* bullet = static_cast<Boss*>(boss)->get_bullet();
				if (bullet) {
					enemy_bullets.push_back(bullet);
					sprites.push_back(bullet);
				}
				static_cast<Boss*>(boss)->move(Position(-4, 0));
				static_cast<Boss*>(boss)->shot(Position(0, 1));
				bullet = static_cast<Boss*>(boss)->get_bullet();
				if (bullet) {
					enemy_bullets.push_back(bullet);
					sprites.push_back(bullet);
				}
				static_cast<Boss*>(boss)->move(Position(8, 0));
				static_cast<Boss*>(boss)->shot(Position(0, 1));
				bullet = static_cast<Boss*>(boss)->get_bullet();
				if (bullet) {
					enemy_bullets.push_back(bullet);
					sprites.push_back(bullet);
				}
				static_cast<Boss*>(boss)->move(Position(-4, 0));
				Boss_shot_start = now;
			}
		}

		GameEngine::update();
	}
	void collosion() {
		for (auto i = 0; i < enemies.size(); i++) {
			auto enemy = enemies[i];
			if (player && player->collide(enemy->get_rect())) {
				player->hitted();
				score->set_lives(player->get_lives());
				static_cast<Enemy*>(enemy)->hitted();
			}
			for (auto j = 0; j < bullets.size(); j++) {
				auto bullet = bullets[j];
				if (enemy->collide(bullet->get_rect())) {
					static_cast<Enemy*>(enemy)->hitted();
					static_cast<Enemy*>(enemy)->set_explode(1);
					static_cast<Enemy*>(enemy)->draw();
					static_cast<Bullet*>(bullet)->hitted();
					j = bullets.size();
				}
			}
		}
		if (BOSS.size() != 0 || BOSS[0]->get_lives() > 0) {
			for (auto i = 0; i < BOSS.size(); i++) {
				auto boss = BOSS[i];
				if (boss->get_lives() == 0)break;
				if (player && player->collide(boss->get_rect())) {
					player->hitted();
					score->set_lives(player->get_lives());
					static_cast<Boss*>(boss)->hitted();
				}
				for (auto j = 0; j < bullets.size(); j++) {
					auto bullet = bullets[j];
					if (boss->collide(bullet->get_rect())) {
						static_cast<Boss*>(boss)->hitted();
						if (boss->is_dead()) {
							BOSS.erase(0);
							score->score_plus();
						}
						static_cast<Bullet*>(bullet)->hitted();

						j = bullets.size();
					}
				}
			}
		}
		if (player) {
			for (auto j = 0; j < enemy_bullets.size(); j++) {
				auto bullet = enemy_bullets[j];
				if (player && player->collide(bullet->get_rect())) {
					player->hitted();
					score->set_lives(player->get_lives());
					if (player->is_dead())
					{
						//window->printAnswer();
						running = false;

					}
					static_cast<Bullet*>(bullet)->hitted();
				}
			}
		}
		Vector deads;
		for (auto i = 0; i < sprites.size();) {
			if (sprites[i]->is_dead()) {
				delete sprites[i];
				deads.push_back(sprites[i]);
				sprites.erase(i);
			}
			else i++;
		}
		for (auto i = 0; i < sprites.size();) {
			if (sprites[i]->get_pos_y() < 0 || sprites[i]->get_pos_y() > window->get_height()
				|| sprites[i]->get_pos_x() > window->get_width() || sprites[i]->get_pos_x() < 0) {
				delete sprites[i];
				deads.push_back(sprites[i]);
				sprites.erase(i);
			}
			else i++;
		}
		for (auto i = 0; i < special.size(); i++) {
			auto y = random_int(window->get_height() / 3 * 2 + 7, window->get_height());
			if (special[i]->get_lives() <= 0)break;
			if (special[i]->get_pos_y() > y) {
				static_cast<SpecialBullet*>(special[i])->hitted();
				static_cast<SpecialBullet*>(special[i])->shot(Position(1, 0));
				Bullet* bullet = static_cast<SpecialBullet*>(special[i])->get_bullet();
				if (bullet) {
					enemy_bullets.push_back(bullet);
					sprites.push_back(bullet);
				};
				static_cast<SpecialBullet*>(special[i])->shot(Position(-1, 0));
				bullet = static_cast<SpecialBullet*>(special[i])->get_bullet();
				if (bullet) {
					enemy_bullets.push_back(bullet);
					sprites.push_back(bullet);
				};
				static_cast<SpecialBullet*>(special[i])->shot(Position(0, 1));
				bullet = static_cast<SpecialBullet*>(special[i])->get_bullet();
				if (bullet) {
					enemy_bullets.push_back(bullet);
					sprites.push_back(bullet);
				};
			}
		}
		for (auto i = 0; i < deads.size(); i++) {
			Sprite* p = deads[i];
			auto deleted = false;
			for (auto i = 0; i < enemies.size(); i++) {
				if (enemies[i] == p) {
					enemies.erase(i);
					score->score_plus();
					//deleted = true;
					break;
				}
			}
			
			for (auto i = 0; i < enemy_bullets.size(); i++) {
				if (enemy_bullets[i] == p) {
					enemy_bullets.erase(i);
					deleted = true;
					break;
				}
			}
			if (deleted)continue;
			for (auto i = 0; i < bullets.size(); i++) {
				if (bullets[i] == p) {
					bullets.erase(i);
					deleted = true;
					break;
				}
			}
			if (deleted)continue;
			for (auto i = 0; i < special.size(); i++) {
				if (special[i] == p) {
					special.erase(i);
					
				}
			}
			//special.set_size(0);
			for (auto i = 0; i < BOSS.size(); i++) {
				if (bullets[i] == p) {
					BOSS.erase(i);
					score->score_plus();
					static_cast<Boss*>(BOSS[i])->set_explode(1);
					static_cast<Boss*>(BOSS[i])->draw();
					break;
				}
			}

		}
		deads.set_size(0);
	}
	void processEvent() {
		char key;
		if (_kbhit()) {
			key = _getch();
			if (key == 27)
				running = false;
			if (key == ' ' || key == 'j') {
				Bullet* bullet = static_cast<Player*>(player)->shot(Position(0, -1));
				bullets.push_back(bullet);
				sprites.push_back(bullet);
			}
			else if (key == 'a' || key == 'A' || key == KEY_LEFT) {
				player->move(Position(-1, 0));
			}
			else if (key == 'd' || key == 'D' || key == KEY_RIGHT) {
				player->move(Position(1, 0));
			}
			else if (key == 'w' || key == 'W' || key == KEY_UP) {
				player->move(Position(0, -1));
			}
			else if (key == 's' || key == 'S' || key == KEY_DOWN) {
				player->move(Position(0, 1));
			}
			fflush(stdin);
		}
	}
};

int main() {

	SpaceInvander game;
	game.run();


}

打地鼠游戏(Qt)

#ifndef HAMSTERGAME_H
#define HAMSTERGAME_H

#include <QMainWindow>
#include<QTimer>

namespace Ui {
class HamsterGame;
}

class HamsterGame : public QMainWindow
{
    Q_OBJECT

public:
    explicit HamsterGame(QWidget *parent = nullptr);
    ~HamsterGame();

private:
    Ui::HamsterGame *ui;
    int score, time;
    QTimer * ptimer;
    void showScore();
    QPoint distance;
    bool start; //解决游戏bug
protected:
    void mousePressEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);
private slots:
    void on_mouse1_clicked();
    void on_mouse3_clicked();
    void on_mouse2_clicked();
    void on_start_clicked();
    void showMouse();
    void on_stop_clicked();
    bool isStart();
    void setStart(bool start);
    void on_line_clicked();
    void on_exit_clicked();
};

#endif // HAMSTERGAME_H
#include "hamstergame.h"
#include "ui_hamstergame.h"
#include<QLabel>
#include<QTimer>
#include<QMessageBox>
#include<QMouseEvent>
#include<QTime>
#include<QTimerEvent>
#include<QCursor>
#include<QPixmap>
#include<QMouseEvent>
#include<QMessageBox>
#include<QAbstractButton>
#include "hamstergame.h"
#include <QApplication>

HamsterGame::HamsterGame(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::HamsterGame)
{
    ui->setupUi(this);
    score = 0;
    time = 0;
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//产生随机数
    this->setWindowOpacity(1);//设置透明度
    this->setWindowFlags(Qt::FramelessWindowHint);//去除边框
    this->setAttribute(Qt::WA_TranslucentBackground);//透明背景
    //this->ui->menuBar->hide();
    this->setStart(false);
    this->ui->mainToolBar->hide();
    this->ptimer = new QTimer;
    //this->p = new QTimer;
    connect(this->ptimer, SIGNAL(timeout()), this, SLOT(showMouse()));
    this->ui->stop->hide();
    this->setCursor(QCursor(QPixmap(":/icons/pictureUp.png")));
    ui->mouse1->setStyleSheet("QPushButton:pressed{border-image: url(:/icons/boom.png);}"
                              "QPushButton{border-image: url(:/icons/hello.png);}");
    ui->mouse2->setStyleSheet("QPushButton:pressed{border-image: url(:/icons/boom.png);}"
                              "QPushButton{border-image: url(:/icons/teeth.png);}");
    ui->mouse3->setStyleSheet("QPushButton:pressed{border-image: url(:/icons/boom.png);}"
                              "QPushButton{border-image: url(:/icons/family.png);}");
}

HamsterGame::~HamsterGame()
{
    delete ui;
}

void HamsterGame::mousePressEvent(QMouseEvent* event)
{
    this->setCursor(QCursor(QPixmap(":/icons/picturedown.png")));
    if (event->button() == Qt::LeftButton)
    {
        distance = event->globalPos()-frameGeometry().topLeft();
        event->accept();
    }
}

void HamsterGame::mouseReleaseEvent(QMouseEvent* event)
{
    this->setCursor(QCursor(QPixmap(":/icons/pictureUp.png")));
    if(event->buttons() & Qt::LeftButton)
    {
        move(event->globalPos()-distance);
        event->accept();
    }
}

void HamsterGame::on_mouse1_clicked()
{
    this->ui->mouse1->hide();
    if(this->isStart()){//修改
        score++;
        showScore();
    }
}

void HamsterGame::on_mouse2_clicked()
{
    this->ui->mouse2->hide();
    if(this->isStart()){
        score++;
        showScore();
    }
}

void HamsterGame::on_mouse3_clicked()
{
    this->ui->mouse3->hide();
    if(this->isStart()){
        score++;
        showScore();
    }
}

void HamsterGame::on_start_clicked()
{
    this->ui->start->hide();
    this->setStart(true);//设置flag
    this->ptimer->start(1000);
    this->ui->stop->show();

}

void HamsterGame::showMouse()
{
    time++;
    ui->label->setText("用时"+QString::number(time)+"s");
    ui->mouse1->move(qrand()%640+20, (qrand()%140)+160);
    ui->mouse2->move(qrand()%640+20, (qrand()%140)+160);
    ui->mouse3->move(qrand()%640+20, (qrand()%140)+160);//y坐标要在160~300,为了适应背景
    ui->mouse1->show();
    ui->mouse2->show();
    ui->mouse3->show();
    //ui->label->move(qrand()%640+20, (qrand()%140)+160);
}

void HamsterGame::showScore()
{
    ui->label_2->setText("命中"+QString::number(score)+"只");
    //this->setCursor(QCursor(QPixmap(":/icons/pictureUp")));
}

void HamsterGame::on_stop_clicked()
{
    this->setStart(false);//设置flag
    this->ptimer->stop();
    ui->label_2->setText("命中0只");
    ui->label->setText("用时0s");
    QMessageBox::information(NULL, "游戏结束", "太厉害了!击中了"+QString::number(this->score)+"只地鼠!", QMessageBox::Yes);
    this->ui->start->show();
    this->ui->stop->hide();
    this->score = 0;
    this->time = 0;
}

void HamsterGame::setStart(bool start){
    this->start = start;
}

bool HamsterGame::isStart(){
    return this->start;
}

void HamsterGame::on_line_clicked()
{
    this->showMinimized();
}

void HamsterGame::on_exit_clicked()
{
    this->close();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    HamsterGame w;
    w.show();

    return a.exec();
}

支付宝打赏 微信打赏

您的打赏是对我最大的鼓励!