[C++]外星人入侵

[Windows8.1 + dev-cpp5.11]

功能描述:

在开始编写一个程序之前,一定要先想好想要的功能,这个项目的描述大概是这样的:

这个游戏是一个外星人入侵的游戏。

玩家的飞船可以通过左右移动,发射炮弹以及使用全屏炸弹,来杀死敌人。

敌方飞船会不停的从屏幕顶端向下掉落,当掉落到底端时,减少一条命。玩家每次可以有三条命。

当玩家的命全部被扣光时,游戏结束。

 

准备工作:

两个重要函数:

void color(int a) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}

这个函数用来设置文本颜色。

void gotoxy(int x, int y) {
	COORD pos;
	pos.X=x;
	pos.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

这个函数用来设置光标的位置。

以上需要引入头文件<Windows.h>

 

编写代码:

编写一个类,用来控制玩家飞机的移动:

struct Plane {
	int x = WIDTH / 2, y = HEIGHT;
	char pic = OPIC;

	void clear(bool left = false) {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
		if (left) {
			gotoxy(x + 1, y);
			color(NCOLOR);
			printf(" ");	
		}
	}

	void blit() {
		gotoxy(x, y);
		color(OCOLOR);
		printf("%c", this->pic);
	}
};

其中clear()函数是用来清空,飞机当前所在位置。

blit()函数是用来在飞机当前位置绘制一个飞机。

 

读取玩家的指令是很重要的。

我们用<conio.h>中的getch()来获取玩家按下的按键。但是很不幸getch()会暂停游戏,直到玩家按下一个按键。

于是我们使用分线程来解决这个问题。

void check_event() {
	while (programe_active) {
		if (Event.size() < QUEUE_MAX_LEN) {
			Event.push(getch());	
		}
	}
	return;
}

 

然后是子弹:

struct Bullet {
	int x, y;
	bool active = false;
	char pic = BPIC;
	
	void __init__(int x) {
		if (!this->active) { 
			this->x = x;
			this->y = HEIGHT;
			this->active = true;
		}
	}
	
	void clear() {
		gotoxy(this->x, this->y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->active = false;
		this->clear();
	}
	
	void blit() {
		if (this->active) {
			gotoxy(this->x, this->y);
			color(NCOLOR);
			printf(" ");
			if (this->y > 1) {
				this->y--;
				gotoxy(this->x, this->y);
				color(OCOLOR);
				printf("%c", pic);
			} else {
				this->stop();
			}
		}
	}
};

Bullet bullet_group[MAX_BULLET];

 

还有敌方飞船:

struct Eship {
	int x, y = 1;
	bool active = false;
	char pic = EPIC;
	
	void __init__(int x) {
		this->active = true;
		this->x = x;
		this->y = 1;
	}
	
	void clear() {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
	}
	
	bool crash() {
		if (this->active) {
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].x == this->x \
				&& bullet_group[i].y == this->y \
				&& bullet_group[i].active) {
					this->active = false;
					clear();
					printf("\a");
					return true;
				}
			}
		}
		return false;
	}
	
	bool Ewin() {
		if (this->y > HEIGHT) {
			programe_active = false;
		}
	}
	
	void blit() {
		if (this->active) {
			this->clear();
			this->y++;
			gotoxy(this->x, this->y);
			color(ECOLOR);
			printf("%c", pic);
		}
	}
};

 

 

完整的代码就在这里给出来:

#include <conio.h>
#include <windows.h>
#include <stack>
#include <vector>
#include <thread>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <ctime>
#include <iostream>

#define BPIC '^'
#define OPIC 24
#define EPIC 25

#define MAX_BULLET 5
#define ONE_PLANE_SCORE 50
#define QUEUE_MAX_LEN 5
#define MAX_ESHIP 120
 
#define OCOLOR 2
#define NCOLOR 15
#define ECOLOR 9

#define WIDTH 50
#define HEIGHT 30
#define BWIDTH 72

#define LETTER_TIME 50
using namespace std;

typedef long long Score_n;

const string BG_COLOR = "0f"; 
const string LOST_MESSAGE = "You lost.\nAn Eship had landed on earth.\n";
bool programe_active = true;
queue<char> Event;
Score_n score = 0;

void gotoxy(int x, int y) {
	COORD pos;
	pos.X=x;
	pos.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

void color(int a) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}

struct Bullet {
	int x, y;
	bool active = false;
	char pic = BPIC;
	
	void __init__(int x) {
		if (!this->active) { 
			this->x = x;
			this->y = HEIGHT;
			this->active = true;
		}
	}
	
	void clear() {
		gotoxy(this->x, this->y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->active = false;
		this->clear();
	}
	
	void blit() {
		if (this->active) {
			gotoxy(this->x, this->y);
			color(NCOLOR);
			printf(" ");
			if (this->y > 1) {
				this->y--;
				gotoxy(this->x, this->y);
				color(OCOLOR);
				printf("%c", pic);
			} else {
				this->stop();
			}
		}
	}
};

Bullet bullet_group[MAX_BULLET];

struct Eship {
	int x, y = 1;
	bool active = false;
	char pic = EPIC;
	
	void __init__(int x) {
		this->active = true;
		this->x = x;
		this->y = 1;
	}
	
	void clear() {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
	}
	
