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

当然,光看效果图还是不够直观,最好是自己能够下载玩一下。下载地址在此:

【点击此处下载游戏】

与此同时,代码开源:https://github.com/daxnet/tetris-sharp

简介

有些内容大致介绍一下:

  1. 开发我没有使用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的支持
  2. 所有图形资源(除了图标),都是我自己用Paint.NET画的。Paint.NET工具挺好用
  3. 背景音乐是以前8位任天堂红白机(或者是小霸王游戏机)中《俄罗斯方块》二代里的背景音乐,从网络下载,仅供学习交流使用
  4. 基本按键:
    1. 方块左移:A
    2. 方块右移:D
    3. 方块下移:S
    4. 旋转方块:J
    5. 暂停:回车键
    6. 开/关背景音乐: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开发俄罗斯方块游戏的更多相关文章

  1. 吴裕雄--天生自然python学习笔记:python 用pygame模块开发俄罗斯方块游戏

    俄罗斯方块游戏 多年前,游戏机中最流行的游戏就是“俄罗斯方块”了.时至今日,虽然网络 游戏日新月异 ,但“俄罗斯方块”这款小游戏仍在许多人心中 占有一席之地.本例中, 我们将亲手设计一个简单的俄罗斯方 ...

  2. 经典 HTML5 & Javascript 俄罗斯方块游戏

    Blockrain.js 是一个使用 HTML5 & JavaScript 开发的经典俄罗斯方块游戏.只需要复制和粘贴一段代码就可以玩起来了.最重要的是,它是响应式的,无论你的显示屏多么宽都能 ...

  3. electron写俄罗斯方块游戏(Tetris)

    背景 在折腾ES6,突然想起大学时用c语言写过俄罗斯方块,本项目中主要是利用ES6的Class特性进行面向对象编程.项目采用node.js v6.2.0 + electron v1.1.0 进行桌面开 ...

  4. 【补档STM32】STM32F103俄罗斯方块游戏实现

    项目地址:https://gitee.com/daycen/stm32-tetris/tree/master 使用Keil uVision5打开即可 一.概述 ​ 本文介绍了一个基于STM32的俄罗斯 ...

  5. 第一个独立开发的游戏 怪斯特:零 已经上线APP STORE!

    今天是个值得纪念的日子,而且是双喜临门 2年多来的摸爬滚打,终于有了回报 第一喜:自己独立开发的游戏 怪斯特:零 已经通过审核并上架APP STORE! 第二喜:迈入了自己期待2年之久的游戏行业,年后 ...

  6. JS开发HTML5游戏《神奇的六边形》(一)

    近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...

  7. Atitit 开发2d游戏的技术选型attilax总结

    Atitit 开发2d游戏的技术选型attilax总结 1.1. 跨平台跨平台:一定要使用跨平台的gui技术,目前最好的就是h5(canvas,webgl,dom) +js了..1 1.2. 游戏前后 ...

  8. 从零开始---控制台用c写俄罗斯方块游戏(1)

    从零开始---控制台用c写俄罗斯方块游戏(1) 很少写博文,一来自身知识有限,二来自己知道,已经有很多这样的博文了,三就是因为懒,文笔也一般,四来刚出来工作,时间也不多 之所以写这篇博文,是因为应群里 ...

  9. JS开发HTML5游戏《神奇的六边形》(二)

    近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...

随机推荐

  1. HTML5存储方式

    由于之前在参加面试或者笔试的过程中经常会被问到HTML5存储的内容,包括它们之间的区别.特征和应用范围,所以看到一篇介绍不错的文章,把里面的个人觉得适合我的内容按照自己的理解总结如下.方便以后忘记了进 ...

  2. javaweb图书管理系统之账号密码验证登录

    验证账号与密码是否正确功能 一.注册功能 首先,在验证账号与密码是否正确的前提下的,需要先注册一个账号,如果没有账号,就会进不去,也无法验证. 其实,注册功能就是一个添加的功能,仿照我的第一篇文章,往 ...

  3. 自定义API(Jar包)的创建与使用(简单实现案例)

    @ 目录 学习内容 1. 自定义工具类 2. 导出jar 3. 加载Jar包 4. 调用自定义的API方法 总结 学习内容 1. 自定义工具类 新建一个java项目,然后创建包和工具类StringUt ...

  4. kubectl scale 一次缩容调整过程

    查看master环境相关信息一.版本信息 [root@master-web-38 ~]# kubectl versionClient Version: version.Info{Major:" ...

  5. 搭建springboot集成mybatis

    1.new project创建新项目选择spring initializr: 2.选择依赖需要选择web.mybatis.mysql就够了,后续需要其他的直接pom引入依赖就好了: 3.自己在java ...

  6. 《手写Mybatis》第4章:Mapper XML的解析和注册使用

    作者:小傅哥 系列:https://bugstack.cn/md/spring/develop-mybatis/2022-03-20-%E7%AC%AC1%E7%AB%A0%EF%BC%9A%E5%B ...

  7. 将个人项目发布到mavan中央仓库

    第一步,准备自己的git代码 比如在gitee或者github上的代码,我的是gitee码云上的,开源了一个处理业务日志采集的组件,支持注解方式,支持SpEL表达式,支持变量自定义. 话不多说,直接上 ...

  8. JVM内存管理面试常见问题全解

    目录 一.什么是JVM 1.jvm的三个组成部分 二.类加载系统 1.类的加载过程 2.类加载器 三.双亲委派机制 1.双亲委派机制介绍 2.为什么要双亲委派机制 3.双亲委派机制的核心源码 4.全盘 ...

  9. Restful API和传统的API的区别

    一.功能区别 Restful API是当作资源的唯一标识符,而传统是实现某某功能 如:/api/getList/1 and /api/getList?page=1 二.methods多样性 Restf ...

  10. Dependabot 开始支持 pub package 版本检测

    今年年初,我们发布了 Flutter 2022 产品路线图,其中「基础设施建设」这部分提到:2022 年 Flutter 团队将增加对供应链的安全的投入,目的是达到符合基础设施 SLSA 4 级别中描 ...