从零开始为四个玩家开发和创建街机

图片

在2019年11月,我辞去工作,决定花几个月时间学习我一直想学习的新技能。当时我是一名Web开发人员。在此之前,我研究了软件开发。甚至早在小时候,我就一直在尝试电子学和程序。因此,我对软件的创建有足够的信心。

但是,我每天都会使用这种神奇的东西叫做“铁”,但是我不知道它是如何工作的。软件开发人员(尤其是Web开发人员)不需要了解硬件。由于所有Web开发代码都是非常高级的,因此很少发现我们软件的问题与硬件有关。

因此,除了高中时,我从未从事过“熨斗”工作,也没有任何电气工程方面的常识。我想改变这种情况。我给自己设定了一个荒谬的目标,那时的目标似乎与我的知识水平相去甚远。然后...我才开始尝试。我计划检查一下我能走多远,然后才能耗尽动力。我没想到会实现我的目标,但是我成功了。

这是我的结果:


我不可思议的目标是从头开始创建一个四人游戏机。它使用微控制器作为大脑,并使用LED条作为显示器。对于位于桌子边缘的每个玩家,使用一个操纵杆和四个按钮,即可控制从内存芯片动态加载到系统中的游戏。因此,设备上的游戏玩法类似于老式的旧游戏机。只是现在,我们不需要吹除磁带来摆脱错误。

令我惊讶的是,我确实能够完成该项目。我花了大约三个完整的工作月来完成实验,失败,阅读文档,绝望和重试的周期。为了确定我花了多少时间,有必要固定工作时间。我将假设大约800-900小时。(假设我每周工作6/7天,每天工作8-10小时,这几乎是事实。)

我试图记录从头到尾的实验过程,拍照和录制视频。通过这篇文章,我将自己记录该项目和我的经验。我希望,如果您也决定进行同样令人难以置信的项目,那么它将对您有所启发。

开始工作


正如我在文章开头所说的那样,当我开始该项目时,除了对欧姆定律公式的记忆不正确之外,我对电子学一无所知。因此,首先,我需要研究电子设备在实际中的工作方式,然后才尝试组装游戏机。我什至不知道如何使用微控制器打开LED。因此,我的第一步是:订购简单的电子设备和微控制器进行实验。首先,我将尝试为LED供电。我几乎可以肯定,我第一次尝试打开LED会导致其烧毁。但这没有记录在相机上,所以我们假装没有。


使用微控制器,电阻器,晶体管和LED进行实验。

这是第一个主要的里程碑。现在我们知道了如何创建在微控制器中运行的代码。我们还学习了如何使用晶体管作为简单的电子开关来打开LED。惊人!

EEPROM冒险



图。 1.使用移位寄存器仅通过3个输出引脚控制16条输出线。

该项目的一部分是将游戏逻辑写入存储芯片(EEPROM)的能力。将带有播放器的盒带插入系统时,应该已经阅读了它们。

从长远来看,我没有学习到足够的信息来了解该项目应使用哪种类型的EEPROM,这使我很受苦。我非常热情,以至于我购买了旧的并行EEPROM芯片(W27C512)。

要写入或读取它们,我需要能够在所有16条线上设置高电平或低电平信号。如果我不想占用微控制器的所有输出触点,那么学习如何使用移位寄存器将是合乎逻辑的。


图。 2.尝试将数据读取/写入并行EEPROM芯片失败的电路。

仅需几个触点,我们就可以分别控制所有16条线。

现在,将这些知识应用于EEPROM!是的...但是没有。我无法稳定地将数据写入EEPROM。这种类型的芯片需要12-14 V的电压才能删除或写入字节。我试图通过使用晶体管作为开关来提供电压以提供电压。据我了解,它必须有效。但这没用。我仍然不明白到底是什么问题。在图。图2显示了我尝试用于从EEPROM读取/写入字节的电路。


图。 3.成功地对串行EEPROM芯片进行字节读写的电路

