简单游戏制作——飞行棋
控制台初始化
int w = 50;
int h = 50;
ConsoleInit(w, h);
static void ConsoleInit(int w, int h)
{//基础设置//光标的隐藏Console.CursorVisible = false;//舞台的大小Console.SetWindowSize(w, h);Console.SetBufferSize(w, h);
}
场景选择相关
#region 场景选择相关
//声明一个表示场景标识的变量
E_SceneType nowSceneType = E_SceneType.Begin;
while (true)
{switch (nowSceneType){case E_SceneType.Begin://开始场景逻辑Console.Clear();break;case E_SceneType.Game://游戏场景逻辑Console.Clear();break;case E_SceneType.End://结束场景逻辑Console.Clear();break;default:break;}
}
#endregion
/// <summary>
/// 游戏场景枚举类型
/// </summary>
enum E_SceneType
{/// <summary>/// 开始场景/// </summary>Begin,/// <summary>/// 游戏场景/// </summary>Game,/// <summary>/// 结束场景/// </summary>End
}
开始场景逻辑实现
static void GameScene(int w, int h, ref E_SceneType nowSceneType)
{Console.SetCursorPosition(w / 2 - 3, 8);Console.Write("飞行棋");//当前选项的编号int nowSelIndex = 0;bool isQuitBengin = false;//开始场景逻辑处理函数while (true){Console.SetCursorPosition(w / 2 - 4, 13);Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;Console.Write("开始游戏");Console.SetCursorPosition(w / 2 - 4, 15);Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;Console.Write("退出游戏");//通过ReadKey可以得到一个输入的枚举类型switch (Console.ReadKey(true).Key){case ConsoleKey.W:--nowSelIndex;if (nowSelIndex < 0){nowSelIndex = 0;}break;case ConsoleKey.S:++nowSelIndex;if (nowSelIndex > 1){nowSelIndex = 1;}break;case ConsoleKey.J:if (nowSelIndex == 0){//进入游戏场景//1.改变当前场景的IDnowSceneType = E_SceneType.Game;//退出当前循环isQuitBengin = true;}else{//退出游戏Environment.Exit(0);}break;}//通过标识决定是否跳出开始场景的循环if (isQuitBengin){break;}}
}
游戏场景逻辑实现
不变的红墙
static void DrawWall(int w, int h)
{Console.ForegroundColor = ConsoleColor.Red;//画墙//横着的墙for (int i = 0; i < w; i += 2){//最上方的墙Console.SetCursorPosition(i, 0);Console.Write("■");//最下面的墙Console.SetCursorPosition(i, h - 1);Console.Write('■');//中间的墙Console.SetCursorPosition(i, h - 6);Console.Write('■');Console.SetCursorPosition(i, h - 11);Console.Write('■');}//竖着的墙for (int i = 0; i < h; i++){//最左边Console.SetCursorPosition(0, i);Console.Write('■');Console.SetCursorPosition(w - 2, i);Console.Write('■');}//文字信息Console.ForegroundColor = ConsoleColor.White;Console.SetCursorPosition(2, h - 10);Console.Write("□:普通格子");Console.ForegroundColor = ConsoleColor.Blue;Console.SetCursorPosition(2, h - 9);Console.Write("‖:暂停,一回合不动");Console.ForegroundColor = ConsoleColor.Red;Console.SetCursorPosition(26, h - 9);Console.Write("●:炸弹,倒退5格");Console.ForegroundColor = ConsoleColor.Yellow;Console.SetCursorPosition(2, h - 8);Console.Write("¤:时空隧道,随机倒退,暂停,换位置");Console.ForegroundColor = ConsoleColor.Cyan;Console.SetCursorPosition(2, h - 7);Console.Write("★:玩家");Console.ForegroundColor = ConsoleColor.Magenta;Console.SetCursorPosition(12, h - 7);Console.Write("▲:电脑");Console.ForegroundColor = ConsoleColor.DarkGreen;Console.SetCursorPosition(22, h - 7);Console.Write("◎:玩家和电脑重合");Console.ForegroundColor = ConsoleColor.White;Console.SetCursorPosition(2, h - 5);Console.Write("按任意键开始扔色子");
}
格子结构体和格子枚举
/// <summary>
/// 格子类型枚举
/// </summary>
enum E_Grid_type
{/// <summary>/// 普通格子/// </summary>Normal,/// <summary>/// 炸弹/// </summary>Boom,/// <summary>/// 暂停/// </summary>Pause,/// <summary>/// 时空隧道,随机倒退,暂停,换位置/// </summary>Tunnel,
}struct Vector2
{public int x;public int y;public Vector2(int x, int y){this.x = x;this.y = y;}
}struct Grid
{//格子的类型E_Grid_type type;//格子的位置public Vector2 pos;//初始化构造函数public Grid(int x, int y, E_Grid_type type){pos.x = x;pos.y = y;this.type = type;}public void Draw(){//提出来的目的,就是少写几行代码,因为它们不管哪种类型,都要设置了位置再画Console.SetCursorPosition(pos.x, pos.y);switch (type){//普通格子怎么画case E_Grid_type.Normal:Console.ForegroundColor = ConsoleColor.White;Console.Write("□");break;//炸弹怎么画case E_Grid_type.Boom:Console.ForegroundColor = ConsoleColor.Red;Console.Write("●");break;//暂停怎么画case E_Grid_type.Pause:Console.ForegroundColor = ConsoleColor.Blue;Console.Write("‖");break;//时空隧道怎么画case E_Grid_type.Tunnel:Console.ForegroundColor = ConsoleColor.Yellow;Console.Write("¤");break;}}
}
地图结构体
struct Map
{public Grid[] grids;//初始化中初始了各个格子类型和位置public Map(int x, int y, int num){grids = new Grid[num];//用于位置变化计数的变量//表示X变化的次数int indexX = 0;//表示Y变化的次数int indexY = 0;//x的步长int stepNum = 2;Random r = new Random();int randomNum;for (int i = 0; i < num; i++){//应该初始化格子类型randomNum = r.Next(0, 101);//设置类型,普通格子//有85%几率是普通格子(首尾两个格子,必为普通格子)if (randomNum < 85 || i == 0 || i == num - 1){grids[i].type = E_Grid_type.Normal;}//有5%的几率是炸弹else if (randomNum >= 85 && randomNum < 90){grids[i].type = E_Grid_type.Boom;}//有5%的几率是暂停else if (randomNum >= 90 && randomNum < 95){grids[i].type = E_Grid_type.Pause;}//有5%的几率是时空隧道else{grids[i].type = E_Grid_type.Tunnel;}//位置应该如何设置grids[i].pos = new Vector2(x, y);//每次循环都应该按一定规则去变化位置//加十次if (indexX == 10){y += 1;//加一次Y记一次数++indexY;if (indexY == 2){//y加了2次过后,把x加的次数记0indexX = 0;indexY = 0;//反向步长stepNum = -stepNum;}}else{x += stepNum;//加一次x记一次数++indexX;}}}public void Draw(){for (int i = 0; i < grids.Length; i++){grids[i].Draw();}}
}
玩家枚举和玩家结构体
/// <summary>
/// 玩家枚举类型
/// </summary>
enum E_PlayType
{/// <summary>/// 玩家/// </summary>Player,/// <summary>/// 电脑/// </summary>Computer,
}struct Player
{//玩家类型public E_PlayType type;//当前所在地图哪一个索引的格子public int nowIndex;public Player(int index, E_PlayType type){nowIndex = index;this.type = type;}public void Draw(Map mapInfo){//必需要先得到地图才能够得到玩家在地图上的哪一个格子//从传入的地图中得到格子信息Grid grid = mapInfo.grids[nowIndex];//设置位置Console.SetCursorPosition(grid.pos.x, grid.pos.y);//画,设置颜色,设置图标switch (type){case E_PlayType.Player:Console.ForegroundColor = ConsoleColor.Cyan;Console.Write("★");break;case E_PlayType.Computer:Console.ForegroundColor = ConsoleColor.Magenta;Console.Write("▲");break;default:break;}}
}
static void DrawPlayer(Player player, Player computer, Map map)
{//重合时if (player.nowIndex == computer.nowIndex){//得到重合的位置Grid grid = map.grids[player.nowIndex];Console.SetCursorPosition(grid.pos.x, grid.pos.y);Console.ForegroundColor = ConsoleColor.DarkGreen;Console.Write("◎");}//不重合的时候else{player.Draw(map);computer.Draw(map);}
}
扔色子逻辑
//擦除提示的函数
static void ClearInfo(int h)
{Console.SetCursorPosition(2, h - 5);Console.Write(" ");Console.SetCursorPosition(2, h - 4);Console.Write(" ");Console.SetCursorPosition(2, h - 3);Console.Write(" ");Console.SetCursorPosition(2, h - 2);Console.Write(" ");
}///<summary>
///扔色子函数
///</summary>
///<param name="w">窗口的宽</param>
///<param name="h">窗口的高</param>
///<param name="p">扔色子的对象</param>
///<param name="map">地图信息</param>
///<returns>默认返回false,代表没有结束</returns>
static bool RandomMove(int w, int h, ref Player p, ref Player otherp, Map map)
{//擦除之前显示的信息ClearInfo(h);//根据扔色子的玩家类型,决定信息的颜色Console.ForegroundColor = p.type == E_PlayType.Player ? ConsoleColor.Cyan : ConsoleColor.Magenta;//扔色子之前判断玩家是否处于暂停状态if (p.isPause){Console.SetCursorPosition(2, h - 5);Console.Write("处于暂停点,{0}需要暂停一回合", p.type == E_PlayType.Player ? "你" : "电脑");Console.SetCursorPosition(2, h - 4);Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayType.Player ? "电脑" : "你");//停止暂停p.isPause = false;return false;}//扔色子的目的是改变玩家或者电脑的位置,计算位置的变化//默认没有结束//扔色子,随机一个1到6的数加上去Random r = new Random();int randomNum = r.Next(1, 7);p.nowIndex += randomNum;//打印扔的点数Console.SetCursorPosition(2, h - 5);Console.Write("{0}扔出的点数为:{1}", p.type == E_PlayType.Player ? "你" : "电脑", randomNum);//首先判断是否到终点了if (p.nowIndex >= map.grids.Length - 1){p.nowIndex = map.grids.Length - 1;Console.SetCursorPosition(2, h - 4);if (p.type == E_PlayType.Player){Console.Write("恭喜你,你率先到达了终点");}else{Console.Write("很遗憾,电脑率先到达了终点");}Console.SetCursorPosition(2, h - 3);Console.Write("请按任意键结束游戏");return true;}else{//没有到达终点就判断当前对象倒了一个什么样的格子Grid grid = map.grids[p.nowIndex];switch (grid.type){case E_Grid_type.Normal://普通格子不用处理Console.SetCursorPosition(2, h - 4);Console.Write("{0}到了一个安全的位置", p.type == E_PlayType.Player ?"你" : "电脑");Console.SetCursorPosition(2, h - 3);Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayType.Player ? "你" : "电脑");break;case E_Grid_type.Boom://炸弹退格p.nowIndex -= 5;//不能比起点还小if (p.nowIndex < 0){p.nowIndex = 0;}Console.SetCursorPosition(2, h - 4);Console.Write("{0}踩到了炸弹,后退5格", p.type == E_PlayType.Player ?"你" : "电脑");Console.SetCursorPosition(2, h - 3);Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayType.Player ? "你" : "电脑");break;case E_Grid_type.Pause://暂停一回合//暂停目的,只有加一个对象的暂停标识,才能知道下一回合它是不是不能扔色子p.isPause = true;Console.SetCursorPosition(2, h - 4);Console.Write("{0}踩到了炸弹,退后5格", p.type == E_PlayType.Player ?"你" : "电脑");Console.SetCursorPosition(2, h - 3);Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayType.Player ? "你" : "电脑");break;case E_Grid_type.Tunnel:Console.SetCursorPosition(2, h - 4);Console.Write("{0}踩到了时空隧道", p.type == E_PlayType.Player ?"你" : "电脑");Console.SetCursorPosition(2, h - 3);Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayType.Player ? "你" : "电脑");//随机randomNum = r.Next(1, 91);//触发倒退if (randomNum <= 30){p.nowIndex -= 5;if (p.nowIndex < 0){p.nowIndex = 0;}Console.SetCursorPosition(2, h - 3);Console.Write("触发倒退5格");}//触发暂停else if (randomNum <= 60){p.isPause = true;Console.SetCursorPosition(2, h - 3);Console.Write("触发暂停一回合");}//触发交换位置else{int temp = p.nowIndex;p.nowIndex = otherp.nowIndex;otherp.nowIndex = temp;Console.SetCursorPosition(2, h - 3);Console.Write("惊喜,惊喜,双方交换位置");}break;default:break;}}//默认没有结束return false;}
结束场景逻辑实现
static void BeginOrEndScene(int w, int h, ref E_SceneType nowSceneType)
{Console.ForegroundColor = ConsoleColor.White;Console.SetCursorPosition(nowSceneType == E_SceneType.Begin ? w / 2 - 3 : w / 2 - 4, 8);Console.Write(nowSceneType == E_SceneType.Begin ? "飞行棋" : "游戏结束");//当前选项的编号int nowSelIndex = 0;bool isQuitBengin = false;//开始场景逻辑处理函数while (true){Console.SetCursorPosition(nowSceneType == E_SceneType.Begin ? w / 2 - 4 : w / 2 - 5, 13);Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;Console.Write(nowSceneType == E_SceneType.Begin ? "开始游戏" : "回到主菜单");Console.SetCursorPosition(w / 2 - 4, 15);Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;Console.Write("退出游戏");//通过ReadKey可以得到一个输入的枚举类型switch (Console.ReadKey(true).Key){case ConsoleKey.W:--nowSelIndex;if (nowSelIndex < 0){nowSelIndex = 0;}break;case ConsoleKey.S:++nowSelIndex;if (nowSelIndex > 1){nowSelIndex = 1;}break;case ConsoleKey.J:if (nowSelIndex == 0){//进入游戏场景//1.改变当前场景的IDnowSceneType = nowSceneType == E_SceneType.Begin ? E_SceneType.Game : E_SceneType.Begin;//退出当前循环isQuitBengin = true;}else{//退出游戏Environment.Exit(0);}break;}//通过标识决定是否跳出开始场景的循环if (isQuitBengin){break;}}
}
相关文章:
简单游戏制作——飞行棋
控制台初始化 int w 50; int h 50; ConsoleInit(w, h); static void ConsoleInit(int w, int h) {//基础设置//光标的隐藏Console.CursorVisible false;//舞台的大小Console.SetWindowSize(w, h);Console.SetBufferSize(w, h); } 场景选择相关 #region 场景选择相关 //声…...
等保一体机
等保一体机是面向等保场景推出的合规型安全防护产品。基于“一个中心,三重防护”的设计理念,通过内置全面、多样的安全能力,为政府、医疗、教育、企业等中小型客户提供快速合规、按需赋能的一站式等保合规解决方案。 等保一体机要求管理网络和…...
什么是寄存器文件(Register File)?
寄存器文件(Register File)是计算机系统中用于存储处理器操作数的小型、快速的存储单元集。它在 CPU 内部,提供极高的访问速度,通常用于存储临时数据、操作数和指令执行过程中的中间结果。 寄存器文件的组成和特点 寄存器集&…...
6月15号作业
使用手动连接,将登录框中的取消按钮使用第二中连接方式,右击转到槽,在该槽函数中,调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admin"࿰…...
零基础入门学用Arduino 第三部分(三)
重要的内容写在前面: 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后,整体感觉是很好的,如果有条件的可以先学习一些相关课程,学起来会更加轻松,相关课程有数字电路…...
Trusty qemu + android环境搭建详细步骤
下载源码 mkdir trusty cd trusty repo init -u https://android.googlesource.com/trusty/manifest -b master repo sync -j32 编译 ./trusty/vendor/google/aosp/scripts/build.py generic-arm64 查看编译结果 ls build-root/build-generic-arm64/lk.bin 安装运行依赖 …...
杀戮尖塔游戏
Java 你正在玩策略卡牌杀戮尖塔游戏,轮到你出牌,手里N张攻击卡,每张都需要花金币coust[i]和获得伤害dmager[i]。 最多花3金币能造成的最大伤害是多少? class Solution{public int calc(int[] cost, int[] dmager, N){int[][] db …...
Kubernetes (K8s) 和 Spring Cloud 的区别
Kubernetes (K8s) 和 Spring Cloud 是两种常用的云原生技术,它们在微服务架构和云计算领域中扮演着重要的角色。尽管两者都有助于开发和部署微服务,但它们的功能和目标存在显著差异。本文将详细讨论 Kubernetes 和 Spring Cloud 的区别,从它们…...
定个小目标之刷LeetCode热题(21)
这是道技巧题,利用了 (num - 1)% n 计算下标的形式来将数组元素与数组索引产生映射关系,代码如下,可以看下注释 class Solution {public List<Integer> findDisappearedNumbers(int[] nums) {int n nums.lengt…...
Oracle 打开钱包 ORA-28368: cannot auto-create wallet
ORA-28368: cannot auto-create wallet 开启钱包抱错,看下钱包信息 SQL> select * from v$encryption_wallet;WRL_TYPE -------------------- WRL_PARAMETER -------------------------------------------------------------------------------- STATUS ------…...
【麒麟虚拟机】NetworkManager没有运行
麒麟V10 建linux麒麟虚拟机,发现,网络没有配置 提示,NetworkManager没有运行。编辑联接也不能配置 解决方法,在终端输入命令: sudo systemctl start NetworkManager 启动以后,编辑连接选自动以太网&…...
vue之一键部署的shell脚本和它的点.bat文件、海螺AI、ChatGPT
MENU 前言vite.config.ts的配置deploy文件夹的其他内容remote.shpwd.txtdeploy.bat 前言 1、在src同级新建deploy.bat文件; 2、在src同级新建deploy文件夹,文件夹中新建pwd.txt和remote.sh文件; 3、配置好后,直接双击deploy.bat文…...
pg和oracle的区别
1、从功能上来说pg要比oracle数据库弱。 2、pg不支持索引组织表。 pg和oracle的相似之处: 1、使用共享内存的进程结构,客户端与数据库服务器建立一个连接后,数据库服务器就启动一个进程为这个连接服务。这与mysql的线程模型不一样。 2、p…...
Docker:在DockerHub上创建私有仓库
文章目录 Busybox创建仓库推送镜像到仓库 本篇开始要学习在DockerHub上搭建一个自己的私有仓库 Busybox Busybox是一个集成了三百多个最常用Linux命令和工具的软件,BusyBox包含了很多工具,这里拉取该镜像推送到仓库中: 安装 apt install …...
框架的使用
什么是框架? 盖房子,框架结构 框架结构就是房子主体,基本功能 把很多基础功能已经实现(封装了) 框架:在基础语言之上,对各种基础功能进行封装,方便开发者,提高开发效…...
Autosar-DEM诊断事件管理流程
文章目录 前言一、故障事件监控二、故障信息上报三、故障信息处理Event的使能条件四、故障信息存储五、故障系统降级关联文章:Autosar实践——DEM配置 前言 DEM全称“Diagnostic Event Management”,该模块是AUTOSAR架构中的BSW模块之一。谈到故障,我们首先会想到如何去监控…...
LabVIEW输送机动态特性参数监测系统
开发了一套基于LabVIEW软件和STM32F103ZET6单片机的带式输送机动态特性参数监测系统。该系统通过电阻应变式压力传感器和光电编码器实时采集输送带的张力和带速信息,通过5G模块将数据传输至上位机,实现数据的可视化处理与实时预警,有效提高输…...
绿色版DirectoryOpus功能强大且高度可定制的Windows文件管理器
Directory Opus(通常简称为DOpus)是一款功能强大且高度可定制的Windows文件管理器。它提供了许多超越Windows默认文件资源管理器(Explorer)的功能,使得文件和文件夹的管理变得更加高效和直观。以下是对Directory Opus的…...
Cocos Creator,Youtube 小游戏!
YouTube 官方前段时间发布了一则重磅通知,宣布平台旗下小游戏功能 Youtube Playables 正式登录全平台(安卓、iOS、网页),并内置了数十款精选小游戏。 Youtube Playables 入口: https://www.youtube.com/playables Coco…...
分层解耦
三层架构 controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据, service:业务逻辑层,处理具体的业务逻辑。 dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