	bool crash() {
		if (this->active) {
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].x == this->x \
				&& bullet_group[i].y == this->y \
				&& bullet_group[i].active) {
					this->active = false;
					clear();
					printf("\a");
					return true;
				}
			}
		}
		return false;
	}
	
	bool Ewin() {
		if (this->y > HEIGHT) {
			programe_active = false;
		}
	}
	
	void blit() {
		if (this->active) {
			this->clear();
			this->y++;
			gotoxy(this->x, this->y);
			color(ECOLOR);
			printf("%c", pic);
		}
	}
};

struct Plane {
	int x = WIDTH / 2, y = HEIGHT;
	char pic = OPIC;

	void clear(bool left = false) {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
		if (left) {
			gotoxy(x + 1, y);
			color(NCOLOR);
			printf(" ");	
		}
	}

	void blit() {
		gotoxy(x, y);
		color(OCOLOR);
		printf("%c", this->pic);
	}
};
/*
void board() {
	Sleep(100);
	while (programe_active) {
		gotoxy(WIDTH + 2, 1);
		color(8);
		printf("score: %d\n", score);
		Sleep(500);
	}
} */

void check_event() {
	while (programe_active) {
		if (Event.size() < QUEUE_MAX_LEN) {
			Event.push(getch());	
		}
	}
	return;
}

void start_s() {
	system("cls");
	system("color 0f");
	for (int i = 0; i < BWIDTH; i++) {
		printf("-");
	}
	printf("\n");
	for (int i = 0; i < HEIGHT; i++) {
		printf("|");
		for (int j = 0; j < WIDTH; j++) {
			printf(" ");
		}
		printf(" |"); 
		for (int j = 0; j < BWIDTH - WIDTH - 3; j++) {
			printf(" ");
		}
		printf("|\n");
	}
	for (int i = 0; i < BWIDTH; i++) {
		printf("-");
	}
	printf("\n");
}

void write(string m) {
	for (int i = 0; i < m.size(); i++) {
		printf("%c", m[i]);
		Sleep(LETTER_TIME);
	}
}

void gohint(char l) {
	while (getch() != l);
}

void hints() {
	write("hints?");
	if (getch() == 'n') return;
	system("cls");
	write("Welcome to Ewar!");
	Sleep(1200);
	write("\nEarth is in danger.You need to protect it by damage Eships.");
	Sleep(2400);
	write("\nHere is a great new that only your ship can fire.");
	Sleep(2400);
	system("cls");
	write("Press letter 'd' to make your ship right. \n");
	gohint('d');
	write("\nPress letter 'a' to make your ship left.\n");
	gohint('a');
	write("\nPress letter 's' to fire.\n");
	gohint('s');
	write("\nNow you have to go.\nGood Luck!");
	Sleep(1700);
}

template <typename T>
void sclear(stack<T> &s) {
	while (!s.empty()) {
		s.pop();
	}
}

int main() {
	hints();
	bool bchange = false;
	bool echange = false;
	bool schange = true;
	int cnt = 0;
	srand((unsigned)time(NULL));
	Plane plane;
	stack<int> bn;
	for (int i = 0; i < MAX_BULLET; i++) {
		bn.push(i);
	}
	stack<int> en;
	for (int i = 0; i < MAX_ESHIP; i++) {
		en.push(i);
	}
	Eship Eship_group[MAX_ESHIP];
	char c;
	start_s();
	thread task01(check_event);
	//thread task02(board);
	while (true) {
		plane.blit();
		//event.push(getch());
		while (!Event.empty()) {
			c = Event.front();
			Event.pop();
			switch(c) {
				case'a':
					if (plane.x > 1) {
						plane.clear(true);
						plane.x--;
					}
					break;
				case'd':
					if (plane.x < WIDTH) {
					plane.clear();
						plane.x++;
					}
					break;
				case's':
					if (bn.size() > 0) {
						bullet_group[bn.top()].__init__(plane.x);
						bn.pop();
						bchange = true;
					}
					break;
				default:
					break;
			}
		}
		for (int i = 0; i < MAX_ESHIP; i++) {
			Eship_group[i].Ewin();
			if (Eship_group[i].crash()) {
				score += 50;
				schange = true;
			}
		}
		if (cnt % 501 == 0 || bchange) { 
			sclear(bn);
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].active) {
					bullet_group[i].clear();
					bullet_group[i].blit();
					continue;
				}
				bn.push(i);
			}
			bchange = false;
		}
		if (cnt % 20001 == 0) {
			Eship_group[en.top()].__init__(rand()%(WIDTH-1)+1);
			en.pop();
			echange = true;
		}
		if (cnt % 9997 == 0 || echange) {
			sclear(en);
			for (int i = 0; i < MAX_ESHIP; i++) {
				if (Eship_group[i].active) {
					Eship_group[i].blit();
					continue;
				}
				en.push(i);
			}
			echange = false;
		} 
		if (schange) {
			gotoxy(WIDTH + 3, 1);
			color(8);
			printf("score: %d\n", score);
			schange = false;
		}
		if (!programe_active) {
			goto LOST;
		}
		cnt++;
	}
	LOST:
		system("cls");
		write(LOST_MESSAGE);
		getch();
		printf("You got %d points!", score);
	END:
		task01.join();
		//task02.join();
	return 0;
}

 