最后,在研究了有关该主题的更多信息后,我了解到如今并行EEPROM不再被广泛使用。通常,开发人员更喜欢串行EEPROM I2C,因此,在其上查找教程要容易得多。 (例如,这个很棒的Sparkfun教程)。

在图。图3显示了我的用于向串行EEPROM读取和写入数据的方案。它更简单,更可靠。这告诉我,您不应该对订购零件和尝试太快地开发项目感到高兴。我们在并行EEPROM上花费了大约1-2周,最终根本没有使用它们。但是,在此过程中,我们学到了很多电子技术和阅读规范(这本身就是一项技能)。这些努力并未完全浪费。

那么我们该怎么做呢?


现在我们可以读写存储芯片了。下一步将是什么?在此阶段,以几个图纸为例更详细地描述我的控制台计划将是合乎逻辑的。


总体规划。这将是一个游戏机,带有可容纳四个玩家的控制器。每个玩家都有一个操纵杆和几个按钮。

红色圆圈标记游戏盒的插头。该连接器将具有四个金属引脚,控制台可使用这些金属引脚读取串行EEPROM以将游戏加载到内存中。

绿色显示了我们计划如何创建一个LED灯带屏幕。我们希望屏幕像素是正方形的发光色块,而不是与其他斑点混合的斑点。

为了达到理想的效果,我们使用了这种方案来将光源彼此分离。同时,它散射了落在屏幕顶部的光线。 (格栅下方的白色条纹表示LED灯条)

我决定制作一个42x42的LED显示屏。即,总共获得1764个LED。我选择数字42,因为这样,桌子的大小恰好适合四个人。

给如此多的LED供电本身就是一项艰巨的任务。在最大亮度下,RGB LED消耗60 mA的电流。 (使白色具有最大亮度)。如果我们乘以LED的总数,那么在5 V时我们将获得105.84 A的最大电流!为了接近此电流,我们购买了电源SE-600-5 MEAN WELL它可以提供高达100 A的电流。这比理论上的105 A还要小。但是,我并不想在游戏中显示具有最大亮度的全白屏幕。此外,我们可以通过编程方式限制亮度。我们还将添加保险丝,以防止意外超过此100 A的限制。


图。4.用于3x3 LED显示屏的纸板原型。

稍后我将返回此屏幕的装配。首先,您需要进行原型制作。让我们看看是否可以使一个小的LED屏幕工作。

该3x3原型由几块分开像素的硬纸板和一块用于散射光的打印机的普通纸组成。效果很好!我们已经收到有关概念工作的精彩确认。

为了使用微控制器控制LED,我们使用了FastLED库。但是,事实证明,如果LED由一条数据总线控制,则不可能以足以用于游戏的速度来更新1764个LED。给定800 kHz的频率,我们可以实现大约每秒17帧的帧速率。并非我们所追求的。就个人而言,我喜欢至少以60FPS玩。幸运的是,这是可能的。使用多个数据总线就足够了。 42x42显示屏可以方便地分为7个相等的部分。这些部分中的每一个都可以通过自己的数据总线进行单独控制。这可以归功于Teensy 4微控制器中FastLED库的并行输出功能使用。通过使用7条数据总线,我们可以获得大约120FPS的最大刷新率!

我没有为此计划,但是有一个偶然的机会,在项目的开始,我选择了这种特殊的微控制器。在我看来,为了使游戏流畅运行,需要此MK提供的快速处理时间。图中的原型 4已经由并行输出功能控制。但是,在此原型中,我们仅使用2条数据总线,只是为了测试是否所有功能都如所述正常工作。

我们如何使用EEPROM执行代码?


因此,在此阶段,我们可以对EEPROM进行读写,并且我们也有LED显示屏概念的有效证明。下一步是什么?

仅剩下两项重要的技术任务:所有玩家的输入法(按钮和操纵杆)的组织。我们还需要弄清楚如何从EEPROM执行游戏逻辑,并在显示屏上显示这些指令的结果。

