每周一坑--打飞机游戏

看了知乎上的一个C语言做的打飞机游戏(控制台)https://zhuanlan.zhihu.com/p/24798125

决定自己做一个C++版的。

先说一下原来游戏的思路。 

首先主函数: 先初始化,然后再一个循环里不断地

显示-->更新与用户无关数据-->用户输入、根据输入更新。

显示是通过一个二维数组canvas (画布)来实现的,通过一个二层循环来在画布上进行绘制(输出字符)

字符的形状代表是 飞机或子弹或者空气。

更新与用户无关数据是按照一个规律:敌机往下飞,子弹往上飞,这样更新的。

根据输入更新            是根据用户输入的'a' 'd'或空格 来设置自己的位置和发射子弹。


int main()
{
	startup();  // 数据初始化	
	while (1)  // 游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();  // 与用户输入有关的更新
	}
	return 0;
}

下面具体地操作。

那么既然要用C++,飞机就可以做成一个基类了。

然后从飞机 派生出两个类 一个是自己,一个是敌机。

自己和敌机有什么不同? 在这里为了简化,敌机不发射子弹,只是简单地往下移动。 自己是可以发射子弹的。

class Plane
{
private:
	int x;
	int y;
	int MoveSpeed;
public:
	Plane() :x(0), y(0) {};
	Plane(int x, int y) :x(x), y(y) {}
	~Plane(){}
	int getX() { return x; }
	int getY() { return y; }
	int getMoveSpeed(){ return MoveSpeed; }
	void setX(int x) { this->x =x; }
	void setY(int y) { this->y = y; }
	void setMoveSpeed(int speed){ MoveSpeed = speed; }
};

class MyPlane : public Plane
{
private:
	int BulletWidth;

public:
	int getBulletWidth() { return BulletWidth; }
	void setBulletWidth(int width) { this->BulletWidth = width; }

};
class EnemyPlane : public Plane
{

};

除了飞机,其他的基本根据原来的改写,因为图像的显示主要依靠画布,所以如果画布不改动的话,其余的基本改变不大。

改写时为了方便,我将原来的长函数分解成短函数,看起来更容易。

最后的代码:

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include"plane.h"
#include"updateFunction.h"

const int High     = 15;// 游戏画面尺寸
const int Width    = 25;
const int EnemyNum = 5;// 敌机个数

// 全局变量
MyPlane myPlane; // 飞机
EnemyPlane enemyPlane[EnemyNum];  // 敌机
int canvas[High+1][Width+1] = { 0 }; // 二维数组存储游戏画布中对应的元素
						       // 0为空格,1为飞机*,2为子弹|,3为敌机@
int score; // 得分

 //光标移动到(x,y)位置
void gotoxy(int x, int y) 
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void startup() // 数据初始化
{
	//下面的两行用于隐藏光标,防止乱闪
	CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);

	//设自己置飞机位置
	startupMyPlane();
	//设置敌机位置
	 startupEnemyPlane();
	 score = 0;
}

void startupMyPlane()
{
	myPlane.setX(High - 1);
	myPlane.setY(Width - 2);
	myPlane.setBulletWidth(0);
}
void startupEnemyPlane()
{
	for (int k = 0; k < EnemyNum; k++)
	{
		enemyPlane[k].setX(rand() % 2);
		enemyPlane[k].setY(rand() % Width);
		enemyPlane[k].setMoveSpeed(20);
	}
}

// 显示画面
void show()  
{
	gotoxy(0, 0);  // 光标移动到原点位置,以下重画清屏
	for (int i = 0; i < High; i++)
	{
		for (int j = 0; j < Width; j++)
		{
			if (canvas[i][j] == 0)
				printf(" ");   //   输出空格
			else if (canvas[i][j] == 1)
				printf("*");   //   输出飞机*
			else if (canvas[i][j] == 2)
				printf("|");   //   输出子弹|
			else if (canvas[i][j] == 3)
				printf("@");   //  输出飞机@
		}
		printf("\n");
	}
	printf("得分:%d\n", score);
	Sleep(20);
}

// 与用户输入无关的更新
void updateWithoutInput()  
{   //更新子弹位置
	for (int i = 0; i < High; i++) {
		for (int j = 0; j < Width; j++) {
			if (canvas[i][j] == 2)    {
				updateBullet(i, j);
			}
		}
	}
	static int speed = 0;
	if (speed < enemyPlane[0].getMoveSpeed())
		speed++;
	updatePlane(speed );
}


