IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 飞机小游戏流畅版 -> 正文阅读

[C++知识库]飞机小游戏流畅版

提示:新人入坑,采用的新手模板草草写就,望谅解


前言

在做课下的游戏设计作业时,因为一时乐趣加入了一些功能,最后的完成代码可玩性不错,于是决定分享出来。


提示:以下是本篇文章正文内容

在这里插入图片描述

一、代码原理和功能

代码采用了数组的方式,像一张无数格子(长宽相乘)组成的地图来存储每一格元素,并用数字赋值,以在打印时对应输出边框,飞机,子弹,敌机这些元素。若有用户输入,则对应改变格子的赋值,以及将之前的格子赋值为空白(移动的位置更新,即新的位置赋值元素,旧的位置将元素清除)。
同时为了扩展玩法,加入了难度选择,增强我方实力,RGB炫彩光效界面等功能,详情请阅读代码,如进入游戏界面按下y则开启RGB,按下l可以增强实力等等。
注释较多,应当容易看懂,当然,在程序员眼里,别人的代码都是(粗鄙之言)。
以下直接附上源代码:

二、成果展示

1.源代码

代码如下(示例):

#include <stdio.h>
#include<iostream>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>

using namespace std;
#pragma warning(disable:4996)//屏蔽了4996的错误

#define High 30  // 游戏画面尺寸
#define Width 50
//#define BadNum 1 // 敌机个数
int BadNum = 1; // 敌机个数

// 全局变量
int defu = 0; //德芙巧克力!
int life = 0; //生命值 高难度下赋值为1,在分数达到落败分后加分续上一命
int MaxSpeed = 3;  //敌机最大速度
int MaxWidth = 2;  //最大弹幕数 即两边增加的弹幕数
int RGB = 7, on = 0;//rgb颜色参数,开关   通过改变RGB数值输出不同的符号颜色
int Plane_x, Plane_y; // 飞机位置
//int enemy_x[BadNum], enemy_y[BadNum];  // 敌机位置
int enemy_x[30], enemy_y[30];  //敌机最大数量
int map[High][Width] = { 0 }; // 二维数组存储游戏画布中对应的元素
						// 0为空格,1为飞机*,2为子弹|,3为敌机@,4为 |,5为-
int score; // 得分
int FireWidth; // 子弹宽度
int EnemySpeed = 10; // 敌机移动速度

void HideCursor()//用于隐藏光标    //这两个函数无脑写上并加到打印里就可以解决刷新的闪烁问题
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };//第二个值为0表示隐藏光标
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

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

void start() // 数据初始化
{
	Plane_x = High - 2;
	Plane_y = Width / 2;
	map[Plane_x][Plane_y] = 1;
	int j, k;
	for (k = 0; k < High; k++) {//初始化边框
		for (j = 0; j < Width; j++) {
			if (j == 0 || j == Width - 1) map[k][j] = 4;//竖向
			if (k == 0 || k == High - 1) map[k][j] = 5;//横向
		}
	}
	for (k = 0; k < BadNum; k++)//敌机初始化
	{
		enemy_x[k] = rand() % 2 + 1;
		enemy_y[k] = rand() % (Width - 2) + 1;
		map[enemy_x[k]][enemy_y[k]] = 3;
	}
	score = 0;//初始分数
	FireWidth = 0;//子弹未强化
}

void die() {//失败效果
	system("cls");
	cout << "\n\n\n\n\n\n\t\t\t游戏结束!\n" << endl;
	cout << "\n\n\t\t\t你失败了!\n" << endl;
	Sleep(2000);
	exit(0);
}

