两年前,我使用C#基于MonoGame编写了一款《俄罗斯方块》游戏,相关介绍可以参考【这篇文章】。最近,使用业余时间将之前的基于MonoGame的游戏开发框架重构了一下,于是,也就趁此机会将之前的《俄罗斯方块》游戏也重制一次,加入了许多我一直打算加入的功能,甚至包括提供跨平台的版本。

先说说这个游戏开发框架,我给它取名为Mfx(MonoGame Fx,Fx是Framework的缩写,但又不想跟MonoGame Framework重名),仓储地址是:https://github.com/daxnet/mfx。这个重构过的框架在整体结构设计上比其前任版本Ovow(https://github.com/daxnet/ovow)更为合理,去掉了一些不必要的功能,也加入了一些新的功能。业余时间有限,所以也没打算将它真正开发成一个完整的游戏引擎,就是能够支持我自己写的一些小游戏就可以了,所以,也不打算对它做过多介绍。

回到重制版《俄罗斯方块》游戏,先开源:【https://github.com/daxnet/tetris-sharp-revised】,在这个页面的Releases列表里,可以直接点击最新的发布版本,然后选择对应的操作系统的ZIP包进行下载把玩,目前该游戏编译输出Windows、Linux和MacOS三个版本(Linux我在Ubuntu 24.04 LTS Desktop下测试可用,MacOS没有试过)。当然,如果不想玩游戏,可以直接看视频:

与旧版本相比,新版文件尺寸更小,打包后尺寸为62MB,相比之前的107MB,减小了45MB,其实新版本自带的背景音乐更加丰富,资源大小也变得更大,但总尺寸是下降了,也是因为.NET从6升级到8后,本身也做了不少的优化。对于这样一个简单的游戏为何会有这么大尺寸?主要有两个方面的原因:各种资源需要占用一部分空间,另外就是在打包编译后的程序时使用了--self-contained开关,也就意味着将整个.NET 8都打包在了一起,玩家不需要安装任何.NET相关的运行库。那反过来想想,如果使用相同的这套技术开发了一个大型游戏,虽然资源会占更多的空间,但是即便是几百MB甚至上GB,或许你也不会在意它的尺寸了。

下载并解压之后,双击TetrisSharp.exe(Linux下先chmod +x ./TetrisSharp,然后直接运行)即可开始游戏,点击【NEW GAME】菜单就能进入主界面开始游戏,【CONTINUE】菜单目前是不可用的,在游戏过程中,按下键盘上的ESC键,即可返回标题界面,此时CONTINUE菜单才可用,点击即可继续游戏。【LOAD】菜单也是不可用的,但在游戏的过程中任意时刻退出游戏,游戏状态会被保存下来,下一次重新运行游戏时,LOAD菜单就会变成可用状态,点击即可载入上次保存的游戏状态。点击【INPUT SETTINGS】菜单可以进入按键设置界面:

红色字体提示当前正在设置的按键,此时只需要在键盘或者游戏手柄上按下对应的键,红色选中项就会跳到下一个项目。如果中途有任何按键设置错误,可以点击【RESET】按钮,从头开始重新设置按键。设置完毕后,点击【SAVE】按钮保存,或者点击【CANCEL】按钮取消设置。对于游戏手柄,目前好像并不是所有手柄都支持(我自己使用的是8BitDo M30),建议可以连上试试,切换一下手柄的模式(估计需要XBOX模式),如果不行,还是先用键盘体验吧。

如上图所示,第一次运行游戏,默认使用键盘作为输入,按键定义如下:

  • 方块下移:S
  • 方块左移:A
  • 方块右移:D
  • 方块旋转:J
  • 方块下落到底:K
  • 暂停游戏:空格键
  • (隐藏:回到开始界面:ESC)

跟老版本相比,新版本在界面上进行了优化(如下上图为老版本,下图为新版本):