订购的按钮和操纵杆尚未到货。因此,首先我们将从事EEPROM游戏逻辑的执行。

有很多方法可以执行来自EEPROM的指令(代码)。但是,首先我们需要设置某些要求:

1)代码应易于编写。

2)代码应较小(文件大小)。

3)代码应该能够与现成的库(例如FastLED)进行交互,以减少工作量。

4)代码应能够尽快加载到RAM中,以减少加载时间。

5)您需要能够在常规PC上模拟代码以测试游戏。

6)我们的解决方案必须是高性能的(至少提供60FPS)。

7)解决方案不应要求购买大量附加设备。

8)该解决方案应适用于Teensy 4.0 MK。

9)该解决方案应易于实施。

我想出了四种从EEPROM执行代码的方法:

-我们将通常编译的Arduino代码写在EEPROM上。然后,我们强制外部Arduino程序员从EEPROM读取编译后的代码,并在每次加载新游戏时即时对Arduino重新编程。

-我们将汇编代码加载到RAM中并从那里执行。

-我们使用现成的代码解释器,例如ArduinoBASICBitlash

-我们编写了自己的代码解释器。

这是我们项目的四种解决方案的优缺点的简要比较:


(1)使用外部编程器的解决方案的文件大小非常糟糕。与游戏逻辑一起,我们在本项目中使用的所有代码库都应存储在EEPROM中。为了显示游戏状态,每个EEPROM必须具有自己的FastLED库副本。这一点都不好。可以通过以某种方式将基本代码添加到外部编程器中来解决此问题,然后在对Arduino进行编程之前将其与EEPROM中的代码合并。这将是一个高风险的任务,因为在Internet上查找教程并不容易。我们可能会花太多时间在上面。

(2)从RAM运行汇编器是一个不错的选择。这就是为什么我决定考虑这一点。可以通过使用某些高级语言(例如C)来降低编写代码的复杂性,然后将该语言编译为正确的汇编代码。但是,尚不清楚让它与Arduino上的其他库进行交互有多么容易,所以我决定放弃它。

(3)使用现成的口译员也是一个很好的解决方案。但是,据我所知,所有这些解释器都是基于字符串执行的。这些长行必须写入EEPROM。这不是一个大问题,但绝对不是减小文件大小的最佳方法。另外,还不清楚这些解释器是否可以与Arduino库交互。因此,我认为使用现成的口译员不是一个好主意。

(4)最后,我们有解决方案4:创建我们自己的代码解释器。它满足所有要求,因为解释器的实现方式完全取决于我。他如果我实现了口译员本身的高速,就可以拥有高速。是的,如果我自己提供的话,文件大小会很小,代码也很容易编写。换句话说,我们将完全掌控一切。如果我付出努力,那么一切都会变得完美。这种解决方案的唯一严重缺点是开发时间长。您可能还记得我在这个项目上花费了800-900个小时。也就是说,很明显,我决定选择解决方案4-创建自己的代码解释器。时间对我来说不是问题。我借此机会学习了如何创建编程语言。我将找出为什么用这些语言做出一个或另一个体系结构决策。

ArcadableScript的诞生


解释器的一般原理非常简单。我不会详细介绍它的内部结构,因为在撰写本文时,我正计划完全重写解释器,以使其变得更有效率,并使他更容易编写代码。但是,基本原理保持不变。解释器将为游戏的每个度量执行一个简单的代码循环:


这种方案的一个很大的缺点是每帧只检查一次游戏的输入和状态。对于不需要快速反应的游戏,这是正常现象。但是,在其他游戏中,玩家将无法在帧之间做出反应。我将在下一版解释器中解决此问题。


图。 5

在带有图的图中。图5显示了我计划在不久的将来升级解释器的过程,为游戏状态和游戏框架创建了两个单独的周期。这将使我们每秒可更新游戏状态数百次,而显示则仅每秒60次。

