使用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)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...
随机推荐
- python-for循环跳过第一行
代码: for i in data[1:]: 即可跳过第一行
- CSS简单样式练习(四)
运行效果: 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta char ...
- vue项目处理dpr和多屏幕适配问题
<!DOCTYPE html> <html style="font-size:37.5px"> <head> <meta charset= ...
- 关于javaweb学习终点的一些感悟
学习完javaweb后,自己做了一套管理项目,使用了mybatis,themeleaf和servlet.大致明白了servlet的真实应用场景. 说白了servlet就是用来指定浏览器url后面输入了 ...
- Linux操作系统与项目部署
Linux操作系统与项目部署 注意:本版块会涉及到操作系统相关知识. 现在,几乎所有智能设备都有一个自己的操作系统,比如我们的家用个人电脑,基本都是预装Windows操作系统,我们的手机也有Andro ...
- 解决一次calico异常情况,pod之间访问pod ip不通
k8s 集群采用二进制安装,cni网络插件用calico通讯问题描述:发现有些pod不是很正常例如: ht13.node正常系统采样 [root@ht6 ~]# cat /etc/redhat-rel ...
- HCIE笔记-第七节-ICMP+ARP
ICMP重定向 作用:解决网络中的次优路径 触发:当某一个设备收到一个数据,进行转发时发现还要从该接口进行转发,于是触发ICMP重定向. 报文:Type=5,Code=0 ARP -- 地址解析协议 ...
- Java语言学习day03--6月30日
今日内容介绍 1.变量 2.运算符 ###01变量概述 * A: 什么是变量? * a: 变量是一个内存中的小盒子(小容器),容器是什么?生活中也有很多容器,例如水杯是容器,用 ...
- Synchronized锁及其膨胀
一.序言 在并发编程中,synchronized锁因其使用简单,在线程间同步被广泛应用.下面对其原理及锁升级过程进行探究. 二.如何使用 1.修饰实例方法 当实例方法被synchronized修饰时, ...
- VS Code 真的会一统江湖吗?
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 作者 | ROBEN KLEENE / 策划 | 万佳原文链接:https://blog.ro ...