这就是整个游戏的主要框架。

第二版和第三版在这里就不仔细讲了代码,也给出来。

 

V2.0:

#include <conio.h>
#include <windows.h>
#include <stack>
#include <vector>
//#include <thread>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <ctime>
#include <fstream>
#include <iostream>

#define BPIC '^'
#define OPIC 24
#define EPIC 25

#define MAX_BULLET 5
#define ONE_PLANE_SCORE 50
#define QUEUE_MAX_LEN 5
#define MAX_ESHIP 120
 
#define OCOLOR 2
#define NCOLOR 15
#define ECOLOR 9

#define WIDTH 50
#define HEIGHT 30
#define BWIDTH 72

#define LETTER_TIME 50

#define KEY_A 97
#define KEY_W 119
#define KEY_D 100
#define KEY_H 104
/*#define KEY_LEFT 37
#define KEY_UP 38
#define KEY_RIGHT 39*/
#define KEY_SPACE 32
#define KEY_TAB 9
#define KEY_ESC 27
#define NKEY 0x00

#define SHIPB 507
#define BULLETB 101
#define ESHIPB 5557
#define MAKE_ESHIP 10007
using namespace std;

typedef long long Score_n;

//const string BG_COLOR = "0f"; 
const string LOST_MESSAGE = "You lost.\nAn Eship had landed on earth.\n";
bool programe_active = true;
Score_n score = 0;
Score_n HIscore = 0;
stack<int> en;
int left_b = 5;

void gotoxy(int x, int y) {
	COORD pos;
	pos.X=x;
	pos.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

void color(int a) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}

struct Bullet {
	int x, y;
	bool active = false;
	char pic = BPIC;
	
	void __init__(int x) {
		if (!this->active) { 
			this->x = x;
			this->y = HEIGHT;
			this->active = true;
		}
	}
	
	void clear() {
		gotoxy(this->x, this->y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->active = false;
		this->clear();
	}
	
	void blit() {
		if (this->active) {
			gotoxy(this->x, this->y);
			color(NCOLOR);
			printf(" ");
			if (this->y > 1) {
				this->y--;
				gotoxy(this->x, this->y);
				color(OCOLOR);
				printf("%c", pic);
			} else {
				this->stop();
			}
		}
	}
};

Bullet bullet_group[MAX_BULLET];

struct Eship {
	int x, y = 1;
	bool active = false;
	char pic = EPIC;
	
	void __init__(int x) {
		this->active = true;
		this->x = x;
		this->y = 1;
	}
	
	void clear() {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->clear();
		this->active = false;
	}
	
	bool crash() {
		if (this->active) {
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].x == this->x \
				&& bullet_group[i].y == this->y \
				&& bullet_group[i].active) {
					this->stop();
					printf("\a");
					return true;
				}
			}
		}
		return false;
	}
	
	bool Ewin() {
		if (this->y > HEIGHT) {
			programe_active = false;
		}
	}
	
	void blit() {
		if (this->active) {
			this->clear();
			this->y++;
			gotoxy(this->x, this->y);
			color(ECOLOR);
			printf("%c", pic);
		}
	}
};

Eship Eship_group[MAX_ESHIP];

void screen_b() {
	for (int i = 0; i < MAX_ESHIP; i++) {
		if (Eship_group[i].active){
			score += 50;
			Eship_group[i].stop();
		}
	}
	for (int i = 0; i < MAX_ESHIP; i++) {
		en.push(i);
	}
}

struct Plane {
	int x = WIDTH / 2, y = HEIGHT;
	char pic = OPIC;

	void clear(bool left = false) {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
		if (left) {
			gotoxy(x + 1, y);
			color(NCOLOR);
			printf(" ");	
		}
	}

	void blit() {
		gotoxy(x, y);
		color(OCOLOR);
		printf("%c", this->pic);
	}
};

struct Event {
	int PKey;
	
	int KeyDown() {
		if (_kbhit()) {
			this->PKey = _getch();
			return this->PKey;
		} else {
			return false;
		}
	}
	
	bool KeyUp() {
		if (PKey != NKEY && !_kbhit()) {
			PKey = NKEY;
			return true;
		}
		return false;
	}
};

Event event;

/*
void board() {
	Sleep(100);
	while (programe_active) {
		gotoxy(WIDTH + 2, 1);
		color(8);
		printf("score: %d\n", score);
		Sleep(500);
	}
} */
/*
void UPevent() {
	Event e;
	while (programe_active) {
		if (gch.ReadKeyPush()) {
			e.__init__(KEY_DOWN, gch.VKey);
		}
		events.push(e);
	}
	return;
}*/
/*
void check_event() {
	while (programe_active) {
		if (event.KeyDown()) {
			nkey = event.PKey;
		}
		if (event.KeyUp()) {
			nkey = NKEY;
		}
	}
	return;
}
*/
/*
void DOWNevent() {
	Event e;
	while (programe_active) {
		if (gch.ReadKeyDown()) {
			e.__init__(KEY_UP, gch.VKey);
		}
		events.push(e);
	}
}
*/
void start_s() {
	system("cls");
	system("color 0f");
	for (int i = 0; i < BWIDTH; i++) {
		printf("-");
	}
	printf("\n");
	for (int i = 0; i < HEIGHT; i++) {
		printf("|");
		for (int j = 0; j < WIDTH; j++) {
			printf(" ");
		}
		printf(" |"); 
		for (int j = 0; j < BWIDTH - WIDTH - 3; j++) {
			printf(" ");
		}
		printf("|\n");
	}
	for (int i = 0; i < BWIDTH; i++) {
		printf("-");
	}
	printf("\n");
}

