我是如何在记事本上玩游戏的

2020-05-28 19:23:45

这一切都始于2017年的一个简单问题:“如果记事本里有游戏怎么办?”

我对这个愚蠢的想法暗自发笑。至少我是这么想的。毕竟已经过去3年了。在思考了这个游戏的工作原理后,我意识到这是完全可能的,并挑战自己去做这个游戏。

在正常的游戏中,你只需按下一个按钮,游戏就会根据它进行操作。按下A会让马里奥跳起来。这是一个接收和回应的问题。游戏接收输入并以输出响应。对于记事本游戏,接收到的信息将是玩家对文件进行了更改,而响应将是更改文件。因此玩家选择一个选项,游戏将显示该选择的结果。为此,游戏会跟踪上次保存文件的时间。如果时间已更改,游戏将读取文件内容,然后可以将新数据写入文件。不过,有一个小问题。Microsoft的记事本不检查文件是否已更新。播放机必须保存该文件,将其关闭,然后重新打开。用这个做游戏还是有可能的,只是不会很好玩。我不得不找一种替代记事本的方法。

我可以理解如果你现在失望了,读到完成的游戏实际上不在微软的记事本上。不过,让我澄清一下,完成的游戏可以在MS记事本上玩。只是太不方便了。我选择了让这个项目变得不那么酷的路线,以换取一个实际上玩起来很有趣的游戏。

所以我需要为我的游戏找到一个替代的文本编辑器。唯一的要求是能够自动刷新文件,不过稍后您会发现另一个功能正在发挥作用。我首先想到的是诸如Notepad++和Sublime Text这样的代码编辑器。但除了它们看起来不像MS记事本,这会夺走它的全部魅力之外,它还会询问播放器是否想刷新文件。虽然这比要求你关闭并重新打开文件前进了一步,但这对游戏来说是破坏性的。我需要它来自动更新文件。就在那时,我发现了一款名为Notepad2的软件,它几乎是完美的。Notepad2可以配置为看起来非常像MS记事本,它会检查文件更改。但是,就像Notepad++和Sublime Text一样,它会询问玩家是否要刷新文件。幸运的是,Notepad2是开源的,所以我能够使它变得完美。

Notepad2是用C语言编写的,这是一种我已经尝试过几次的语言,但我远不是专家。这没什么大不了的,因为大多数编程语言都非常相似。一个有经验的Javascript程序员应该可以毫不费力地阅读和理解C代码的一般思想。真正的挑战是理解Notepad2的源代码,并能够找到并编辑我想要的更改。一个好的开始是对话框中的文本“当前文件已被外部程序修改。重新装弹?“。将其设置为变量,并将该变量用作对话函数的参数。所以我找到了它。

