飞机大战(类与对象)

这篇文章描述了一个使用C++编写的控制台射击游戏,涉及类的设计(如Creature、Myplane、Bullet和Plane),光标移动函数,以及敌机、子弹的移动和碰撞检测逻辑。玩家通过控制Myplane与敌机和子弹互动,游戏目标是避免碰撞并累计分数。
摘要由CSDN通过智能技术生成
#include<iostream>
#include<conio.h>
#include<windows.h>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
class Creature;
class Myplane;
class Bullet;
class Plane;
struct Position { int x, y; };
vector<Plane*>plane;
vector<Bullet*>bullet;

void gotoxy(int x, int y) //光标移动到(x,y)位置
{
	COORD pos = { x,y };
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两参数分别是指定哪个窗体,具体位置
}

void HideCursor()
{
	CONSOLE_CURSOR_INFO cursor_info = { 1,0 };//第二个值为0表示隐藏光标
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

class Creature {
public:
	Position p;
	bool flag;
	int type;
	Creature() { flag = 1; }
	virtual ~Creature() {}
	virtual void show() {};
};
Creature* map[35][55] = { NULL };

class Bullet :public Creature {
public:
	Bullet(Position s, int Type) {
		type = 3 + Type;
		p.x = s.x;
		if (type == 4)p.y = s.y - 1;
		else p.y = s.y + 1;
	}
	void show() {
		gotoxy(p.x, p.y);
		if (type == 4)printf("\033[32m|\033[0m");
		else printf("|");
	}
	void move() {
		if (type == 4)p.y--;
		if (type == 5)p.y++;
		if (p.y == 0 || p.y == 35)flag = 0;
	}
};

class Myplane :public Creature {
public:
	int count;
	Myplane() { p.x = 28; p.y = 32; type = 1; count = 10; }
	void move(char m) {
		if (m == 'a' && p.x - 1 > 2)p.x--;
		if (m == 'd' && p.x + 1 < 53)p.x++;
		if (m == 's' && p.y + 1 < 33)p.y++;
		if (m == 'w' && p.y - 1 > 0)p.y--;
		if (m == ' ') {
			Bullet* tmp = new Bullet(p, type);
			bullet.push_back(tmp);
		}
	}
	void show() {
		gotoxy(p.x - 2, p.y);
		printf("\033[32m /=\\\033[0m");
		gotoxy(p.x - 2, p.y + 1);
		printf("\033[32m<<*>>\033[0m");
		gotoxy(p.x - 2, p.y + 2);
		printf("\033[32m * *\033[0m");
	}
	void Countdown() {
		count--;
		if (count == 0)flag = 0;
	}
};

class Plane :public Creature {
public:
	Plane() { srand(time(NULL)); p.x = rand() % 33 + 2; p.y = 1; type = 2; }
	void show() {
		gotoxy(p.x - 1, p.y - 1);
		printf("\\+/");
		gotoxy(p.x, p.y);
		printf("|");
	}
	void move() {
		p.y++;
		if (p.y == 35)flag = 0;
		if (p.y % 10 == 0) {
			Bullet* tmp = new Bullet(p, type);
			bullet.push_back(tmp);
		}
	}
};
Myplane myp;
//检测相撞的情况
void draw(Creature* c, int type) {
	if (type == 1)//将我的飞机放在地图上
	{
		for (int j = c->p.y; j <= c->p.y + 2; j++) {
			for (int i = c->p.x - 2; i <= c->p.x + 2; i++) {
				map[j][i] = c;
			}
		}
	}
	else if (type == 2) {  //敌机
		//如果没有与我的飞机相撞则放上地图
		for (int i = c->p.x - 1; i <= c->p.x + 1; i++) {
			if (map[c->p.y - 1][i] == NULL)map[c->p.y - 1][i] = c;
			else {
				c->flag = 0;
				myp.Countdown();
			}
		}
		if (map[c->p.y][c->p.x] == NULL)map[c->p.y][c->p.x] = c;
		//否则敌机死亡 我的飞机count-1
		else {
			c->flag = 0;
			myp.Countdown();
		}
	}
	else {//子弹
		//如果没有相撞则放上地图
		if (map[c->p.y][c->p.x] == NULL)map[c->p.y][c->p.x] = c;
		else {
			//不打同类
			if (c->type - 3 != map[c->p.y][c->p.x]->type) {
				//撞到我的飞机则count-- 子弹flag=0
				if (map[c->p.y][c->p.x]->type == 1)myp.Countdown();
				//撞到敌机则全部flag=0 count++
				else if (map[c->p.y][c->p.x]->type == 2) { map[c->p.y][c->p.x]->flag = 0; myp.count++; }
				//撞到子弹则先出现的子弹flag=0
				else map[c->p.y][c->p.x]->flag = 0;
				c->flag = 0;
			}
		}
	}

}

void display() {
	HideCursor();//隐藏坐标
	//打印边框
	for (int i = 0; i <= 35; i++) {
		for (int j = 0; j <= 55; j++) {
			if (i == 0 || i == 35)cout << '#';
			else if (j == 0 || j == 55)cout << '#';
			else cout << " ";
		}
		cout << endl;
	}
	//打印飞机
	myp.show();
	for (int i = 0; i < plane.size(); i++)plane[i]->show();
	for (int i = 0; i < bullet.size(); i++)bullet[i]->show();
}

int main() {
	int cnt = 0;
	int win = 0;
	while (myp.flag) {
		memset(map, NULL, sizeof(map));
		//敌机及子弹自动移动
		if (cnt == 0) {//生成新敌机
			Plane* diji = new Plane();
			plane.push_back(diji);
		}
		if (cnt % 12 == 0) {//敌机移动
			for (int i = 0; i < plane.size(); i++)plane[i]->move();
		}
		if (cnt % 5 == 0) {//敌机发射的子弹移动
			for (int i = 0; i < bullet.size(); i++)
				if (bullet[i]->type == 5)bullet[i]->move();
		}
		for (int i = 0; i < bullet.size(); i++) {// 我的飞机发射的子弹移动
			if (bullet[i]->type == 4)bullet[i]->move();
		}
		if (cnt == 30)cnt = 0;
		else cnt++;
		//myplane移动
		if (_kbhit()) {
			char mo = _getch();
			myp.move(mo);
		}
		//相撞的飞机子弹flag=0
		draw(&myp, 1);
		for (int i = 0; i < plane.size(); i++) {
			if (plane[i]->flag) {
				draw(plane[i], 2);
			}
			if(plane[i]->flag==0) {
				delete[]plane[i];
				plane[i] = NULL;
				plane.erase(plane.begin() + i);
				i--;
			}
		}
		for (int i = 0; i < bullet.size(); i++) {
			if (bullet[i]->flag) {
				draw(bullet[i], bullet[i]->type);
			}
			if(bullet[i]->flag==0) {
				delete[]bullet[i];
				bullet[i] = NULL;
				bullet.erase(bullet.begin() + i);
				i--;
			}
		}
		if (myp.count >= 15) { win = 1; break; }
		//显示画面
		gotoxy(0, 0);
		display();
		Sleep(50);
	}
	gotoxy(0, 36);
   	if (win)cout << "you are win!";
	else cout << "you are false!";
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值