使用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)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...
随机推荐
- 基于canvas和web audio实现低配版MikuTap
导言 最近发掘了一个特别happy的网页小游戏--MikuTap.打开之后沉迷了一下午,导致开发工作没做完差点就要删库跑路了,还好boss瞥了我一眼就没下文了.于是第二天我就继续沉迷,随着一阵抽搐,这 ...
- Python使用函数模拟“汉诺塔”过程
运行效果: 源代码: 1 # -*- coding:utf-8 -*- 2 ##汉诺塔游戏开始 3 _times=0 #用于统计移动次数 4 def hannuota(nlist,mfrom,mpas ...
- 浅谈一下流式处理平台Flink
浅谈一下流式处理平台(Flink) 大数据框架听过很多,比如 Hadoop,HDFS...不过自己的项目都没有上过 为什么突然提到 Flink,因为最近一个项目需要用到,所以学习最好的方式就是项目驱动 ...
- 微信小程序组件封装及调用-原生
封装一个弹窗组件 1.新建component文件夹存放我们的组件,里边存放的就是我们所用的组件,我们今天要做的事弹出框,新建文件夹popup存放我们的组件模板,点击右键选择新建component,就会 ...
- Centos7 使用pm2快速安装创建定时任务
Centos7 安装 pm2 一丶拿到一个动态拨号的服务器还不用使用网络得先打开: pppoe-start 如果没有wget,需要先下载安装: yum install wget 二丶环境搭建 wget ...
- ArcGIS使用技巧(五)——批量裁剪
新手,若有错误还请指正! 最近用到了,所以记下来,用同一矢量范围裁剪多幅栅格数据.用到了ArcGIS中的迭代模型(图1): 图 1 首先,需要做一个准备工作,就是把需要裁剪的栅格数据放在同一数据库中( ...
- QGIS 插件开发Debug教程——使用Pycharm
参考文章:Remote Debugging Guide for Python PyQGIS CookBook 16.4. IDE settings for writing and debugging ...
- 3.2 常用Linux命令
1.ifconfig命令 ifconfig命令用于获取网卡配置与网络状态等信息,英文全称为"interface config",语法格式为"ifconfig [参数] [ ...
- jmeter元件,作用域与优先级
jmeter元件,作用域与优先级 一.jmeter元件 1.配置元件:优先级最高 1.1 重点使用元件:csv数据文件设置.用户定义变量.计数器 2.取样器:根据不同协议来编写请求脚本的元件 2.1 ...
- Solon 1.7 重要发布,更现代感的应用开发框架
相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...