使用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)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...
随机推荐
- Java/C++实现代理模式---婚介所
婚介所其实就是找对象的一个代理,请仿照我们的课堂例子"论坛权限控制代理"完成这个实际问题,其中如果年纪小于18周岁,婚介所会提示"对不起,不能早恋!",并终止业 ...
- 关于根据数据反选checkbox
前两天完成了一个连接hbase数据库的mis系统,mis系统中经常需要修改功能,复选框.多选框等等的自动勾选,感觉很麻烦,在此记录一下修改功能checkbox自动选中. 例子: <div cla ...
- 【Android开发】简单好用的阴影库 ShadowLayout
先来看一张使用 ShadowLayout 库实现的各种阴影的效果图,如下图所示: 如上图所示,通过使用 ShadowLayout 可以控制阴影的颜色.范围.显示边界(上下左右四个边界).x 轴和 y ...
- 整合SSM框架环境搭建
知识要求 MySQL相关操作 Maven操作 Mybatis.Spring.SpringMVC三个框架基本操作 JavaWeb等知识 搭建环境 MySQL 8.0 Mybatis 3.5.2 使用c3 ...
- 演示默认学习用户scott,默认密码是tiger
默认学习用户scott,默认密码是tiger oracle@prd:/home/oracle$sqlplus /nolog SQL> conn scott/tiger ERROR: ORA-28 ...
- mysql发展历程 各分支版本溯源
首先为什么要了解mysql的历史,了解一个软件的前生后世有时候还是很有必要,特别是对于走在架构之路或者是想深入了解一个软件的时候,在不同版本中由于进行了很多的改进或者说加入了新的功能,也有可能是软件本 ...
- [翻译] Cassandra 分布式结构化存储系统
Cassandra 分布式结构化存储系统 摘要 Cassandra 是一个分布式存储系统,用于管理分布在许多商品服务器上的大量结构化数据,同时提供无单点故障(no single point of fa ...
- Java语言学习day38--8月13日
###11哈希表的数据结构 A:哈希表的数据结构:(参见图解) 加载因子:表中填入的记录数/哈希表的长度 例如: 加载因子是0.75 代表: 数组中的16个位置,其中存入16*0.75=12个元素 如 ...
- 如何设置notepad++为默认文本编辑器
第一步:选择.txt文件: 第二步:右键单击选择属性: 第三步:打开方式选择notepad++: 然后以后的文件都是用notepad++编写的了:
- ValidForm5.3.2 忽略表单项校验详解
ValidForm 官方文档 项目的需求是这样的:一个checkbox,一个input,选中checkbox的时候,需要校验input,取消选中的时候,不要校验input. <input typ ...