void write(string m) {
	for (int i = 0; i < m.size(); i++) {
		printf("%c", m[i]);
		Sleep(LETTER_TIME);
	}
}

void checkch(char l) {
	while (getch() != l);
}

void hints() {
	write("hints?");
	if (getch() == 'n') return;
	system("cls");
	write("Welcome to Ewar!");
	Sleep(1200);
	write("\nEarth is in danger.You need to protect it by damage Eships.");
	Sleep(2400);
	write("\nHere is a great new that only your ship can fire.");
	Sleep(2400);
	system("cls");
	write("Press letter 'd' to make your ship right. \n");
	checkch('d');
	write("\nPress letter 'a' to make your ship left.\n");
	checkch('a');
	write("\nPress letter 'w' to fire.\n");
	checkch('w');
	write("\n Press letter 'h' or botton Tab to use the screen bomb.");
	checkch('h');
	write("\nNow you have to go.\nGood Luck!");
	Sleep(1700);
	return;
}

template <typename T>
void sclear(stack<T> &s) {
	while (!s.empty()) {
		s.pop();
	}
}

void write_HIs() {
	if (score > HIscore) {
		HIscore = score;
	}
	ofstream fout("HIscore.s");
	fout << HIscore << endl;
	fout.close();
}

int main() {
	if (IsDebuggerPresent()) {
		printf("Error: on debugger!\n");
		//system("pause");
		return 1;
	}
	ifstream fin("HIscore.s");
	fin >> HIscore;
	fin.close();
	hints();
	
	bool bchange = false;
	bool echange = false;
	bool schange = true;
	bool mchange = false;
	bool move_left = false;
	bool move_right = false;
	
	int cnt = 0;
	srand((unsigned)time(NULL));
	Plane plane;
	stack<int> bn;
	for (int i = 0; i < MAX_BULLET; i++) {
		bn.push(i);
	}
	
	for (int i = 0; i < MAX_ESHIP; i++) {
		en.push(i);
	}
	char c;
	start_s();
	//thread task01(check_event);
	//thread task02(DOWNevent);
	int key;
	while (true) {
		plane.blit();
		//event.push(getch());
		if (key = event.KeyDown()) {
			switch (key) {
				case KEY_A: 
				//case KEY_LEFT:
					move_left = true;					
					mchange = true;
					break;
				case KEY_D: 
				//case KEY_RIGHT:
					move_right = true;
					mchange = true;
					break;
				case KEY_W: 
				case KEY_SPACE: 
				//case KEY_UP:
					if (bn.size() > 0) {
						bullet_group[bn.top()].__init__(plane.x);
						bn.pop();
						bchange = true;
					}
					break;
				case KEY_H:
				case KEY_TAB:
					if (left_b > 0) {
						screen_b();
						schange = true;
						left_b--;
					}
					break;
				case KEY_ESC:
					programe_active = false;
					break;
				default:
					break; 
			} 
		} else if (event.KeyUp()){
			move_left = false;
			move_right = false;
			mchange = true;
		}
		for (int i = 0; i < MAX_ESHIP; i++) {
			Eship_group[i].Ewin();
			if (Eship_group[i].crash()) {
				score += 50;
				schange = true;
			}
		}
		if (cnt % SHIPB == 0 || mchange) {
			if (move_left) {
				if (plane.x > 1) {
					plane.clear(true);
					plane.x--;
				}
			} else if (move_right) {
				if (plane.x < WIDTH) {
					plane.clear();
					plane.x++;
				}
			}
			mchange = false;
		}
		if (cnt % BULLETB == 0 || bchange) { 
			sclear(bn);
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].active) {
					bullet_group[i].clear();
					bullet_group[i].blit();
					continue;
				}
				bn.push(i);
			}
			bchange = false;
		}
		if (cnt % MAKE_ESHIP == 0) {
			Eship_group[en.top()].__init__(rand()%(WIDTH-1)+1);
			en.pop();
			echange = true;
		}
		if (cnt % ESHIPB == 0 || echange) {
			sclear(en);
			for (int i = 0; i < MAX_ESHIP; i++) {
				if (Eship_group[i].active) {
					Eship_group[i].blit();
					continue;
				}
				en.push(i);
			}
			echange = false;
		} 
		if (schange) {
			gotoxy(WIDTH + 3, 1);
			color(8);
			printf("score: %d", score);
			gotoxy(WIDTH + 3, 2);
			printf("HIscore: %d", HIscore);
			gotoxy(WIDTH + 3, 3);
			printf("left bomb: %d", left_b);
			schange = false;
		}
		if (!programe_active) {
			goto LOST;
		}
		cnt++;
	}
	LOST: 
		write_HIs();
		system("cls");
		write(LOST_MESSAGE);
		getch();
		printf("You got %d points!", score);
		//task01.join();
		
	//task02.join();
	return 0;
}

 

 

