雷电战机游戏
//-------------方梦成-雷电战机.基于国人开发的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();
}
您的打赏是对我最大的鼓励!