主要改进地方有:

  1. 棋盘变得更大:由原来的12x24改为了15x28
  2. 方块材质进行了调整
  3. 方块下落时会在棋盘上留下投影,方便定位
  4. 为方块快速下落新增独立按键,按下后直接将方块下落到最底端
  5. 界面配色和字体做了调整
  6. 显示已经使用过的方块数量
  7. 统计最高分,当分数突破最高分后会更新最高分

此外,在游戏操控方面也做了一些优化,按键控制更加灵活。由于修正了旧版本中的背景音乐加载问题,新版内存占用率大幅下降,为原来的50%左右,从400多MB降为了200多MB。总而言之,新版本更接近一个完整的游戏。

与老版本相同,新版也提供了自定义方块的功能,只不过新版使用了更为简洁的文本文件,而非之前的XML文件。在游戏目录下,找到blocks.txt文件,双击打开即可编辑。文件格式如下:

  • #开头行为注释行
  • 每个方块的定义都是以block "<名称>"指令开头,end block指令结束,中间包含1到多行方块变体(也就是旋转形态Rotation)的定义
  • 每个方块变体占用一行,比如L形方块,它有四个旋转形态:、、、厂,那么就有四行0和1的数字来定义它的形态
  • 对于每个旋转形态,使用数字0和1来定义它的形状,可以有多行,每行之间用空格隔开

比如,如果我们希望把下面这个方块加入到游戏中:

如果将它旋转起来,就会有以下四种旋转形态,如果在每种旋转形态中,需要显示材质的方格用1表示,而不需要显示的方格用0表示,就得到:

因此,对于这个方块,就可以用下面的文本进行定义:

block "custom"
111 101
11 10 11
101 111
11 01 11
end block

将这个定义加到blocks.txt文件中后,重新启动游戏,就会出现这个自定义的方块,比如:

程序设计方面,因为使用的C#,所以遵循面向对象基本原则无疑,在Mfx框架和游戏本身中,也应用了一些设计模式(比如Builder、Adapter、Mediator等)以使得游戏的整体结构更为优雅,有时间我可以在另外的博文中介绍。对于源代码的使用,如果希望自己调试,首先确保.NET 8 SDK已经安装,然后用Visual Studio 2022打开src目录下的TetrisSharp.sln,将TetrisSharp项目设置为启动项目,直接F5即可调试。如果希望直接编译源码,则可在src目录下,使用下面的命令生成编译,生成的结果会输出到bin\Release\net8.0目录下:

REM 生成Windows编译
dotnet publish -c Release --sc -r win-x64 REM 生成Linux Desktop编译
dotnet publish -c Release --sc -r linux-x64 REM 生成MacOS编译
dotnet publish -c Release --sc -r osx-x64

OK,今天先介绍这么多,有兴趣的读者欢迎试玩吐槽。