V3.0改动有点大大家可以仔细看看。

#include <conio.h>
#include <windows.h>
#include <stack>
#include <vector>
#include <string>
//#include <cstring>
//#include <thread>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <ctime>
#include <fstream>
//#include <iostream>

#define BPIC '^'
#define OPIC 24
#define EPIC 25
#define SELECT_PIC 26

#define BOSS_ESHIP_PIC '#'
#define BOSS_ESHIP_LIFE 99
#define BOSS_ESHIP_SCORE 200

#define ONE_USHIP_SCORE 100
#define B2PIC 'A'

#define MAX_USHIP 20
#define MAX_ESHIP 120
#define MAX_BULLET 20
#define ONE_PLANE_SCORE 50
#define PLAYER_LIFE 3
 
#define OCOLOR 2
#define SCOLOR 2
#define NCOLOR 15
#define ECOLOR 9
#define ONCOLOR 2
#define OFFCOLOR 4

#define WIDTH 50
#define HEIGHT 30
#define BWIDTH 72

#define LETTER_TIME 50

#define KEY_P 112
#define KEY_A 97
#define KEY_W 119
#define KEY_D 100
#define KEY_S 115
#define KEY_H 104
#define KEY_LEFT 75
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_RIGHT 77
#define KEY_END 79
#define KEY_SPACE 32
#define KEY_TAB 9
#define KEY_ESC 27
#define NKEY 0x00

#define SCOREBOARDB 5007
#define BOSSB 701
#define BULLETB 29
#define PLANEB 249
#define ESHIPB 349
#define USHIPB 503
#define MAKE_BOSS 7001
#define MAKE_USHIP 2001
#define MAKE_ESHIP 1003

#define SFILE "HIscore.s"
using namespace std;

typedef unsigned long long Score_n;

//const string BG_COLOR = "0f"; 
const string LOST_MESSAGE = "You lost.\nAll your ships are broken.\n";
const string ABOUT = "    Ewar 3.0\n     By Tom\n";
//bool game_active = true;
Score_n HIscore = 0;

int left_b = 5;

vector<string> menu_chooses;

void gotoxy(int x, int y) {
	COORD pos;
	pos.X=x;
	pos.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

void color(int a) {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}

bool check224(int &ch) {
	if (ch != 224) {
		return false;
	}
	ch = getch();
	return true;
}

template <typename T>
void sclear(stack<T> &s) {
	while (!s.empty()) {
		s.pop();
	}
}

char pause() {
	printf("press any key to continue...\n");
	return getch();
}

bool switch_botton(string text, int oncolor = ONCOLOR, int offcolor = OFFCOLOR,
					bool st = false) {
	bool ans = st;
	int ch;
	while (true) {
		printf("%s", text.c_str());
		if (ans) {
			color(oncolor);
			printf("ON");
		} else {
			color(offcolor);
			printf("OFF");
		}
		ch = getch();
		check224(ch);
		switch(ch) {
			case '\r':
			case '\n':
			case '\t':
			case KEY_END:
				return ans;
			default:
				ans = !ans;
				break;
		}
		system("cls");
	}
}

int choose_text(vector<string> text, string ex_text = "", int ex_color = NCOLOR, 
		char lch = SELECT_PIC, bool light = true) {
	int select = 0;
	int c;
	while (true) {
		system("cls");
		color(ex_color);
		printf("%s", ex_text.c_str());
		for (int i = 0; i < text.size(); i++) {
			if (i == select) {
				if (light) {color(SCOLOR);}
				else {color(NCOLOR);}
				printf("%c", lch);
			} else {
				color(NCOLOR);
				printf(" ");
			}
			printf("%s\n", text[i].c_str());
		}
		c = getch();
		check224(c);
		switch (c) {
			case KEY_W:
			case KEY_UP:
				if (select > 0) {select--;}
				break;
			case KEY_S:
			case KEY_DOWN:
				if (select < text.size() - 1) {select++;}
				break;
			case'\n': case'\r':
				return select;
			default: break;
		}
	}
}

void show_text(string text) {
	system("cls");
	printf("%s\n\n", text.c_str());
	pause();
}

bool confirm() {
	char ch;
	while (true) {
		ch = getch();
		switch(ch) {
			case'y': case'Y':
				return true;
			case'n': case'N':
				return false;
			default:
				break;
		}
	}
}

struct Bullet {
	int x, y;
	bool active = false;
	char pic = BPIC;
	
	void __init__(int x) {
		if (!this->active) { 
			this->x = x;
			this->y = HEIGHT;
			this->active = true;
		}
	}
	
	void clear() {
		gotoxy(this->x, this->y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->active = false;
		this->clear();
	}
	
	void blit() {
		if (this->active) {
			this->clear();
			if (this->y > 1) {
				this->y--;
				gotoxy(this->x, this->y);
				color(OCOLOR);
				printf("%c", pic);
			} else {
				this->stop();
			}
		}
	}
};

Bullet bullet_group[MAX_BULLET];

struct Eship {
	int x, y;
	bool active = false;
	char pic = EPIC;
	
	void __init__(int x) {
		this->active = true;
		this->x = x;
		this->y = 1;
	}
	
	void clear() {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->clear();
		this->active = false;
	}
	
	bool crash() {
		if (this->active) {
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].x == this->x \
				&& bullet_group[i].y == this->y \
				&& bullet_group[i].active) {
					this->stop();
					//printf("\a");
					bullet_group[i].stop();
					return true;
				}
			}
		}
		return false;
	}
	
	bool Ewin() {
		if (this->active && this->y > HEIGHT) {
			return true;
		}
		return false;
	}
	
	void blit() {
		if (this->active) {
			this->clear();
			this->y++;
			gotoxy(this->x, this->y);
			color(ECOLOR);
			printf("%c", pic);
		}
	}
};