void win() {//胜利效果
	system("cls");
	while (1) {
		HideCursor();//隐藏光标
		gotoxy(0, 0);  // 光标移动到原点位置,以下重画清屏
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), RGB);//改变颜色为背景黑色,字符青色
		if (RGB < 11) {
			RGB++;
		}
		else {
			RGB = 1;
		}
		cout << "\n\n\n\n\n\n\t\t\t游戏胜利!\n" << endl;
		cout << "\n\n\t\t\t666!\n" << endl;
		if (BadNum >= 10) {//如果战胜硬汉及以上难度显示
			cout << "\n\n\t\t\tyyds!\n" << endl;
		}
	}
	Sleep(2000);
	exit(0);
}
void updateAuto() {//非按键输入的更新
	int i, j, k;
	for (i = 0; i < High; i++)//遍历每一个元素
	{
		for (j = 0; j < Width; j++)
		{
			if (map[i][j] == 2)
			{
				for (k = 0; k < BadNum; k++)
				{
					if ((i == enemy_x[k]) && (j == enemy_y[k]))  // 子弹击中敌机
					{
						score++;   // 分数加1
						if (!defu) {//非德芙模式30分获胜
							if (score >= 30)
								win();
						}
						else {//德芙模式加分太快,则500
							if (score >= 500)
								win();
						}
						if (score % 5 == 0 && EnemySpeed > MaxSpeed)   // 达到一定积分后,敌机变快
							EnemySpeed--;
						if (score % 3 == 0 && FireWidth < MaxWidth)   // 达到一定积分后,子弹变厉害
							FireWidth++;
						map[enemy_x[k]][enemy_y[k]] = 0;
						enemy_x[k] = rand() % (2) + 1;           // 产生新的飞机
						enemy_y[k] = rand() % (Width - 2) + 1;
						map[enemy_x[k]][enemy_y[k]] = 3;
						map[i][j] = 0;      // 子弹消失
					}
				}
				// 子弹向上移动
				map[i][j] = 0;
				if (i > 0)
					map[i - 1][j] = 2;
				if (i <= 1)
					map[0][j] = 5;
			}
		}
	}

	static int speed = 0;
	if (speed < EnemySpeed)
		speed++;
	for (k = 0; k < BadNum; k++)
	{
		if ((Plane_x == enemy_x[k]) && (Plane_y == enemy_y[k]))  // 敌机撞到我机
		{
			die();
		}
		if (enemy_x[k] > High - 3)   // 敌机跑出显示屏幕
		{
			map[enemy_x[k]][enemy_y[k]] = 0;
			enemy_x[k] = rand() % (3) + 1;           // 产生新的飞机
			enemy_y[k] = rand() % (Width - 2) + 1;
			map[enemy_x[k]][enemy_y[k]] = 3;
			score--;  // 减分
			if (score < -10  && life == 0)//普通模式没有濒死buff
				die();
			if (score < -10 && life > 0) {//获得濒死buff,分数加15拥有新的机会
				life = 0;//只发生一次
				score += 15;
			}
		}
		if (speed == EnemySpeed)
		{
			// 敌机下落
			for (k = 0; k < BadNum; k++)
			{
				map[enemy_x[k]][enemy_y[k]] = 0;
				enemy_x[k]++;
				speed = 0;
				map[enemy_x[k]][enemy_y[k]] = 3;
			}
		}
	}
}
void strong() {//增强玩家实力   //德芙模式下没有意义了,你不需要变强了
	system("cls");
	printf("\n\n\n\t\t嘿!你是否觉得难度太高? \n\n");
	printf("\t\t(=‘ W ’=) \n\n");
	printf("\t\t那就给你些力量吧! \n\n");
	printf("\t\t请选择强化方式! \n\n");
	printf("\t\t1.狂 暴 弹 幕  m\n\n");
	printf("\t\t2.时 间 掌 控  n\n\n");
	char a = ' ';
	a = _getch();
	if (a == 'm') {
		system("cls");
		printf("\n\n\n\t\t解放力量会释放更加强大的弹幕! \n\n");
		printf("\t\t强大的弹幕会破坏左右墙壁! \n\n");
		printf("\t\t请选择强化等级!(按等级对应字母) \n\n");
		printf("\t\t1.一级  i\n\n");
		printf("\t\t1.二级  o\n\n");
		printf("\t\t1.超级  p\n\n");
		char a = ' ';
		a = _getch();//增加子弹宽度和上限
		if (a == 'i')
			MaxWidth++;
		else if (a == 'o')
			MaxWidth += 2, FireWidth++;
		else if (a == 'p')
			MaxWidth += 12, FireWidth += 12;
	}
	else if (a == 'n') {
		system("cls");
		printf("\n\n\n\t\t控制时间使敌人前进速度更慢! \n\n");
		printf("\t\t请选择强化等级!(按等级对应字母) \n\n");
		printf("\t\t1.一级  i\n\n");
		printf("\t\t1.二级  o\n\n");
		char a = ' ';
		a = _getch();//减小敌人峰值速度,对高难度无作用
		if (a == 'i')
			MaxSpeed += 2;
		else if (a == 'o')
			MaxSpeed += 4;
	}
}
void update() {//德芙模式下的操作
	int m, n;
	m = Plane_x, n = Plane_y;
	if ((GetAsyncKeyState(0x41) & 0x8000) && Plane_y > 1 + FireWidth)//FireWidth用于限制移动,子弹能够到的地方人物就不必要过去了
	{
		Plane_y--;	// 位置左移
	}
	else if ((GetAsyncKeyState(0x44) & 0x8000) && Plane_y < Width - 2 - FireWidth)
	{
		Plane_y++;  // 位置右移
	}
	else if ((GetAsyncKeyState(0x57) & 0x8000) && Plane_x > 1)
	{
		Plane_x--;  // 位置上移
	}
	else if ((GetAsyncKeyState(0x53) & 0x8000) && Plane_x < High - 2)
	{
		Plane_x++;  // 位置下移
	}
	else if (GetAsyncKeyState(0x59) & 0x8000)
	{
		on = on == 0 ? 1 : 0;//按y开启RGB
		if (on == 0) RGB = 7;
	}
	map[m][n] = 0;
	map[Plane_x][Plane_y] = 1;

	if (GetAsyncKeyState(0x20) & 0x8000)//开火 空格
	{
		int left = Plane_y - FireWidth;
		int right = Plane_y + FireWidth;
		if (left < 0)
			left = 0;
		if (right > Width - 1)
			right = Width - 1;
		int k;
		for (k = left; k <= right; k++) // 发射闪弹
			map[Plane_x - 1][k] = 2; // 发射子弹的初始位置在飞机的正上方
	}
}
void updateGetchar() {//普通模式下的操作
	char input;
	int m, n;
	if (kbhit())  // 判断是否有输入
	{
		m = Plane_x, n = Plane_y;
		input = getch();  // 根据用户的不同输入来移动,不必输入回车
		if (input == 'a' && Plane_y > 1 + FireWidth)
		{
			Plane_y--;  // 位置左移
		}
		else if (input == 'd' && Plane_y < Width - 2 - FireWidth)
		{
			Plane_y++;  // 位置右移
		}
		else if (input == 'w' && Plane_x > 1)
		{
			Plane_x--;  // 位置上移
		}
		else if (input == 's' && Plane_x < High - 2)
		{
			Plane_x++;  // 位置下移
		}
		else if (input == 'y')//开启RGB灯效
		{
			on = on == 0 ? 1 : 0;
			if (on == 0) RGB = 7;
		}
		else if (input == 'l')//变得更强(买挂)
		{
			strong();
		}
		else if (input == 'z')//吃下德芙,不可逆
		{
			defu = defu == 0 ? 1 : 0;
		}
		else if (input == ' ')  // 发射子弹
		{
			int left = Plane_y - FireWidth;
			int right = Plane_y + FireWidth;
			if (left < 0)
				left = 0;
			if (right > Width - 1)
				right = Width - 1;
			int k;
			for (k = left; k <= right; k++) // 发射闪弹
				map[Plane_x - 1][k] = 2; // 发射子弹的初始位置在飞机的正上方
		}
		map[m][n] = 0;
		map[Plane_x][Plane_y] = 1;
	}
	
}