不幸的是,在Teensy 4.0上,无法执行硬件多线程代码。因此,我们将无法并行执行这两个循环。但我确定我会提出一些建议。


一段时间后,我设法使用自己发明的字节码语言编写了两个简单的程序。他们使用原始数字作为输入以最小化文件大小。也就是说,我完成了这两个程序的编写,从字面上写下了解释器可以理解的数字列表。为了让您了解此字节码的可读性,我将演示在示例程序中使用的真实指令,该指令在屏幕上移动点:

// TODO: Write/read all untyped... data to/from ROM
  int untypedGamestate[] = {
    0, // Previous time, to keep track of game time/framerate.
    0, // Player position x.
    0, // Player position y.
    0, // Player R color value.
    0, // Player G color value.
    255, // Player B color value.
  };
  int untypedValues[][3] = {
    // ID, Type, Value
    {0, 0, 0}, // Move up button value 
    {1, 0, 1}, // Move right button value
    {2, 0, 2},  // Move down button value
    {3, 0, 3},  // Move left button value
    {4, 3, 1},  // True/1
    {5, 3, 0},  // False/0
    {6, 4, 0},  // Current millis since game start
    {7, 2, 0},  // Gamestate previous time
    {8, 2, 1},  // Gamestate player x
    {9, 2, 2},  // Gamestate player y
    {10, 2, 3}, // Gamestate player r color
    {11, 2, 4}, // Gamestate player g color
    {12, 2, 5}, // Gamestate player b color
    {13, 3, 1}, // Move player up after button press boundary check
    {14, 1, 0}, // System config screen width
    {15, 1, 1}, // System config screen height
    {16, 3, 3}, // Move player down after button press boundary check
    {17, 3, 5}, // Move player left after button press boundary check
    {18, 3, 7}, // Move player right after button press boundary check
  }
  int untypedCalculations[][5] = {
    // ID, ending, valueLeftID, calculationRightID, calculationOperator
    {0, 0, 9, 1, 1}, // Current player y position - 1
    {1, 1, 4, 0, 0}, // True/1
    {2, 1, 0, 0, 0}, // Up button
    {3, 1, 2, 0, 0}, // Down button
    {4, 1, 5, 0, 0}, // False/0
    {5, 1, 9, 0, 0}, // Current player y position
    {6, 0, 15, 1, 1} // screenheight - 1
    {7, 0, 9, 1, 0}, // Current player y position + 1
    {8, 1, 3, 0, 0}, // Left button
    {9, 1, 1, 0, 0}, // Right button
    {10, 1, 8, 0, 0}, // Current player x position
    {11, 0, 8, 1, 0}, // Current player x position + 1
    {12, 0, 8, 1, 1}, // Current player x position - 1
    {13, 0, 14, 1, 1} // screenwidth - 1
  }
  int untypedInstructions[][10] = {
    // ID, rootInstruction, conditionCalculationLeftID, conditionCalculationRightID, conditionOperator, conditionSuccesValueLeftID,
    // conditionSuccessCalculationRightID, hasFailedCondition, conditionFailedValueLeftID, conditionFailedCalculationRightID
    {0, 1, 2, 1, 0, 13, 0, 0, 0, 0}, // move player up when up button is pressed.
    {1, 0, 5, 4, 1, 9, 0, 0, 0, 0}, // move the player up when the boundary is not reached.
    {2, 1, 3, 1, 0, 16, 0, 0, 0, 0}, // move player down when down button is pressed. 
    {3, 0, 5, 6, 1, 9, 7, 0, 0, 0} // move the player down when the boundary is not reached.
    {4, 1, 8, 1, 0, 17, 0, 0, 0, 0}, // move player left when left button is pressed.
    {5, 0, 10, 4, 1, 8, 12, 0, 0, 0}, // move the player left when the boundary is not reached.
    {6, 1, 9, 1, 0, 18, 0, 0, 0, 0}, // move player right when right button is pressed.
    {7, 0, 10, 13, 1, 8, 11, 0, 0, 0}, // move the player right when the boundary is not reached.
  };