struct Uship {
	int x, y;
	bool active = false;
	char pic = B2PIC;
	
	void __init__(int x) {
		this->active = true;
		this->x = x;
		this->y = 1;
	}
	
	void clear() {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->clear();
		this->active = false;
	}
	
	bool crash() {
		if (this->active) {
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].x == this->x \
				&& bullet_group[i].y == this->y \
				&& bullet_group[i].active) {
					this->stop();
					//printf("\a");
					bullet_group[i].stop();
					return true;
				}
			}
		}
		return false;
	}
	
	bool Ewin() {
		if (this->active && this->y > HEIGHT) {
			return true;
		}
		return false;
	}
	
	void blit() {
		if (this->active) {
			this->clear();
			this->y++;
			int m = rand() % 3 - 1;
			this->x += m;
			if (this->x >= WIDTH) {
				this->x = WIDTH - 1;
			} else if (this->x <= 0){
				this->x = 1;
			}
			gotoxy(this->x, this->y);
			color(ECOLOR);
			printf("%c", pic);
		}
	}
};
/*
struct InvEship {
	int x, y;
	bool active = false;
	char pic = EPIC;
	
	void __init__(int x) {
		this->active = true;
		this->x = x;
		this->y = 1;
	}
	
	void clear() {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->clear();
		this->active = false;
	}
	
	bool crash() {
		if (this->active) {
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].x == this->x \
				&& bullet_group[i].y == this->y \
				&& bullet_group[i].active) {
					this->stop();
					//printf("\a");
					bullet_group[i].stop();
					return true;
				}
			}
		}
		return false;
	}
	
	bool Ewin() {
		if (this->active && this->y > HEIGHT) {
			return true;
		}
		return false;
	}
	
	void move() {
		if (this->active) {
			this->y++;
		}
	}
	
	void show() {
		if (this->active) {
			gotoxy(this->x, this->y);
			color(ECOLOR);
			printf("%c", pic);
		}
	}
};
*/
//InvEship InvE[MAX_INVE];

struct BossE {
	int x, y;
	bool active = false;
	char pic = BOSS_ESHIP_PIC;
	int left_life;
	void __init__(int x) {
		this->left_life = BOSS_ESHIP_LIFE;
		this->active = true;
		this->x = x;
		this->y = 1;
	}
	
	
	void clear() {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
	}
	
	void stop() {
		this->clear();
		this->active = false;
	}
	
	int crash() {
		if (this->active) {
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].x == this->x \
				&& bullet_group[i].y == this->y \
				&& bullet_group[i].active) {
					if ((this->left_life--) == 0) {
						this->stop();
						return 1;
					}
					//printf("\a");
					bullet_group[i].stop();
					return -1;
				}
			}
		}
		return false;
	}
	
	bool Ewin() {
		if (this->active && this->y > HEIGHT) {
			return true;
		}
		return false;
	}
	
	void blit() {
		if (this->active) {
			this->clear();
			this->y++;
			gotoxy(this->x, this->y);
			color(ECOLOR);
			printf("%c", pic);
		}
	}
};

BossE boss;
Eship Eship_group[MAX_ESHIP];

int screen_b(stack<int> &bn, stack<int> &en) {
	int cnt = 0;
	for (int i = 0; i < MAX_ESHIP; i++) {
		if (Eship_group[i].active){
			cnt++;
			Eship_group[i].stop();
		}
	}
	sclear(en);
	for (int i = 0; i < MAX_ESHIP; i++) {
		en.push(i);
	}
	for (int i = 0; i < MAX_BULLET; i++) {
		bullet_group[i].stop();
	}
	sclear(bn);
	for (int i = 0; i < MAX_BULLET; i++) {
		bn.push(i);
	}
	return cnt;
}

struct Plane {
	int x = WIDTH / 2, y = HEIGHT;
	char pic = OPIC;

	void clear(bool left = false) {
		gotoxy(x, y);
		color(NCOLOR);
		printf(" ");
		if (left) {
			gotoxy(x + 1, y);
			color(NCOLOR);
			printf(" ");	
		}
	}

	void blit() {
		gotoxy(x, y);
		color(OCOLOR);
		printf("%c", this->pic);
	}
};

struct Event {
	int PKey;
	
	int KeyDown() {
		if (_kbhit()) {
			this->PKey = _getch();
			return this->PKey;
		} else {
			return false;
		}
	}
	
	bool KeyUp() {
		if (PKey != NKEY && !_kbhit()) {
			PKey = NKEY;
			return true;
		}
		return false;
	}
};

Event event;