IF((iFileWatchingMode==2&;&;!b修改后的&;&;iEncoding==iOriginalEncoding)||bMsgBox(MBYESNO,IDS_FILECHANGENOTIFY)==IDYES){。

这段代码检查文件的内容是否仍然相同,如果不是,它将打开对话框,并检查用户是否单击了Yes。我所要做的就是将MsgBox(MBYESNO,IDS_FILECHANGENOTIFY)==IDYES替换为true,现在它会自动重新加载文件。解锁此功能后,我基本上创建了一个基于ASCII的渲染器。下一项工作是围绕这一点创建一个引擎。

这个游戏是用洛维制作的。Lua中2D游戏的开源框架,我已经使用了很多年,并写了一篇关于它的教程。在这个游戏中,我主要使用LöVE的文件系统模块,它提供了我需要的一切。通常,使用LÖVE这样的框架,您会创建一个图像对象,然后在屏幕上绘制该图像对象。我希望能够做同样的事情,除了我的文本文件和ASCII艺术。我从一座房子和一只鸟开始,目标是让鸟飞过档案。我使用了我在https://asciiart.website/上找到的图片,但请注意,游戏中的图片都是原创的(字体除外)。

房子将被用作背景,所以我从把房子写到“屏幕”开始。在本例中,屏幕将是home.txt。

在本例中,x将是列,y将是行号。我从把屏幕和鸟分成几行开始。

--获取当前画布屏幕=love.filesystem.read(";home.txt";)​--创建表。表就像一个数组。SCREEN_LINES={}​--Lua模式(.-)\n表示捕获\n(换行符)之前的所有内容。--我们在文件末尾添加一个\n,以便它也捕获最后一行。对于线路输入(屏幕..。";\n";):gMatch(";(.-)\n";)执行表格。插入(SCREEN_LINES,LINE)END。

我也是为这只鸟这么做的。现在我需要把鸟儿的线条贴在房子的线条上。把它分成几个步骤。

得到这条线的第二部分,从x+鸟画的长度到这条线的末尾。

用第一部分、鸟的线和第二部分创建一条新线。

函数DraArt(ART,x,y)ART_LINES=getLines(Art)​--在Lua中,您可以使用#for i=1,#SCREEN_LINES do if i==y,则对于j=1,#ART_LINES DO--WITH STRING:SUB(START,END)我们可以获取字符串的一部分LOCAL FIRST_PART=SCREEN_LINES[i]:SUB(1,x-1)本地第二部分=屏幕行[i]:SUB(x+#个艺术行[j],#SCREEN_LINES[i])SCREEN_LINES[i]=FIRST_PART..。艺术线条[i]..。第二部分结束端

你可能注意到这只鸟有这个长方形。这是因为它还复制了空格。为了解决这个问题,我计算了行首的空格数量,并将其添加到位置,以便只绘制艺术。

--(%s)获取所有空格字符。局部空格=art_lines[j]:匹配(";(%s*)";)--删除该行中的空格。art_lines[i]=art_lines[i]:sub(#space+1,#art_lines[i])local first_part=screen_lines[i]:sub(1,x+#space-1)local Second_part=screen_lines[i]:sub(x+#space+#art_lines[j],#screen_lines[i])screen_lines[i]=first_part。艺术线条[i]..。第二部分。

每帧都有这个{{F}}标签。然后,在读取文件内容时,我根据该标签对其进行拆分,以获得每一帧。在那之后,它会像您通常做的那样进行动画制作。创建一个计时器,并根据该计时器绘制一个帧。

我还实现了打字机文本,并创建了单独的组件,如屏幕、库存和选项框,我可以将它们粘合在一起。还是有一个问题。游戏如何知道文件是否已打开?这是我之前谈到的另一个功能。在Notepad2的源代码中,我制作了它,以便在您打开文件后立即保存它。然后,它再次检查文件的上次保存时间是否已更改,如果是,游戏知道该文件已被打开并可以对其执行操作。

//在FileLoad函数的末尾。//如果该文件不是新文件,并且没有重新加载,则保存该文件。如果(!b新建&;&;!b重新加载){*FileSave(true,false,false,false);}。

最终,我有了一个很好的框架可以使用,我可以开始创建一个围绕它的游戏。经过9天的开发(按照gif文件的创建日期),我得到了以下内容:

如果你玩过这个游戏,你就会知道打字机效果和动画都消失了。这有多种原因。

我一直在想,所有这些写入操作是否会毁了我的硬盘/固态硬盘,所以用这些功能测试游戏,然后听到我的电脑发出声音,让我变得非常偏执。我不想让其他球员也有这种恐惧。

在动画过程中,你实际上什么都做不了。如果您尝试选择一个选项,您将在框中键入一个角色,但在您能够保存游戏之前,下一帧已加载,并将您的角色从框中移除。因此,动画一开始可能很酷,但后来,它们可能会变得令人讨厌。

动画很酷,但不太像Notepadish。文本文件不应该是动画的。出于同样的原因,游戏中没有音乐。是的,我可以这样做,这样游戏就可以创建一个音频文件,你可以在媒体播放器中打开,但它会把焦点从记事本上移开。我留下了几个动画来展示这个很酷的功能。在战斗中,当你看到敌人眨眼的时候,这也是一个很好的反馈。

我一直讨厌玩家必须将文件拖到游戏打开的Notepad2窗口的顶部。如果他们双击该文件,它将使用MS记事本或任何他们设置为.txt文件扩展名的默认程序打开。我可以执行一个命令,将.txt文件的默认程序更改为Notepad2,但如果游戏对我的计算机这样做,我会非常生气。好的,如果你在玩家退出游戏时把它改回来呢?当然,我可以这么做,但如果游戏以其他方式意外崩溃或关闭怎么办?所有这些选择似乎都是我无法证明的。直到最后我有了这样的想法,我不使用.txt文件,而是使用.Tхt文件。如果你认为这句话令人困惑,我不会责怪你,但是的,这是有区别的。“.Tх%t”具有不同类型的“x”。具体地说,它是U+0445西里尔小写字母Ha Unicode字符。为防止混淆,我将其命名为.txt。因此,我将其设置为所有文件的类型为.txt,并使用命令将txt文件的默认程序更改为Notepad2。

可悲的是,或者我应该说幸运的是,程序只有在以管理员身份运行时才能更改默认程序。现在,对于发布的游戏,如果您不以管理员身份运行游戏,文件将为.txt类型。如果您在MS记事本中打开文件,游戏会告诉您需要将文件拖到打开的记事本上,或者您可以管理员身份运行游戏以允许您双击。在您以管理员身份运行游戏至少一次之后,默认程序已设置,并且将使用.txt文件扩展名。

那都是3年前的事了。嗯,除了缺省的程序部分。是我在释放前3周想出来的。但是这三年之间发生了什么呢?嗯,这是一个典型的失去动力的例子。这个故事的想法和现在几乎一样,除了更大。你的父母被龙杀死了,你需要去找铁匠费尔丹,他会告诉你关于剑的事。只不过这把剑原来是用你需要收集的3种不同的材料锻造的。正因为如此,游戏的范围要大得多,这意味着终点更远了。这个游戏感觉也不是很有趣。在开始这个项目2个月后,我退出了。

但这个项目一直萦绕在我的脑海中。我围绕着用记事本制作游戏构建了整个框架,项目就在那里。我应该把它做完,让世界看看我做了什么。然后在2019年,我几乎没有完成任何项目。对自己感到失望,我决定在2020年通过完成未完成的事情来改变这一点。从记事本游戏开始。所以我们就来了。我缩小了范围,给自己设定了一个月的最后期限(比这个多花了一个星期),然后匆忙完成了。我把游戏提交给了A迷宫。奖项,其中截止日期是2月2日,所以这有助于激励。

我真的很高兴游戏结束了。想到这个项目一直只是收集数字灰尘,而现在我已经能够在大约一个月内完成它,这简直是疯了。不管怎么说,没有一个很好的理由让这场比赛像我最初想象的那样大。当你有一个像这样诡异的花招的游戏时,游戏需要变得足够大,以展示你可以用它做的所有酷的事情。不过,我想说的是,在这款游戏中,我本可以做更多的事情,而不是你在最终产品中可以找到的东西。无论如何,我为我所取得的成就感到自豪。

下一个是什么?一场彩绘游戏?计算器里的游戏?我可能不会制作它们,但我希望看到更多这类使用非传统平台的游戏。