void show()  // 显示画面
{
	HideCursor();//隐藏光标
	gotoxy(0, 0);  // 光标移动到原点位置,以下重画清屏
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), RGB);//改变颜色为RGB数字
	if (RGB < 11 && on == 1) {//颜色变换
		RGB++;
	}
	else {//重置
		if (on == 1)
			RGB = 1;
	}
	int i, j;
	for (i = 0; i < High; i++)
	{
		for (j = 0; j < Width; j++)
		{
			if (map[i][j] == 0)
				printf(" ");   //   输出空格
			else if (map[i][j] == 1)
				printf("*");   //   输出飞机*
			else if (map[i][j] == 2)
				printf("|");   //   输出子弹|
			else if (map[i][j] == 3)
				printf("@");   //  输出敌机@
			else if (map[i][j] == 4)
				printf("|");   //   输出围墙纵
			else if (map[i][j] == 5)
				printf("-");   //  输出围墙横
		}
		printf("\n");
	}//一众状态栏
	printf("\n得分:%d \n", score);
	if (on == 1)
		printf("RGB:开启 \n");
	else
		printf("RGB:关闭 \n");
	printf("敌人速度(越小越快):%d \n", EnemySpeed);
	if (!defu) {
		printf("按l获得力量! \n");
		printf("按z大哥吃德芙! \n");
	}
	else {
		printf("德芙,纵享丝滑! \n");
		printf("吃掉德芙的你已经天下无敌了,享受游戏吧! \n");
	}
	printf("随机刷新精英怪,拥有护盾! \n");
	if (life > 0) {
		printf("获得免疫一次死亡的机会(撞到不算)!\n");
	}
}