/*
void board() {
	Sleep(100);
	while (game_active) {
		gotoxy(WIDTH + 2, 1);
		color(8);
		printf("score: %d\n", score);
		Sleep(500);
	}
} */
/*
void UPevent() {
	Event e;
	while (game_active) {
		if (gch.ReadKeyPush()) {
			e.__init__(KEY_DOWN, gch.VKey);
		}
		events.push(e);
	}
	return;
}*/
/*
void check_event() {
	while (game_active) {
		if (event.KeyDown()) {
			nkey = event.PKey;
		}
		if (event.KeyUp()) {
			nkey = NKEY;
		}
	}
	return;
}
*/
/*
void DOWNevent() {
	Event e;
	while (game_active) {
		if (gch.ReadKeyDown()) {
			e.__init__(KEY_UP, gch.VKey);
		}
		events.push(e);
	}
}
*/
void start_s() {
	system("cls");
	system("color 0f");
	for (int i = 0; i < BWIDTH; i++) {
		printf("-");
	}
	printf("\n");
	for (int i = 0; i < HEIGHT; i++) {
		printf("|");
		for (int j = 0; j < WIDTH; j++) {
			printf(" ");
		}
		printf(" |"); 
		for (int j = 0; j < BWIDTH - WIDTH - 3; j++) {
			printf(" ");
		}
		printf("|\n");
	}
	for (int i = 0; i < BWIDTH; i++) {
		printf("-");
	}
	printf("\n");
}

void write(string m) {
	for (int i = 0; i < m.size(); i++) {
		printf("%c", m[i]);
		Sleep(LETTER_TIME);
	}
}

void gohint(char l) {
	while (getch() != l);
}

void hints() {
	/*write("hints?");
	if (getch() == 'n') return;*/
	system("cls");
	write("Welcome to Ewar!");
	Sleep(1200);
	write("\nEarth is in danger.You need to protect it by damage Eships.");
	Sleep(2400);
	write("\nHere is a great new that only your ship can fire.");
	Sleep(2400);
	system("cls");
	write("Press letter 'd' to make your ship right. \n");
	gohint('d');
	write("\nPress letter 'a' to make your ship left.\n");
	gohint('a');
	write("\nPress letter 'w' to fire.\n");
	gohint('w');
	write("\nNow you have to go.\nGood Luck!");
	Sleep(1700);
	return;
}

void set_every_sets_ok(stack<int> &bn, stack<int> &en) {
	/*sclear(en);
	sclear(bn);
	for (int i = 0; i < MAX_BULLET; i++) {
		bn.push(i);
	}
	for (int i = 0; i < MAX_ESHIP; i++) {
		en.push(i);
	}*/
	
	//score = 0;
	//screen_b(bn, en);
	for (int i = 0; i < MAX_ESHIP; i++) {
		Eship_group[i].stop();
	}
	sclear(en);
	for (int i = 0; i < MAX_ESHIP; i++) {
		en.push(i);
	}
	for (int i = 0; i < MAX_BULLET; i++) {
		bullet_group[i].stop();
	}
	sclear(bn);
	for (int i = 0; i < MAX_BULLET; i++) {
		bn.push(i);
	}
	boss.stop();
}