如果您花时间仔细研究代码,则可以了解此解释器的早期版本是如何工作的。当前版本保留了使用“值”,“计算”和“指令”的一般原则。但是,发生了很多变化。我们不再有固定的游戏状态值列表,现在它们只是常规值列表的一部分。此外,我们将“条件”与说明分开。因此,我们可以重用代码中的指令,从而减小了文件大小。

让我们不介绍解释器的细节,因为在重新设计的版本中,所有这些都将很快改变。

现在我们处于知道如何读写EEPROM的阶段,并且我们可以基于普通数字数组执行指令。下一步的逻辑步骤是从代码中删除指令的硬编码列表,并将其写入EEPROM。从现在开始,我们将能够尝试读取和执行EEPROM中存储的指令。


在这一阶段,我们已经掌握了开始创建最终结果所需的概念工作能力的所有证明!

显然,我们创建的原型的每个单独部分仍然需要大量工作。但是,我认为最困难的任务已经解决。我要做的就是发展我已经拥有的东西。一切都很简单!

LED显示屏总成



组装显示器花了很多工作。非常辛苦。首先,我必须将电线焊接到42个单独的条上。每个条带在一侧需要三根电线,在另一侧需要两根电线。也就是说,只有大约200根电线。在进行此项目之前,我没有太多的焊接实践经验,因此您可以清楚地注意到,我进行的焊接越多,质量就会越强。当然,最后,我不得不重做许多第一个LED灯带,因为我不喜欢这个结果。所有这些都是学习过程的一部分!


下一步:我们将所有LED灯条都固定在一块大木板上。往回看,我认为也许是为了更好的导热性,值得使用金属板,因为经过一个小时的操作,显示屏现在变热了(40-50°C)。但这仍然不是经常发生,所以这不是一个大问题。但是,如果我决定重复该项目,则将纠正此方面。


接下来,我们将直径较大的导线连接到LED灯条的正极和负极。为了确保更大直径的导线能够可靠地承受100 A的最大电流,为进一步保护,我们还在显示器的每个部分增加了15 A的保险丝,

在此阶段,我们准备进行首次尝试来控制显示器。经过多次失败和对软件参数和导线的操纵后,我终于设法在显示器上显示了一种单色,而没有失真和干扰。花了很长时间,结果仍然远远不够完美。长期以来,我仍然遇到信号失真的问题,直到我在electronics.stackexchange.com上发布了有关它的问题这个站点的好人帮助我诊断了问题。我仍然不完全了解它是什么,但是通过沿着数据总线将负极引线从MK接地直接连接到靠近数据输入的接地端子,我可以解决它。从那时起,我在显示器上就没有任何失真的问题。


从上图可以看到,两层材料叠加在LED灯条上。

作为这种涂料的材料,我们需要坚固,透明但散射的光。但是,我不想使用玻璃,因为它既昂贵又易碎。因此,我决定采用标准的透明聚苯乙烯。为了使他散射光,我用细砂纸将其处理到无法透过的程度。一切都非常简单。

花了很多时间创建一个直接位于条带顶部的网格。我以为只是订购带有必要参数的格栅,但他们给我的价格约为500欧元。我认为她不值得。因此,我必须自己收集它。为此,我们需要薄的(不超过2毫米厚),耐用的不透明白色塑料条。有很多要求。因此,选择正确的材料要花费很多时间。事实证明,百叶窗(薄板)的条纹非常理想。


首先,我们制作了一个小支架,可以均匀,均匀地切割宽条纹。在这种情况下,获得了相当小的塑料条。然后,我们需要在正确的位置准确地在每个条带的中间切开切口。这是连接塑料件和组装炉排的必要步骤。这是我在第三张照片中所做的。在执行此操作之前,您需要确保锯的宽度等于或略大于所切割条的宽度。否则,炉be无法组装。就我而言,事实证明金属钢锯具有理想的厚度。