void choice() {//难度选择
	printf("\n\n\n\t\t欢迎来到飞机大战! \n\n");
	printf("\t\t请选择难度!(按难度对应字母,默认普通) \n\n");
	printf("\t\t1.普通 u\n");
	printf("\t\t2.困难 i\n");
	printf("\t\t3.大师 o\n");
	printf("\t\t4.硬汉 p\n");
	printf("\t\t5.神谕 l\n");
	printf("\t\t6.人类一败涂地 h\n");
	printf("\t\t7.开挂吧 b\n");
	char a = ' ';
	a = _getch(); 
	if (a == 'u')
		;   //默认模式
	else if (a == 'i')
		BadNum = 2;   //敌人加一
	else if (a == 'o')
		BadNum = 4;   //敌人为四
	else if (a == 'p')
		BadNum = 10;   //敌人为十
	else if (a == 'l') {//敌人为十以及初始速度更快
		BadNum = 10;
		EnemySpeed = 6;
		life = 1;
	}   //  输出敌机@
	else if (a == 'h') {//更多敌人和更快速度
		BadNum = 15;
		EnemySpeed = 3;
		life = 1;
	}//  输出敌机@
	else if (a == 'b') {//超级多敌人
		BadNum = 30;
		EnemySpeed = 3;
		life = 1;
	}// 
	system("cls");
}

int main()
{
	choice();
	start();  // 数据初始化
	while (1) //  游戏循环执行
	{
		show();  // 显示画面
		updateAuto();  // 与用户输入无关的更新
		if (!defu)
			updateGetchar();  // 与用户输入有关的更新
		else
			update();//德芙方向及开火操作系统
	}
	return 0;
}


总结

因为原来的控制方式在while的每次循环中只能接收一个字符并发生相应改变,控制操作自然很生硬,所以我在后来加入了新的控制方式,按下z则进入,流畅度大大提升,值得一试。不过因为每次循环可以接收很多字符,键盘的一次按下和抬起速度如果不够快就会产生多个同样字符,仅仅只影响流畅模式下的RGB效果开启。
为何保留了两个操作方法是因为在流畅模式下难度根本没有意义,随便按按就通过了。
以上。

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-29 10:03:43  更:2021-09-29 10:04:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 4:24:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计