基于MonoGame重制《俄罗斯方块》游戏的更多相关文章

  1. 使用C#和MonoGame开发俄罗斯方块游戏

    小的时候就看到有同学使用C语言在DOS下做过一款俄罗斯方块的游戏,当时是启用了DOS的图形化模式,感觉也挺有意思.最近上海疫情封控在家,周末也稍微有点空余时间,于是使用Visual Studio 20 ...

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

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

  3. [Unity3D]自己动手重制坦克舰队ArmadaTank(2)从碰撞说起

    [Unity3D]自己动手重制坦克舰队ArmadaTank(2)从碰撞说起 在上一篇里我给出了重制的坦克舰队效果图和试玩程序.本篇介绍一下玩家坦克和敌方坦克碰撞问题. +BIT祝威+悄悄在此留下版了个 ...

  4. [Unity3D]自己动手重制坦克舰队ArmadaTank

    [Unity3D]自己动手重制坦克舰队ArmadaTank 我玩过一款坦克游戏ArmadaTank(坦克舰队),如下图所示 几个月前我尝试用Unity3D重制这款游戏,已经可以玩起来了.下面是在PC上 ...

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

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

  6. 教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏

    早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要是以注释的形式). 我用C写一个功能基本齐全的俄罗斯方块的话,大 ...

  7. 俄罗斯方块游戏JavaScript代码

    JavaScript代码俄罗斯方块游戏 早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要是以注释的形式). 我用 ...

  8. 使用JS实现俄罗斯方块游戏

    简单的JS俄罗斯方块游戏源码 效果图: 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <meta charset=&q ...

  9. 使用AndEngine重制《是男人就上一百层》

    1.为什么还要做<是男人就上一百层> 一是在用Android原生API开发完<是男人就上一百层>以后,一直想体验一下用引擎开发游戏是个什么感觉,顺便也让游戏听上去高大上一些(使 ...

  10. 基于Pierre Dellacherie的俄罗斯方块-05Pierre Dellacherie算法

    基于Pierre Dellacherie的俄罗斯方块-05Pierre Dellacherie算法 Pierre Dellacherie算法感觉上像是一个遍历算法,给与各个参数不同的权重,使得更加合理 ...

随机推荐

  1. 卷积神经网络中nn.Conv2d()和nn.MaxPool2d()以及卷积神经网络实现minist数据集分类

    卷积神经网络中nn.Conv2d()和nn.MaxPool2d() 卷积神经网络之Pythorch实现: nn.Conv2d()就是PyTorch中的卷积模块 参数列表 参数 作用 in_channe ...

  2. NXP i.MX 8M Plus工业开发板硬件说明书( 四核ARM Cortex-A53 + 单核ARM Cortex-M7,主频1.6GHz)

    前  言 本文主要介绍创龙科技TLIMX8MP-EVM评估板硬件接口资源以及设计注意事项等内容. 创龙科技TLIMX8MP-EVM是一款基于NXP i.MX 8M Plus的四核ARM Cortex- ...

  3. dig 命令详解及使用示例

    一.背景知识 CNAME CNAME 是 Canonical Name 的缩写,它是 DNS(域名系统)记录的一种类型.CNAME 记录用于将一个域名映射(别名)到另一个域名.换句话说,当你访问一个设 ...

  4. Java中final用法与详解

    final作为Java中经常用到的关键字,了解final的使用方法是非常有必要的. 这里从final关键字在数据域.方法和类中三个方面分析final关键字的主要用法. final应用于基本数据类型 1 ...

  5. AJAX基础+Axios快速入门+JSON使用+综合案例

    目录 1. AJAX 1.1 概述 1.1.1 作用 1.1.2 同步和异步 1.2 快速入门 1.2.1 服务端实现 1.2.2 客户端实现 1.3 案例 1.3.1 需求 1.3.2 分析 1.3 ...

  6. Mac 版本10.15.4 安装 telnel工具

    下载脚本 mac新版本安装telnel发生的变化,进入下面的链接,右键另存为,保存到桌面 https://raw.githubusercontent.com/Homebrew/install/mast ...

  7. Mac Eclipse 常用快捷键汇总

    寻找类:shift+command+t 删除当前行:command+d 上移当前行代码:option+↑ 下移当前行代码:option+↓ 复制当前行至下一行:option+command+↓ 复制当 ...

  8. Aug. 2024 杭二训练游记

    \(\text{前言}\) 我在 \(\text{Aug. 6th}\) 到 \(\text{Aug. 25th}\) 在杭州某知名中学集训,但是我亲爱的母亲却在一开始告诉我是 \(\text{Aug ...

  9. Rust 中 *、&、mut、&mut、ref、ref mut 的用法和区别

    Rust 中 *.&.mut.&mut.ref.ref mut 的用法和区别 在 Rust 中,*.ref.mut.& 和 ref mut 是用于处理引用.解引用和可变性的关键 ...

  10. scratch少儿编程卡通三国背景72张全套素材包【免费下载】

    scratch卡通三国题材背景图片,共72张,让你轻松打造scratch三国世界! 免费下载地址:https://www.xiaohujing.com.cn 这套背景图片以卡通风格呈现,色彩鲜艳.造型 ...