void updateBullet(int i,int j)
{
	for (int k = 0; k < EnemyNum; k++) {
		if ((i == enemyPlane[k].getX()) && (j == enemyPlane[k].getY()))  // 子弹击中敌机
		{
			score++;                // 分数加1
			if (score % 5 == 0 && enemyPlane[k].getMoveSpeed() > 3)   // 达到一定积分后,敌机变快
				enemyPlane[k].setMoveSpeed(enemyPlane[k].getMoveSpeed() - 1);
			if (score % 5 == 0)   // 达到一定积分后,子弹变厉害
				myPlane.setBulletWidth(myPlane.getBulletWidth() + 1);
			canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 0;
			enemyPlane[k].setX(rand() % 2);           // 产生新的飞机
			enemyPlane[k].setY(rand() % Width);
			canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 3;
			canvas[i][j] = 0;      // 子弹消失
		}
	}
	// 子弹向上移动
	canvas[i][j] = 0;
	if (i > 0)
		canvas[i - 1][j] = 2;
}
void updatePlane(int& speed )
{
	for (int k = 0; k < EnemyNum; k++)
	{
		if ((myPlane.getX() == enemyPlane[k].getX()) && (myPlane.getY() == enemyPlane[k].getY()))  // 敌机撞到我机
		{
			printf("失败!\n");
			Sleep(3000);
			system("pause");
			exit(0);
		}

		if (enemyPlane[k].getX() > High)   // 敌机跑出显示屏幕
		{
			canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 0;
			enemyPlane[k].setX(rand() % 2);           // 产生新的飞机
			enemyPlane[k].setY(rand() % Width);
			canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 3;
			score--;  // 减分
		}

		if (speed == enemyPlane[0].getMoveSpeed())
		{
			// 敌机下落
			for (k = 0; k < EnemyNum; k++)
			{
				canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 0;
				enemyPlane[k].setX(enemyPlane[k].getX() + 1);
				speed = 0;
				canvas[enemyPlane[k].getX()][enemyPlane[k].getY()] = 3;
			}
		}
	}
}

void updateWithInput()  // 与用户输入有关的更新
{
	char input;
	if (_kbhit())  // 判断是否有输入
	{
		input = _getch();  // 根据用户的不同输入来移动,不必输入回车
		if (input == 'a' && myPlane.getX() > 0)
		{
			canvas[myPlane.getX()][myPlane.getY()] = 0;
			myPlane.setY(myPlane.getY()-1);  // 位置左移
			canvas[myPlane.getX()][myPlane.getY()] = 1;
		}
		else if (input == 'd' && myPlane.getY() < Width - 1)
		{
			canvas[myPlane.getX()][myPlane.getY()] = 0;
			myPlane.setY(myPlane.getY() +1);  // 位置右移
			canvas[myPlane.getX()][myPlane.getY()] = 1;
		}
		else if (input == 'w')
		{
			canvas[myPlane.getX()][myPlane.getY()] = 0;
			myPlane.setX(myPlane.getX() - 1);;  // 位置上移
			canvas[myPlane.getX()][myPlane.getY()] = 1;
		}
		else if (input == 's')
		{
			canvas[myPlane.getX()][myPlane.getY()] = 0;
			myPlane.setX(myPlane.getX() +1);;  // 位置上移
			canvas[myPlane.getX()][myPlane.getY()] = 1;
		}
		else if (input == ' ')  // 发射子弹
		{
			int left = myPlane.getY() - myPlane.getBulletWidth() ;
			int right = myPlane.getY() + myPlane.getBulletWidth();
			if (left < 0)
				left = 0;
			if (right > Width - 1)
				right = Width - 1;
			int k;
			for (k = left; k <= right; k++) // 发射闪弹
				canvas[myPlane.getX() - 1][k] = 2; // 发射子弹的初始位置在飞机的正上方
		}
	}
}

int main()
{
	startup();  // 数据初始化	
	while (1)  // 游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();  // 与用户输入有关的更新
	}
	return 0;
}

updateFunction.h 

#pragma once
void startupMyPlane();
void startupEnemyPlane();
void updateBullet(int i, int j);
void updatePlane(int& speed);

plane.h 

#pragma once

class Plane
{
private:
	int x;
	int y;
	int MoveSpeed;
public:
	Plane() :x(0), y(0) {};
	Plane(int x, int y) :x(x), y(y) {}
	~Plane(){}
	int getX() { return x; }
	int getY() { return y; }
	int getMoveSpeed(){ return MoveSpeed; }
	void setX(int x) { this->x =x; }
	void setY(int y) { this->y = y; }
	void setMoveSpeed(int speed){ MoveSpeed = speed; }
	int condition;
};


class MyPlane : public Plane
{
private:
	int BulletWidth;

public:
	MyPlane(){ Plane(); condition = 1; };
	MyPlane(int x, int y) :Plane(x, y) { condition = 1; }
	~MyPlane() {}
	int getBulletWidth() { return BulletWidth; }
	void setBulletWidth(int width) { this->BulletWidth = width; }

};
class EnemyPlane : public Plane
{
public:
	static int num;
public:
	EnemyPlane() { Plane(); condition = 3; };
	EnemyPlane(int x, int y) : Plane(x, y) { condition = 3; }
	~EnemyPlane() {}

};

猜你喜欢

转载自blog.csdn.net/qq_41068877/article/details/84140916