两年前,我使用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. vue3实现模拟地图上,站点名称按需显示的功能

    很久很久没有更新博客了,因为实在是太忙了,每天都有公司的事情忙不完....... 最近在做车辆模拟地图,在实现控制站点名称按需显示时,折腾了好一段时间,特此记录一下.最终界面如下图所示: 站点显示需求 ...

  2. 记录.Net部署Docker-v指令使用

    记录Docker的-v指令使用 前言 之前我浅学了一下docker,方便部署.net项目(部署的是打包之后的项目) dockerfile文件如下: FROM mcr.microsoft.com/dot ...

  3. ZYNQ:使用 PetaLinux 构建Linux项目

    参考文档:ug1144-petalinux-tools-reference-guide.pdf 环境安装 tofrodos iproute2 gawk gcc g++ git make net-too ...

  4. OpenStack 下 CentOS6.X 镜像网络初始化失败问题排查

    问题表现 在我的 OpenStack 集群上迁移了一批老旧的镜像(从其他三方云平台过来的)发现这批镜像在使用 ConfigDrive 的方式注入配置初始化时无法对非首张网卡镜像初始化(后经过测试非 C ...

  5. SpringBoot可视化接口开发工具magic-api

    magic-api简介 magic-api是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成,自动映射为HTTP接口,无需定义Controller.Service ...

  6. Maven pom.xml文件

    pom.xml 版本依赖 <!--编译器依赖--> <properties> <project.build.sourceEncoding>UTF-8</pro ...

  7. C#事件总结(二)

    续接上一篇文<C#事件总结>,那是通过一个结合例子的文字描述,接下来我将通过图文形式展现. 现在VS开发环境中看看事件是什么样子的: 再来看看我的笔记,希望对你的理解有帮助. 哦,顺便提醒 ...

  8. 解决方案 | MiKTex SSL connect error code 35

    可能是:你的网络屏蔽了需要连接的网站,更换手机流量热点即可解决

  9. [oeasy]python0125_汉字打印机_点阵式打字机_汉字字形码

    汉字字形码 回忆上次内容 IBM 将 ASCII 扩展之后 规定了 一个字节的字符集 并制作了 相应的字形库   ​   添加图片注释,不超过 140 字(可选)   这种显示模式和字符大小之下 中文 ...

  10. oeasy教您玩转vim - 1 - # 存活下来 🥊

    存活下来 更新 apt 源,升级 vim vim 是什么 vim 是类 unix 系统上的一个文本编辑神器,在 Linux 系统环境中也被许多程序员使用,书写程序和文档. 我们本次课程将围绕 Vim ...