使用C#和MonoGame开发俄罗斯方块游戏
小的时候就看到有同学使用C语言在DOS下做过一款俄罗斯方块的游戏,当时是启用了DOS的图形化模式,感觉也挺有意思。最近上海疫情封控在家,周末也稍微有点空余时间,于是使用Visual
Studio 2019,C# 9.0配合MonoGame 3.8,自己也写了一个俄罗斯方块的游戏,效果如下:

当然,光看效果图还是不够直观,最好是自己能够下载玩一下。下载地址在此:
与此同时,代码开源:https://github.com/daxnet/tetris-sharp
简介
有些内容大致介绍一下:
- 开发我没有使用Visual Studio 2022和.NET 6,而是使用的Visual Studio 2019配合.NET Core
3.1,这是因为MonoGame 3.8目前对VS 2019和.NET Core 3.1的支持最好,有现成的项目模板,以及Content
Pipeline的支持也不错。如果你希望自己编译源代码,最好选择Visual Studio 2019和.NET Core
3.1;后续MonoGame会完成.NET 6的支持 - 所有图形资源(除了图标),都是我自己用Paint.NET画的。Paint.NET工具挺好用
- 背景音乐是以前8位任天堂红白机(或者是小霸王游戏机)中《俄罗斯方块》二代里的背景音乐,从网络下载,仅供学习交流使用
- 基本按键:
- 方块左移:A
- 方块右移:D
- 方块下移:S
- 旋转方块:J
- 暂停:回车键
- 开/关背景音乐:F12
游戏设计和开发要点
介绍几个开发要点吧。
方块的定义和方块旋转
为了能够支持扩展,我使用了XML文件来定义各种方块,以及每种方块在不同的旋转角度下的形态。这个文件是blocks.xml,跟可执行文件在同一个目录下。它的结构如下:
<?xml version="1.0" encoding="utf-8" ?>
<tetris-blocks>
<blocks>
<block>
<name>方块名称</name>
<description>方块描述(可以不填)</description>
<rotations>
<rotation>
<definition>旋转形态1的描述</definition>
</rotation>
<rotation>
<definition>旋转形态2的描述</definition>
</rotation>
...
</rotations>
</block>
...
</blocks>
</tetris-blocks>
其中:
- 方块名称:给方块取个名字,随便什么名字都可以
- 方块描述:随便给个描述文字,可以不填
- 旋转形态的描述:用来表述当前这个旋转形态的样子,待会再介绍
玩过俄罗斯方块的都知道,一个方块可以有多个旋转形态,比如L方块,可以有4个形态:

对于第一个形态,我们可以用一个3*2的整型数组来表示:

于是,从上到下,从左到右,这个数组里的值就是:1、1、1、1、0、0;如果我们把每一行的数字连起来,然后行与行之间用空格隔开,那就是111
100,这也就是这个方块在当前这个“厂”字形态下的定义,所以rotation definition就是111 100。完整的L方块的定义如下:
<block>
<name>Reversed L</name>
<rotations>
<rotation>
<definition>001 111</definition>
</rotation>
<rotation>
<definition>11 01 01</definition>
</rotation>
<rotation>
<definition>111 100</definition>
</rotation>
<rotation>
<definition>10 10 11</definition>
</rotation>
</rotations>
</block>
现在我们往XML里加入一个新的方块:十字方块:

<block>
<name>Cross</name>
<rotations>
<rotation>
<definition>010 111 010</definition>
</rotation>
</rotations>
</block>
加入十字方块后,立刻会被加载到游戏中:

游戏棋盘与方块
游戏中有一块看不见的棋盘,它主要记录着目前游戏中有哪些地方已经堆积了方块,并对于完全塞满的行,游戏棋盘会负责清理(也就是消行)。根据棋盘的大小,可以将这个数据模型定义为一个整型的二维数组,有方块堆砌的格子,值为1,否则为0。
在方块下落的时候,会首先判断其所在行的下一行中,与之下边缘对应的方格中有没有值为1的格子,如果有的话,当前方块就需要被融合到棋盘中,然后发出下一个方块。如果没有,那么当前方块继续下落。
棋盘的融合其实很简单,方法是:扫描方块当前旋转形态的所有格子,如果值为1,就在棋盘的对应位置将数组值设置为1即可。后续由MonoGame的渲染机制负责渲染棋盘就可以了。
方块的移动
方块并不是随意在界面上移动的,当方块左右移动时,要看左右方是否已有棋盘中的堆砌块阻挡,或者是否已经到了界面的边缘,如果有,则要阻止其左右移动。判断方法跟上面所说的判断方块下移过程是否与棋盘接触的方法类似,就看左右两边的边缘是否会与棋盘或者边界接触,如果是,则禁止移动。
面向对象与框架的思想
整个游戏的实现代码中还包含了一个框架,位于TetrisSharp.Framework命名空间,它封装了一些简单游戏的常见组件,比如Sprite、Scene、Text、ProgressBar等,以及一些简单的诸如碰撞检测的算法和一个消息系统(比如当碰撞发生时,Sprite可以通知Scene做一些事情)。这些东西在编写小的休闲游戏的时候还是可以重用的。我们不推荐重复造轮子,像Unity、UR等这样成熟的游戏引擎其实已经有这些强大功能了,不过有兴趣有精力也可以考虑自己做个游戏引擎,毕竟MonoGame它也只是一个框架,不是游戏引擎。
总结
这个俄罗斯方块游戏的一些设计思路就简单介绍这些吧,千言万语都在源代码里,欢迎大家下载参考。
使用C#和MonoGame开发俄罗斯方块游戏的更多相关文章
- 吴裕雄--天生自然python学习笔记:python 用pygame模块开发俄罗斯方块游戏
俄罗斯方块游戏 多年前,游戏机中最流行的游戏就是“俄罗斯方块”了.时至今日,虽然网络 游戏日新月异 ,但“俄罗斯方块”这款小游戏仍在许多人心中 占有一席之地.本例中, 我们将亲手设计一个简单的俄罗斯方 ...
- 经典 HTML5 & Javascript 俄罗斯方块游戏
Blockrain.js 是一个使用 HTML5 & JavaScript 开发的经典俄罗斯方块游戏.只需要复制和粘贴一段代码就可以玩起来了.最重要的是,它是响应式的,无论你的显示屏多么宽都能 ...
- electron写俄罗斯方块游戏(Tetris)
背景 在折腾ES6,突然想起大学时用c语言写过俄罗斯方块,本项目中主要是利用ES6的Class特性进行面向对象编程.项目采用node.js v6.2.0 + electron v1.1.0 进行桌面开 ...
- 【补档STM32】STM32F103俄罗斯方块游戏实现
项目地址:https://gitee.com/daycen/stm32-tetris/tree/master 使用Keil uVision5打开即可 一.概述 本文介绍了一个基于STM32的俄罗斯 ...
- 第一个独立开发的游戏 怪斯特:零 已经上线APP STORE!
今天是个值得纪念的日子,而且是双喜临门 2年多来的摸爬滚打,终于有了回报 第一喜:自己独立开发的游戏 怪斯特:零 已经通过审核并上架APP STORE! 第二喜:迈入了自己期待2年之久的游戏行业,年后 ...
- JS开发HTML5游戏《神奇的六边形》(一)
近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...
- Atitit 开发2d游戏的技术选型attilax总结
Atitit 开发2d游戏的技术选型attilax总结 1.1. 跨平台跨平台:一定要使用跨平台的gui技术,目前最好的就是h5(canvas,webgl,dom) +js了..1 1.2. 游戏前后 ...
- 从零开始---控制台用c写俄罗斯方块游戏(1)
从零开始---控制台用c写俄罗斯方块游戏(1) 很少写博文,一来自身知识有限,二来自己知道,已经有很多这样的博文了,三就是因为懒,文笔也一般,四来刚出来工作,时间也不多 之所以写这篇博文,是因为应群里 ...
- JS开发HTML5游戏《神奇的六边形》(二)
近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...
随机推荐
- H5使用Canvas绘图
一.什么是Canvas Canvas 是H5的一部分,允许脚本语言动态渲染图像.Canvas 定义一个区域,可以由html属性定义该区域的宽高,javascript代码可以访问该区域,通过一整套完整的 ...
- Android 接入腾讯IM即时通信(详细图文)
原文地址:Android 接入腾讯IM即时通信(详细图文) | Stars-One的杂货小窝 腾讯云IM官网文档上提供了带UI模块和不带UI模块的,本文是基于带UI模块进行了Module封装,可以方便 ...
- Python入门-深入了解数据类型以及方法
写在开始:每一种数据类型,有对应一种功能,面对不同的问题,使用不同类型. 1.全部数据类型 1.2数值型:解决数字的计算问题 #基础的计算,求除结果,求商,求余数 print(10 / 3) prin ...
- spring data es操作es
https://www.freesion.com/article/59481222940/
- JVM诊断及工具笔记(4) 使用visualvm分析JVM堆内存泄漏
在这里感谢最近一直阅读我文章的小伙伴,如果觉得文章对你有用,可以帮忙关注转载,需要的时候可以及时找到文章. 背景 今年Q3季度我们在推广业务方使用Iceberg,当时为了让不同业务线的用户可以使用自己 ...
- Solon 1.6.36 发布,更现代感的应用开发框架
相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...
- TypeScript学习_入门向
TypeScript学习_入门向 1-TypeScript简介 首先官网祭天 ---> https://www.tslang.cn/ TypeScript 是 JavaScript 的一个超集, ...
- android软件简约记账app开发day01-今日收支明细的界面绘制
android软件简约记账app开发day01-今日收支明细的界面绘制 导入素材 导入在阿里iconfront图标库下载的字体图标分为大小两种,分别导入到项目目录mipmap-hdpi和mipmap- ...
- netty系列之:netty中的核心MessageToMessage编码器
目录 简介 框架简介 MessageToMessageEncoder MessageToMessageDecoder MessageToMessageCodec 总结 简介 在netty中我们需要传递 ...
- java序列回显学习
java反序列化回显 在很多不出网的情况下,一种是写webshell(内存嘛),另一种就是回显,本文先学习回显,回显的主要方式有一下几种. defineClass RMI绑定实例 URLClassLo ...