树莓派Pico上的游戏
在这篇文章中,我想谈谈 Raspberry Pi Pico 上的游戏。
我记得我的第一部傻瓜手机,那时候叫 "电话"。它可以玩像蛇这样的简单游戏。那是一种边缘化的东西。
在此之前,你必须携带一个单独的掌上电脑,玩俄罗斯方块或更多的动态游戏系统,如Gameboy。
与90年代的手持设备相比,Raspberry Pi Pico是一个相当强大的微控制器。自然,它为我们提供了玩那个时代的游戏的能力。
Raspberry Pi Pico的功能有多强大
与80年代的控制台相比,Raspberry Pi Pico的功能非常强大。
如果你编程的游戏与20世纪80年代的游戏的资源要求相似,Raspberry Pi Pico可能会轻而易举地通过它。
到了90年代,要说出这样一个明确的结论开始变得有点困难了。
一方面,如果你认为它是一个能够玩类似于Gameboy或手机上的游戏的设备,你可能会感到高兴。
然而,90年代后期的游戏变得更加费力。例如,你不会在Pico上玩Quake 3(1999年的游戏)。
事实上,虽然Raspberry Pi Pico可以播放《毁灭战士》(1993年),但对编码的人来说,这是一个为期6个月的努力,因为将游戏压缩到Raspberry Pi Pico的2MB存储空间是一个相当困难的任务。
因此,虽然Pico有两个133MHz的处理器,但它的内存和存储空间有限,这使得它很困难。
让我们看看它与Gameboy相比如何。
规格 | 树莓派Pico | Gameboy (1989) | 彩色游戏机 (1998) |
显示 | 彩色LCD或电子墨水,这取决于你的想象力 | 4种色调的灰度 | 10、32、56种颜色 |
决议 | 取决于你的显示器,但受限于Pico的资源。 | 160x144px | 160×144 px |
CPU | 133MHz双核 | 4MHz | 4MHz/8MHz |
内存 | 264KB | 8KB | 32kb内存,16kb显存 |
储存 | 2MB | 游戏包盒:8MB ROM,128KB RAM | 游戏包盒:8MB ROM,128KB RAM |
为什么在Pico上玩游戏而不是在Zero/Pi 4上?
好问题。
如你所知,Raspberry Pi Pico是一个微控制器,而Raspberry Pi Zero或Pi 4是微型计算机。
两者都可以玩游戏,但Raspberry Pi Pico的限制更多。
也就是说,如果你想在今天(2022年)用Raspberry Pi Zero或Pi 4s建立一个模拟器或游戏系统,你最好已经有一个,否则你最大的瓶颈就是库存。
要获得Pi Zero非常困难,要获得Pi 4也相当具有挑战性。
另一方面,Pico的内容很丰富。它也几乎可以立即启动,而微机皮克则要经历一个漫长的启动过程。
Pico的持续时间也更长。如果你想要一个能运行数小时且便于携带的移动装置,那么你用Pico会好很多。
最后,除了库存之外,Pico的库存也很充裕。
对Pi Zero和Pi 4来说是公平的,你绝对可以用这些微型计算机玩更好的游戏,获得更好的仿真效果。正如你在下一节所看到的,Pico在玩Zero或Pi 4会轻而易举地通过的游戏时确实很吃力。
Raspberry Pi Pico可以玩什么游戏?
我们先来看看修理工社区在Raspberry Pi Pico上都玩了些什么。
RP2040 "末日 "是对 "会不会末日 "的回答。
是的!Raspberry Pi Pico可以玩Doom。
一个来自德克萨斯州奥斯汀的名叫格雷厄姆-桑德森的家伙,成功地将《毁灭》移植到了树莓派Pico上。
他的神奇配方?
while (!convice_myself_its_probably_impossible()) {
do_some_more();
}
他 在他的过程文件中解释说 他面临着树莓派Pico的硬件规格所带来的多种限制。毕竟,这不是一个用于游戏的设备。
尽管如此,格雷厄姆还决定使《毁灭战士》的移植工作更加困难。他希望得到《毁灭战士》的真实体验,这意味着要有320×200(彩色)的分辨率、立体声、OPL2音乐、保存和加载、网络多人游戏和其他原名中的功能。
在Raspberry Pi Pico上装这么多的游戏意味着内存方面的挑战。内存和存储都是关键问题。
首先,Raspberry Pi Pico只有2MB的存储空间,但Doom的共享软件版本是这个大小的两倍。虽然其他开发者可能会决定削减某些功能,如闪屏和降低纹理的取样,但格雷厄姆不想这样做。
内存也是另一个问题,Chocolate Doom源代码需要约1MB的内存,而Pico只有约264KB。内存紧张是因为渲染图形占用了RAM的一大块空间,但RAM对于游戏的顺利运行也非常重要。为了管理这两个方面,格雷厄姆不得不做他所谓的 "抽脂"。
你可以通过以下网址阅读更多信息 文件,观看 他的YouTube播放列表 或 审查代码.
NES仿真器
Raspberry Pi Pico已被成功制成NES模拟器。
在仿真器区论坛的一个主题中,用户ropgar说,Raspberry Pi Pico具有模拟NES的能力,它可以做到每秒60帧,并且可以完美地模拟APU和PPP。
罗普加使用PS/2键盘作为控制器,但你也可以使用原始的NES控制器。
声音很好,视频和背景游戏音乐没有出现故障。
Pico有大约1.5MB的闪存空间,可用于不同的游戏,可以通过按Caps Lock键在游戏间切换来选择。
ropgar设法在他的演示中加载的游戏有:吃豆子、Arkanoids、DK、小DK、BubbleBobble、Galaga和许多其他游戏。
有一个缺点是,没有公开的源代码或教程说明如何做到这一点。
用于Raspberry Pi Pico的Gameboy模拟器
你可以制作你自己的Gameboy外壳,然后用Raspberry Pi Pico来模拟Gameboy。
这里棘手的部分是,它实际上不是已经看到大量成功的东西。换句话说,你建立的东西可能有效,但不一定。
让我们来看看有哪些选择。
Rust Gameboy模拟器(OxidGB Pico Port)。
一看到屏幕上的口袋妖怪图像,我立刻兴奋起来。
然而,詹姆斯-塞尔比实际上写了关于他的Gameboy模拟器的挑战和缺点,该模拟器是用Rust编写的,名为OxidGB Pico Port。
"塞尔比说:"这是一次旅程--一次令人沮丧的旅程,但从教育的角度来说,我还是非常享受这次旅程。
问题和胜利
这里是主要的挑战。 Rust Gameboy模拟器 "不幸的是,在其目前的状态下并不完全可玩"。
塞尔比说,游戏只能得到大约10 FPS,因为模拟器的代码是一个瓶颈,以及到显示器的缓慢SPI接口。
有可能加快事情的进展,但这需要时间来计划和实施。
输入还没有配置好,因为游戏不能玩。
测试OxidGB Pico端口
如果你想试一试,你可以按照塞尔比的指示在他的 OxidGB Pico端口的Github repo。
RP2040_GB仿真器
你可以尝试的另一个仿真器是 RP2040_GB,它是基于 花生-GB 仿真器。
RP2040_GB的性能还不错,Koshkouei说他的设置 "在没有音频模拟的情况下以超过70帧的速度运行。在跳帧和隔行扫描的情况下,可以以120帧的速度运行"。
正如你所看到的,RP2040_GB正在玩口袋妖怪。把ROM装到RP2040上的步骤是这样的。
- 你必须拥有Pico SDK
- 转换 .gb 或 .gbc ROM到一个C头文件,使用 xxd 节目
- 通过添加两行代码来修改转换后的文件(在Github readme中)。
- 将ROM复制到 画面 文件夹,并进行编译。
这个模拟器有一些限制。
- "这个模拟器是不准确的,而且在很大程度上是一项正在进行的工作......一些游戏可能运行不正确或根本无法运行。"
- Gameboy Color游戏会出现错误
- 没有对微控制器进行优化。Koshkouei建议,"使用针对空间和速度进行优化的APU "可以帮助。
用树莓皮Pico编撰大型游戏
这个项目最好的地方是它很简单,而且说明足以让你迅速开始制作Raspberry Pi Pico游戏机。
Roger Bühler在他的Github上有零件、说明和演示。
大型游戏汇编包含以下游戏。
- 小小吉尔伯特
- 小小的把戏
- 小小侵略者 v3.1
- 小小弹球 v2
- 小小吃豆人 v1.2
- 小小炸弹人 v1.3
- 小巧的自行车 v1.2
- 小Bert 1.1
- 小小阿卡诺德 v2
- 小小特里斯 v2.1e
- 小小的牌子
- 小小DDug
- 小小导弹 v1.1
- Tiny Lander v1.0 ( 作者:Roger Buehler )
- 小小的莫泊桑
- 小管子
你需要的部件如下。
- 树莓派Pico
- SSD1309 128x64px SPI OLED显示屏(2.42英寸显示屏,2:1比例)。
- 压电式蜂鸣器
- 五个按钮
- 麵包板
- 跨接电缆
- 可选:10欧姆电阻,额定电压至少为10V和220uF的电解电容器
你还将需要 Adafruit的SSD1306库.
下面是连接显示器的方法。
- GND -> 显示器GND
- 3V3(OUT) -> 显示屏VCC
- GP16 -> 显示DC(数据命令)。
- GP17 -> 显示CS(通道选择)。
- GP18 -> 显示SCL(时钟)。
- GP19 ->显示SDA(MOSI)。
- GP20 -> 显示RES(复位)。
并且要连接按钮。
- GP15 -> 按钮向上
- GP14 -> 按钮下降
- GP13 -> 按钮 LEFT
- GP12 -> 按钮右键
- GP11 -- -- 按钮FIRE(所有按钮到GND)。
并连接压电式蜂鸣器。
- GP10 -> 蜂鸣器(+)
- GND -> 蜂鸣器(-)
软件安装。
为了安装该软件,你需要使用Arduino IDE。
树莓派Pico上的类似玉兔的游戏(Pico-Tamachibi)。
为什么它被称为Pico-Tamachibi?
据该设备的创造者凯文-麦卡勒说,"tama "的意思是 "鸡蛋","chibi "指的是人物有一个大脑袋的图形。
创建Tamachibi很容易,因为凯文在他90分钟的教程中介绍了每一步的方法。
建立你自己的游戏机
如果你想制作自己的Raspberry Pi Pico游戏机,一般有两种方法:购买现成的套件或自己制作。
现成的套件与DIY树莓派Pico游戏硬件的对比
虽然有可能从头开始,但你可能想跳过建立自己系统的麻烦,直接购买一个现成的软件包。
有一些基于RP2040的套件,可以让你直接跳到玩或开发自己的游戏。
让我们看看Pimoroni Picosystem,然后将其与使用单个零件建造类似东西的过程进行比较。
Pimoroni Picosystem
让我们来看看Pimoroni Picosystem。
正如你所看到的,它比Raspberry Pi Pico W大得多,但这也是因为它有一个四向D-pad,四个按钮,LCD屏幕,一个锂离子电池,压电扬声器和一个USB-C端口,以及其他附加功能。
它有相同的处理器和内存,因为Picosystem和Pico都使用RP2040芯片。以下是完整的规格。
- 由RP2040(双臂Cortex M0+,264kB的SRAM)提供动力
- 16MB的QSPI闪存支持XiP
- 1.54英寸彩色SPI IPS LCD(240×240和120×120模式)。
- D-pad和按钮
- 525mAh锂电池(6小时以上)。
- 压电式蜂鸣器/扬声器
- 开/关电源按钮
- RGB LED
- 可编程,可通过USB-C充电(不包括电缆)。
图形模式
PicoSystem支持两种图形模式。
- 240×240:LCD的原始分辨率
- 120×120:像素加倍模式(节省RAM)。
Picosystem上的游戏是什么样子的?
在Picosystem上玩游戏很容易。只需按下电源按钮,你就可以看到预装的游戏 "超级广场兄弟"。
该游戏是一个简单的平台游戏,很像马里奥。
皮摩罗尼还包括其他游戏。
- 超级广场兄弟 由Scorpion Games制作 - 一个有弹性的四边形平台游戏 (预装游戏)
- 点状物 - 点弹出的益智游戏。创建两个或更多的链子,竞相获得最大的分数。
- 岩石和钻石 - 躲避石块和抓取钻石的经典游戏。
- 几何学 - 用激光击碎太空巨石,以制造更小的太空巨石!
- 彩虹上升 - 黑暗之魂》的程序生成的垂直跳跃谜题。好运。
- 超级布利特卡丁车 Daft_Freak - 一个基于 "Mode7 "的赛车游戏。
为了安装这些游戏,请做以下工作。
- 下载文件。
- 将您的Picosystem插入电脑
- 按住X键,并按下电源键。
- Picosystem应该被安装成一个名为RPI-RP2的驱动器。
- 将下载的.uf2文件复制到驱动器上。它将自动加载。
由于某些原因,我的USB-C到USB-C电缆没有工作,但USB-A到USB-C电缆在Picosystem上工作。如果您没有看到红色LED灯亮起,那么请尝试其他电缆。
为你自己的游戏编程
Picosystem最好的部分是它为你提供了一个创建你自己的游戏的系统。
与其从头开始编码,PicoSystem附带了一个特殊的API,可以帮助你创建你的游戏。
它还消除了很多购买单个部件的繁琐工作,如液晶屏、按钮、跳线、面包板,然后弄清楚让所有这些工作所需的库和包。
PicoSystem的API具有在屏幕上绘制东西、输出音频、硬件功能和其他实用功能。这使你更容易建立你的游戏。
就像Raspberry Pi Pico一样,PicoSystem可以用C++或MicroPython进行编码。
用Picosystem进行游戏编程容易吗?
我建议你有一些时间和耐心,以便用Picosystem建立自己的游戏。
文档提供了基础知识,以便让你开始工作,但如果你以前有一些游戏编程的知识,这将是最好的。
对于初学者来说,最大的挑战是没有多少资源可以教你如何编码样本项目。然而,这里有一个参考清单,可以帮助你。
Picosystem MicroPython指南(在readme中)。
Picosystem API小抄,外加图像、字体转换器 (在侧边栏)
DIY系统。创建硬件
YouMakeTech的指南 该书带领读者了解如何制作一个完整的游戏机,包括外壳、音响系统和永久焊接。
对于我们的比较,让我们看看建造一个DIY装置与Picosystem的成本是多少,后者是一个完整的套件。
YMT的游戏系统 | Pimoroni Picosystem | |
案例 | 可选的,3D打印($4.47为STL蓝图,加上灯丝和3D打印机的租赁/操作费用)。 | 包括 |
树莓派Pico | $5用于Pico H,因为你将需要针座。 | 包括 |
OLED显示屏 | $15(0.96英寸显示屏) | 包括 |
钮扣 | 可忽略不计 | 包括 |
麵包板 | $15(面包板套件) | 包括 |
跳线 | 包括在面包板套件中 | 包括 |
螺钉 | 高达$1 | 包括 |
压电式 | 可忽略不计 | 包括 |
总成本 | $40.47,不包括3D打印费用 | $70 |
因此,让我们看看不同层级的DIY设置的最终成本。
设置 | 费用 |
没有电池 | $40.47不包括3D打印费用 |
锂离子电池 | $8 |
Pimoroni Pico Lipo | $16.39 - $4(由于我们使用的是Pimoroni Pico的替代品,我们可以扣除Raspberry Pi Pico的成本) |
电池供电的套件总计 | $60.86,不包括3D打印费用 |
只是要注意的是--YouMakeTech说,你可以用低于$20的价格建造这个。然而,在我的研究中,与Picosystem相匹配的DIY装置的成本其实相差不大,特别是当你考虑到软件和便利性时。
这就是说,DIY路线是一个很好的学习机会。挑战我的一件事是屏幕。YouMakeTech的例子使用的是I2C连接,而我的屏幕使用的是4针的SPI接口。这要么需要改变编码,要么需要对硬件进行修改,以便继续进行。如果你喜欢挑战,DIY路线就适合你。
那么,DIY与Picosystem相比,有什么优势呢?
优点/缺点 | DIY | 皮考斯系统 |
硬件组装 | 你DIY一切 | 你什么都不自己动手 |
软件 | 这里没有什么帮助。你自己DIY一切,并学习如何操作每个组件。 | 你必须学习Picosystem的API |
学习机会 | 更大的学习机会,因为你是把不同的部分拼凑起来的 | 较小。它是现成的,软件将是这里最大的学习机会 |
延伸性 | 既然你建造了它,你可以改变LCD屏幕,添加更多的按钮,添加LED,等等。 | 除非你想把一个完整的系统拆开,否则不多。 |
在Picosystem与DIY系统上创建类似Pong的游戏
我的一个好奇的实验涉及到了解使用Picosystem开发一个游戏和从头开始做一个游戏要花多少精力。
为了比较这两个系统,我将在YouMakeTech的DIY系统和Picosystem上建立一个类似于Pong的单人游戏。
该游戏的前提很简单。这是一个类似于庞克的单人游戏,每当你的球从球拍上弹起时,你会得到10分。如果球掉到屏幕底部,你就会得到一个 "游戏结束 "的信息。
在这两个系统上创建游戏遵循一个简单的工作流程,所有这些都指向Thonny。
你需要将MicroPython闪存到Pico上,然后你将使用Thonny来编码你的程序。
你在Picosystem上闪现的MicroPython与官方MicroPython UF2文件不同,所以要确保你闪现的是正确的,因为Picosystem会在官方MicroPython版本上运行。它只是不能按原计划运行。
现在,让我们来看看两者之间的一些基本差异。我这里不包括游戏逻辑,只比较软硬件互动和编程模式的差异。
第一个区别:硬件代码
在DIY路线上,事情非常 "原始"。这里有一些初始化显示器、GPIO和按钮的代码,你不需要用Picosystem来做。
from machine import Pin, PWM, I2C,
from ssd1306 import SSD1306_I2C
…
# Buttons
up = Pin(2, Pin.IN, Pin.PULL_UP)
down = Pin(3, Pin.IN, Pin.PULL_UP)
left = Pin(4, Pin.IN, Pin.PULL_UP)
right = Pin(5, Pin.IN, Pin.PULL_UP)
button1 = Pin(6, Pin.IN, Pin.PULL_UP)
button2 = Pin(7, Pin.IN, Pin.PULL_UP)
# Buzzer connected to GP18
buzzer = PWM(Pin(18))
# OLED Screen connected to GP14 (SDA) and GP15 (SCL)
i2c = machine.I2C(1, sda = Pin(14), scl = Pin(15), freq = 400000)
oled = SSD1306_I2C(SCREEN_WIDTH, SCREEN_HEIGHT, i2c)
第二个区别。Picosystem的API
如果你在Picosystem上写代码,你就必须在其系统内写。
在YouMakeTech的例子中,所有游戏逻辑都被封装在一个 而真 循环。这包括按钮互动、碰撞检测和对屏幕的绘制。
在Picosystem中,你需要在三个功能范围内进行写作--- init(), update() 和 绘制().
在我的代码中,所有游戏的逻辑都写在 update() 包括碰撞处理和D-pad互动。
在一个简单的乒乓游戏中,我使用了API中的几个函数,使事情变得更简单。
相交(x1, y1, w1, h1, x2, y2, w2, h2) 可能是这里最大的帮助。你将传递两个方块的坐标和大小,如果有交集,它将返回true。在本例中,这两个矩形是球和杆(又称桨)。intersects()函数的缺点是它不能检测到碰撞发生在哪一边,所以我不得不写额外的代码来处理酒吧一边的碰撞问题。
Picosystem的API将在你开发更复杂的游戏时真正大放异彩,因为它已经有了帧缓冲器、音频输出、混合等的方法。
Pimoroni Picosystem Pong-like游戏的代码
#bar_pos_x = pixels from left, e.g. 0 from left
bar_pos_x = 50
#bar_pos_y = pixels from top, e.g. 100px from top
bar_pos_y = 100
BAR_WIDTH = 30
LENGTH_CONSTANT = 5
ball_speed = 1
ball_pos_x = 10
ball_pos_y = 10
ball_dx = 2
ball_dy = 2
score = 0
game_over = False
def update(tick):
global bar_pos_x
global bar_pos_y
global ball_pos_x
global ball_pos_y
global ball_dx
global ball_dy
global ball_speed
global score
global game_over
def reverse_ball_dx():
global ball_dx
ball_dx = ball_dx * -1
def reverse_ball_dy():
global ball_dy
ball_dy = ball_dy * -1
ball_pos_x += ball_dx
ball_pos_y += ball_dy
if button(LEFT) and bar_pos_x > 0:
bar_pos_x -= 1
if button(RIGHT) and bar_pos_x < 120 - BAR_WIDTH :
bar_pos_x += 1
if ball_pos_x <= 0 :
ball_pos_x = 0
reverse_ball_dx()
if ball_pos_x >= 120 - LENGTH_CONSTANT :
ball_pos_x = 120 - LENGTH_CONSTANT
reverse_ball_dx()
if ball_pos_y >= 120 - LENGTH_CONSTANT :
game_over = True
if ball_pos_y <= 0:
ball_pos_y = 0
reverse_ball_dy()
if intersects(bar_pos_x,bar_pos_y,BAR_WIDTH,LENGTH_CONSTANT, ball_pos_x, ball_pos_y, LENGTH_CONSTANT,LENGTH_CONSTANT):
reverse_ball_dy()
score += 10
#main intersection of ball and bar. if they intersect, check if they are intersecting on the sides.
#if not on sides (i.e. on top) reverse Y direction. Or else, reverse X direction.
if intersects(bar_pos_x,bar_pos_y,1,LENGTH_CONSTANT, ball_pos_x, ball_pos_y, LENGTH_CONSTANT,LENGTH_CONSTANT):
#intersecting on left
reverse_ball_dx()
ball_pos_x -= 2
if intersects(bar_pos_x + BAR_WIDTH,bar_pos_y,1,LENGTH_CONSTANT, ball_pos_x, ball_pos_y, LENGTH_CONSTANT,LENGTH_CONSTANT):
#intersecting on right
reverse_ball_dx()
ball_pos_x += 2
def draw(tick):
if game_over:
pen(0,0,0)
clear()
pen(15,15,15)
text("Game Over", 35, 60)
else:
pen(0, 0, 0)
clear()
pen(15,15,15)
#draw bar (paddle)
frect(bar_pos_x,bar_pos_y,BAR_WIDTH,LENGTH_CONSTANT)
#draw the ball
frect(ball_pos_x, ball_pos_y, LENGTH_CONSTANT,LENGTH_CONSTANT)
text(str(score), 80, 20)
start()
有什么游戏可以推荐吗?
如果你有适用于Raspberry Pi Pico的游戏,请在下面留言并附上网址。
如果您想了解我们的 "百丽宫项目 "系列,请访问 这里.
pimoroni 系统是否有代码允许您使用外部附件/设备(如小型 Fpga)来提高性能?