Score_n start_single_game(Score_n begin_score = 0, int left_life = 3) {
	bool bchange = false;
	bool uchange = false;
	bool echange = false;
	bool schange = true;
	bool mchange = false;
	bool move_left = false;
	bool move_right = false;
	
	Score_n score = begin_score;
	
	bool game_active = true;
	int left_b = 5;
	
	int kind;
	
	Uship Uship_group[MAX_USHIP];
	stack<int> un;
	for (int i = 0; i < MAX_USHIP; i++) {
		un.push(i);
	}
	
	int cnt = 1;
	srand((unsigned)time(NULL));
	Plane plane;
	stack<int> bn;
	for (int i = 0; i < MAX_BULLET; i++) {
		bn.push(i);
	}
	stack<int> en;
	for (int i = 0; i < MAX_ESHIP; i++) {
		en.push(i);
	}
	char c;
	start_s();
	//thread task01(check_event);
	//thread task02(DOWNevent);
	int key;
	while (true) {
		plane.blit();
		//event.push(getch());
		if (key = event.KeyDown()) {
			check224(key);
			switch (key) {
				case KEY_P:
					getch();
					break;
				case KEY_A: 
				case KEY_LEFT:
					move_left = true;					
					mchange = true;
					break;
				case KEY_D: 
				case KEY_RIGHT:
					move_right = true;
					mchange = true;
					break;
				case KEY_W: 
				case KEY_SPACE: 
				case KEY_UP:
					if (bn.size() > 0) {
						bullet_group[bn.top()].__init__(plane.x);
						bn.pop();
						bchange = true;
					}
					break;
				case KEY_H:
				case KEY_TAB:
					if (left_b > 0) {
						score += screen_b(bn, en) * ONE_PLANE_SCORE;
						printf("\a");
						schange = true;
						left_b--;
					}
					break;
				case KEY_ESC:
					game_active = false;
					break;
				default:
					break; 
			} 
		} else if (event.KeyUp()){
			move_left = false;
			move_right = false;
			mchange = true;
		}
		if (boss.active) {
			
			kind = boss.crash();
			if (kind != 0) {
				schange = true;
			}
			if (kind == 1) {
				score += BOSS_ESHIP_SCORE;
				left_b++;
			}
			if (boss.Ewin()) {
				game_active = false;
			}
		}
		for (int i = 0; i < MAX_ESHIP; i++) {
			if (Eship_group[i].Ewin()) {
				game_active = false;
			}
			if (Eship_group[i].crash()) {
				score += ONE_PLANE_SCORE;
				printf("\a");
				schange = true;
			}
		}
		
		for (int i = 0; i < MAX_USHIP; i++) {
			if (Uship_group[i].Ewin()) {
				game_active = false;
			}
			if (Uship_group[i].crash()) {
				score += ONE_USHIP_SCORE;
				printf("\a");
				schange = true;
			}
		}
		
		if (cnt % MAKE_USHIP == 0) {
			Uship_group[un.top()].__init__(rand()%(WIDTH-1)+1);
			un.pop();
			uchange = true;
		}
		
		if (cnt % USHIPB == 0) {
			sclear(un);
			for (int i = 0; i < MAX_USHIP; i++) {
				if (Uship_group[i].active) {
					Uship_group[i].blit();
					continue;
				}
				un.push(i);
			}
			uchange = false;
		}
		
		if (cnt % PLANEB == 0 || mchange) {
			if (move_left) {
				if (plane.x > 1) {
					plane.clear(true);
					plane.x--;
				}
			} else if (move_right) {
				if (plane.x < WIDTH) {
					plane.clear();
					plane.x++;
				}
			}
			mchange = false;
		}
		
		if (cnt % BULLETB == 0 || bchange) { 
			sclear(bn);
			for (int i = 0; i < MAX_BULLET; i++) {
				if (bullet_group[i].active) {
					//bullet_group[i].clear();
					bullet_group[i].blit();
					continue;
				}
				bn.push(i);
			}
			bchange = false;
		}
		
		if (cnt % MAKE_BOSS == 0 && !boss.active) {
			boss.__init__(rand()%(WIDTH-1)+1);
		}
		
		if (cnt % BOSSB == 0) {
			boss.blit();
		}
		
		if (cnt % MAKE_ESHIP == 0) {
			Eship_group[en.top()].__init__(rand()%(WIDTH-1)+1);
			en.pop();
			echange = true;
		}
		if (cnt % ESHIPB == 0 || echange) {
			sclear(en);
			for (int i = 0; i < MAX_ESHIP; i++) {
				if (Eship_group[i].active) {
					Eship_group[i].blit();
					continue;
				}
				en.push(i);
			}
			echange = false;
		} 
		if (cnt % SCOREBOARDB == 0 ||schange) {
			gotoxy(WIDTH + 3, 1);
			color(8);
			printf("score: %d", score);
			gotoxy(WIDTH + 3, 2);
			printf("HIscore: %d", HIscore);
			gotoxy(WIDTH + 3, 3);
			printf("left bomb: %2d", left_b);
			gotoxy(WIDTH + 3, 4);
			printf("left lives: %2d", left_life);
			if (boss.active) {	
				gotoxy(WIDTH + 3, 6);
				printf("boss left lives: %2d", boss.left_life);
			}
			schange = false;
		}
		if (!game_active) {
			//Sleep(1000);
			break;
		}
		Sleep(1);
		cnt++;
		//printf("%d", cnt);
	}
	
	left_b = 5;
	set_every_sets_ok(bn, en);
	
	system("cls");
	/*
	write(LOST_MESSAGE);
	pause();
	printf("You got %d points!\n", score);
	pause();
	if (score > HIscore) {
		ofstream fout(SFILE);
		fout << score << endl;
		fout.close();
	}*/
	return score;
}

Score_n start_new_game() {
	Score_n sscore = 0;
	for (int i = PLAYER_LIFE; i > 0; i--) {
		sscore = start_single_game(sscore, i);
		/*system("cls");
		printf("%d\n", sscore);
		pause();*/
	}
	color(NCOLOR);
	write(LOST_MESSAGE);
	pause();
	printf("You got %d points!\n", sscore);
	pause();
	if (sscore > HIscore) {
		printf("\a");
		ofstream fout(SFILE);
		fout << sscore << endl;
		fout.close();
	}
	return sscore;
} 

int main_menu() {
	system("cls");
	system("color 0f");
	// color(ECOLOR);
	return choose_text(menu_chooses, "Ewar\n", ECOLOR);
}

void ask_read_data() {
	printf("Read Data(y/n)?");
	if (confirm()) {
		ifstream fin(SFILE);
		fin >> HIscore;
		fin.close();
	}
	return;
}

int main() {
	if (IsDebuggerPresent()) {
		printf("Error: on debugger!\n");
		//system("pause");
		return 1;
	}
	system("title Ewar3.0");
	menu_chooses.push_back("START GAME!");
	menu_chooses.push_back("Hint");
	menu_chooses.push_back("About");
	menu_chooses.push_back("Exit");
	//hints();
	ask_read_data();
	int select_, score;
	while (true) {
		select_ = main_menu();
		switch(select_) {
			case 0:
				score = start_new_game();
				if (HIscore < score) {
					HIscore = score;
				}
				break;
			case 1:
				hints();
				break;
			case 2:
				show_text(ABOUT);
				break;
			case 3:
				return 0;
			default:
				break;
		}
		
	}
	//task02.join();
	return 0;
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值