在第四张照片中,可以看到将所有条带组装到网格中的结果。这是一个非常烦人且单调的工作,但事实证明该烤架非常耐用。通常,看起来所有单元格都相同。像元大小之间没有太大的差异,否则显示看起来会很奇怪,因此一切都还不错。我对这个烤架很满意。


然后,我将炉rate放在一个可以完成多项任务的木制框架中。首先,她在烤架的顶部放了一块聚苯乙烯。它确保格栅不动。此外,一个木制框架会压紧所有电线,使它们更牢固地固定,并且不会意外脱落(当我移动显示器时发生了两次)。


这张照片显示了放在电线架上的磨砂聚苯乙烯板。请注意,现在几乎看不见烧烤架,这就是我们想要的。


在花费大量时间尝试正确地执行显示控件之后,我们终于设法使其正常工作。一个巨大的问题是信号完整性的保存。但是正如我上面所说。来自electronic.stackexchange的社区帮助了我!

显示屏明亮,比我预期的要明亮得多。必须预见到这一点,订购100 A的电源。


正如我多次说过的,我们使用FastLED库来控制LED。但我没有提到,我也用修改后的版本由FastLED-GFX库 于尔根Skrocki(这本身就是一个端口的Adafruit的-GFX-库为显示屏上的数字简单的渲染该库中的更改很小,但是它们是必需的,以便解释器可以方便的方式与库进行通信。

大脑和...


完成此项目需要解决的最后一项技术任务是完成控制台的操作。您需要将它们变成一个方便且紧凑的集合。但是首先我们需要弄清楚如何处理播放器的所有输入信号。让我提醒您,每个玩家都有4个按钮和一个操纵杆。总共有16个数字输入信号和8个模拟输入信号。 MK永远没有足够的联系人进行此类输入。此外,已经使用两个数据总线引脚来读取EEPROM,并且需要7个并行数据总线引脚来控制显示。

为了解决这个问题,我们将一对移位寄存器用于数字输入。对于所有模拟输入,我们将使用一个模拟多路复用器。


用于同时读写EEOPROM,处理播放器输入和显示控制的方案。

然后混乱开始了。让我从左到右解释这张照片中发生的事情。左面包板的顶部是7条数据总线,用于控制显示。以下是可插入EEPROM和读取EEPROM的区域。

在中间面包板的顶部是一个模拟多路复用器。该多路复用器最多可以接收16个模拟输入信号,并且根据多路复用器上的输入信号,将其中一个模拟信号连接到MK。因此,我们只需要一个模拟输入引脚和一对数字输入引脚即可处理16个模拟输入。这张照片中似乎没有模拟输入连接到多路复用器。

在多路复用器下是MK Teensy。

在右面包板上,我们处理数字输入信号。在这张照片中,简单地将16个数字信号接地。我仍在等待按钮到达,因此我以这种方式测试了所有16个数字信号。借助移位寄存器,只需要4个引脚即可控制所有数字信号。

整个系统是一个巨大的,不可靠的混乱。有必要使其更加紧凑,以使其不会从一次粗心的呼气中消失。因此,我订购了几个原型板,然后再次开始焊接!



事实证明这是一项艰巨的任务!但是,这是学习如何准确焊接的绝佳机会。

为了提出这个电路,我以面包板上电线的混乱为例。然后,我尝试提出一个更智能的电路,以使应该相互通信的组件尽可能地靠近。所以我试图摆脱拉太多电线的需要。现在,我认为您可以使用一些建模工具来设计电路。但是结果仍然很好。

我决定设计一个两层电路。在较低的原型板上,所有输入均被处理。在4个输入连接的每一个上,我都有8条输入线(1-接地,1-正,4-数字输入,2-模拟输入)。 MK使用靠近移位寄存器的四个连接和靠近多路复用器的四个连接与底层通信。

电源位于上层,在右侧有7条用于显示器的输出数据总线,在底部有用于读取EEPROM的触点。最后,当然是微控制器。


在主控制板和播放器的输入之间,放置了中间板以将两侧所需的电线数量从12减少到8,因为不必使用从主板到输入板的所有5条接地线。所有按钮和操纵杆只需一个接地即可。因此,有四个这样的中间板。我喜欢您可以注意到收到的每个下一个木板的质量都有所提高。


由于从未收到订购的按钮,我从另一位卖家订购了另一套按钮,几天后我收到了它。这使我们最终可以开始测试所有按钮。


在此阶段,我还编写了可以在控制台上玩的第一款游戏。是的,现在我将其称为控制台。

我之所以成功,是因为在显示的过程中,我同时改进了口译员。特别是,在编写代码时,我设法改善了开发过程。从外部看,此过程并不那么有趣,因此我决定不对其进行特别记录。


我创建了一个简单的开发环境,用于编写可在控制台上执行的代码。

这种环境可在浏览器中工作,它使您可以为控制台编写代码,而不会弄乱我们在上面看到的混乱的数字列表。另外,我创建了一个在同一Web应用程序中运行的控制台模拟器。

在Web应用程序中为控制台模拟游戏的能力节省了大量时间,因为在PC上进行调试比在MK上进行调试容易得多。

仿真器不是完美的。有一些错误将仿真与在实际版本的控制台上播放区分开。将来,当我编写新版本的解释器时,我将尝试消除它们。支持两个版本的解释器(一个用C ++编写,另一个用TS编写)的需求有点烦人,但这是值得的。

放在一起


都准备好了。我们可以根据取自EEPROM的游戏逻辑以及来自按钮和操纵杆的玩家输入来显示图像。现在,我们需要将所有这些组合到一个耐用的设备中。


我首先在铝板上钻孔,以将按钮和操纵杆固定到位。然后可以将这些板插入木盒的凹槽中,在其中可以方便地将它们凹进去。因此,玩家将无法意外刮伤金属。



我们收集显示器周围的所有东西,并添加可靠的折叠脚(以便于存放)。涂有黑色油漆的金属板看起来非常漂亮。感觉该项目确实正在走向完成。


但是,当然,我误以为该项目已接近完成。这是控制台大约一个月的样子。

我们收集了所有信息,我们知道该按钮不起作用。我们再次拆卸,用按钮解决问题。一切似乎都正常。我们知道操纵杆不起作用。再次拆卸。迟早所有的按钮和操纵杆都将开始起作用。但随后LED停止工作。要修复它们,您需要拆卸整个控制台并从头开始重新组装。这持续了大约一个月,直到最终一切正常。

结果




都准备好了!在开始该项目的工作后,已经过了3-4个月。因此,合乎逻辑的是,我继续改善口译员,画树和开发新游戏的动力已经枯竭。在撰写本文时,距离我最近参与该项目的时间已经过去了一个月。我终于有力量为自己和你(我的读者)写这篇纪录片。尽管我并不希望有一个正确的想法的人能真正阅读我写的所有内容,但我希望您喜欢观看该项目逐步发展的照片。

但是,如果您阅读了所有这些内容,那么您可能会对项目的Github存储库感兴趣。当然,我所有的代码都是开源的!https://github.com/Arcadable

进一步的项目开发计划:

-首先,您需要制作一个更漂亮的弹药筒以供四人打乒乓球,如上一个视频所示。它是一块带有弯曲铝箔的纸板,用作接触表面。

-另外,我想更好地绘制控制台。最初,我计划与经验丰富的喜欢绘画的朋友一起绘画。但是,现在由于大流行,这是不可能的。

-最后,正如我说过几次,我将以一种更有效的方式重写解释器。我还将改善开发环境以简化游戏。Web应用程序设计目前正在阻碍生产力。


补偿录制垂直视频。

All Articles