如何使用 Python 和 Arcade 库创建 2D 游戏
Python对于学习编程的人来说是一门出色的语言,非常适合任何想要“完成工作”而不是花大量时间在样板代码上的人。Arcade是一个 Python 库,用于创建易于上手的 2D 视频游戏,并且在您获得经验时非常有能力。在本文中,我将解释如何开始使用 Python 和 Arcade 来编写视频游戏。 在教学生使用PyGame库后,我开始在 Arcade 上进行开发。我使用 PyGame 进行了近 10
Python对于学习编程的人来说是一门出色的语言,非常适合任何想要“完成工作”而不是花大量时间在样板代码上的人。Arcade是一个 Python 库,用于创建易于上手的 2D 视频游戏,并且在您获得经验时非常有能力。在本文中,我将解释如何开始使用 Python 和 Arcade 来编写视频游戏。
在教学生使用PyGame库后,我开始在 Arcade 上进行开发。我使用 PyGame 进行了近 10 年的面对面教学,并开发了ProgramArcadeGames.com用于在线教学。 PyGame 很棒,但最终我觉得我在浪费时间来解决从未修复过的错误。
我担心教诸如事件循环之类的东西,这不再是我们编码的方式。我有一个整个部分我在其中解释了为什么 y 坐标被反转。因为 PyGame 很少更新并且它基于旧的SDL 1库,而不是像OpenGL这样更现代的库,所以我对未来没有太大希望。
更多 Python 资源
-
什么是IDE?
-
备忘单:适用于初学者的 Python 3.7
-
顶级 Python GUI 框架
-
下载:7 个必不可少的 PyPI 库
-
红帽开发者
-
最新 Python 内容
我想要一个更容易使用、更强大的库,并且使用了 Python 3 的一些新特性,比如装饰器和类型提示。街机就是它。这就是如何开始。
安装
与许多其他软件包一样,Arcade 可通过PyPi获得,这意味着您可以使用pip
命令(或pipenv命令)安装 Arcade。如果您已经安装了 Python,您可能只需在 Windows 上打开命令提示符并键入:
点安装街机
或者在 MacOS 和 Linux 上输入:
pip3 安装街机
更详细的安装说明可以参考Arcade安装文档。
简单画法
您只需几行代码即可打开一个窗口并创建简单的绘图。让我们创建一个绘制笑脸的示例,如下图所示:
图片来源:
下面的脚本展示了如何使用Arcade 的绘图命令来执行此操作。请注意,您不需要知道如何使用 classes 甚至定义 functions。对于想要开始学习编程的人来说,具有快速视觉反馈的编程非常有用。
进口商场
# 设置屏幕大小的常量
屏幕_宽度 \u003d 600
屏幕_高度 \u003d 600
# 打开窗户。设置窗口标题和尺寸(宽度和高度)
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "绘图示例")
# 设置背景颜色为白色。
# 有关命名颜色的列表,请参见:
# http://arcade.academy/arcade.color.html
# 颜色也可以指定为(红、绿、蓝)格式和
#(红、绿、蓝、阿尔法)格式。
arcade.set_background_color(arcade.color.WHITE)
# 开始渲染过程。这必须在任何绘图命令之前完成。
arcade.start_render()
# 画人脸
x \u003d 300
y \u003d 300
半径 \u003d 200
arcade.draw_circle_filled(x, y, 半径, arcade.color.YELLOW)
# 画右眼
x \u003d 370
y \u003d 350
半径 \u003d 20
arcade.draw_circle_filled(x, y, 半径, arcade.color.BLACK)
# 画左眼
x \u003d 230
y \u003d 350
半径 \u003d 20
arcade.draw_circle_filled(x, y, 半径, arcade.color.BLACK)
#画出微笑
x \u003d 300
y \u003d 280
宽度 \u003d 120
高度 \u003d 100
开始_角度\u003d 190
结束_角度\u003d 350
arcade.draw_arc_outline(x, y, width, height, arcade.color.BLACK, start_angle, end_angle, 10)
# 完成绘制并显示结果
arcade.finish_render()
# 保持窗口打开直到用户点击“关闭”按钮
街机.run()
使用函数
当然,在全局上下文中编写代码并不是一种好的形式。值得庆幸的是,通过使用函数来改进您的程序很容易。在这里,我们可以看到使用函数在特定 (x, y) 位置绘制松树的示例:
def draw_pine_tree(x, y):
""" 该函数在指定位置绘制一棵松树。"""
# 在树干顶部画出三角形。
# 我们需要三角形的三个 x, y 点。
arcade.draw_triangle_filled(x + 40, y, # 点 1
x, y - 100, # 第 2 点
x + 80, y - 100, # 第 3 点
街机.color.DARK\GREEN)
# 画树干
arcade.draw_lrtb_rectangle_filled(x + 30, x + 50, y - 100, y - 140,
街机.color.DARK\BROWN)
有关完整示例,请参见带有函数](http://arcade.academy/examples/drawing_with_functions.html)的[绘图。
更有经验的程序员会知道,现代图形程序首先将绘图信息加载到显卡上,然后再让显卡批量绘制。Arcade 也支持这个。单独绘制 10,000 个矩形大约需要 0.800 秒。将它们作为一个批次绘制只需不到 0.001 秒。
窗口类
较大的程序通常会派生自Window类,或者使用装饰器。这允许程序员编写代码来处理绘图、更新和处理来自用户的输入。下面是一个启动基于Window
\ 的程序的模板。
进口商场
屏幕_宽度\u003d 800
屏幕_高度 \u003d 600
类 MyGame(arcade.Window):
"""主应用程序类。"""
def __init__(自我,宽度,高度):
超级()。__init__(宽度,高度)
arcade.set_background_color(arcade.color.AMAZON)
默认设置(自我):
# 在这里设置你的游戏
经过
def on_draw(self):
""" 渲染屏幕。"""
arcade.start_render()
# 你的绘图代码在这里
def 更新(自我,增量_time):
"""所有的移动逻辑,游戏逻辑都在这里。"""
经过
定义主():
游戏\u003d我的游戏(屏幕\宽度,屏幕\高度)
游戏设置()
街机.run()
如果 __name__ \u003du003d "__main__":
主要的()
Window
类有几个方法,您的程序可以重写这些方法来为程序提供功能。以下是一些最常用的:
-
on_draw
:所有绘制屏幕的代码都在这里。 -
update
:移动物品和执行游戏逻辑的所有代码都在这里。这被称为每秒大约 60 次。 -
on_key_press
:处理按键按下时的事件,例如给玩家一个速度。 -
on_key_release
:释放按键时的处理,在这里你可能会阻止玩家移动。 -
on_mouse_motion
:每次鼠标移动时调用。 -
on_mouse_press
:按下鼠标按钮时调用。 -
set_viewport
:此功能用于滚动游戏,当您的世界比在一个屏幕上所能看到的要大得多时。调用set_viewport
允许程序员设置该世界的哪个部分当前可见。
精灵
Sprites 是在 Arcade 中创建 2D 位图对象的简单方法。 Arcade 有一些方法可以很容易地绘制、移动和动画精灵。您还可以轻松地使用精灵来检测对象之间的碰撞。
创建精灵
从图形中创建 Arcade 的Sprite类的实例很容易。程序员只需要图像的文件名来作为精灵的基础,还需要一个可选的数字来放大或缩小图像。例如:
雪碧_SCALING_COIN \u003d 0.2
coin \u003d arcade.Sprite("coin_01.png", SPRITE_SCALING_COIN)
此代码将使用存储在coin_01.png
中的图像创建一个精灵。图像将缩小到其原始高度和宽度的 20%。
精灵列表
精灵通常被组织成列表。这些列表使管理精灵变得更容易。列表中的精灵将使用 OpenGL 将精灵作为一个组进行批量绘制。下面的代码设置了一个玩家的游戏,以及一堆供玩家收集的硬币。我们使用两个列表,一个用于玩家,一个用于硬币。
默认设置(自我):
""" 设置游戏并初始化变量。"""
# 创建精灵列表
self.player_list \u003d arcade.SpriteList()
self.coin_list \u003d arcade.SpriteList()
# 分数
self.score \u003d 0
# 设置播放器
# 来自kenney.nl 的字符图像
self.player\sprite \u003d arcade.Sprite("images/character.png", SPRITE\SCALING\PLAYER)
self.player_sprite.center_x \u003d 50 # 起始位置
self.player_sprite.center_y \u003d 50
self.player\list.append(self.player\sprite)
# 创建硬币
对于我在范围内(COIN_COUNT):
# 创建硬币实例
# 来自kenney.nl 的硬币图片
coin \u003d arcade.Sprite("images/coin_01.png", SPRITE_SCALING_COIN)
# 放置硬币
coin.center_x \u003d random.randrange(SCREEN_WIDTH)
coin.center_y \u003d random.randrange(SCREEN_HEIGHT)
# 将硬币添加到列表中
self.coin\list.append(硬币)
我们可以很容易地画出硬币列表中的所有硬币:
def on_draw(self):
""" 绘制一切"""
arcade.start_render()
self.coin_list.draw()
self.player_list.draw()
检测精灵碰撞
函数check_for_collision_with_list
允许我们查看一个精灵是否遇到了列表中的另一个精灵。我们可以使用它来查看玩家精灵接触的所有硬币。使用一个简单的for
循环,我们可以摆脱游戏中的硬币并增加我们的分数。
def 更新(自我,增量_time):
# 生成与玩家碰撞的所有硬币精灵的列表。
硬币_hit_list \u003d arcade.check\for\collision\with_list(self.player\sprite, self.coin_list)
# 循环遍历每个碰撞的精灵,将其移除并添加到分数中。
对于硬币\命中\列表中的硬币:
coin.kill()
self.score +\u003d 1
有关完整示例,请参见collect_coins.py。
游戏物理
许多游戏都包含某种物理。最简单的是防止玩家穿过墙壁的自上而下的程序。平台游戏增加了重力和移动平台的复杂性。一些游戏使用带有质量、摩擦力、弹簧等的完整 2D 物理引擎。
自上而下的游戏
对于简单的基于自上而下的游戏,街机程序需要玩家(或其他任何东西)无法穿过的墙壁列表。我通常称之为wall_list
。然后在Window
类的设置代码中创建一个物理引擎:
self.physics_engine \u003d arcade.Physics EngineSimple(self.player\sprite, self.wall\list)
player_sprite
被赋予一个运动向量,它有两个属性change_x
和change_y
。一个简单的例子是让玩家用键盘移动。例如,这可能在Window
类的自定义子类中:
运动_速度\u003d 5
def on_key_press(self, key, modifiers):
"""当一个键被按下时调用。"""
如果键 \u003du003d arcade.key.UP:
self.player\sprite.change_y \u003d 运动\速度
elif 键 \u003du003d arcade.key.DOWN:
self.player\sprite.change_y \u003d -MOVEMENT\SPEED
elif 键 \u003du003d arcade.key.LEFT:
self.player_ sprite.change_x \u003d -MOVEMENT\SPEED
elif 键 \u003du003d arcade.key.RIGHT:
self.player_ sprite.change_x \u003d MOVEMENT\SPEED
def on_key_release(self, key, modifiers):
"""当用户释放按键时调用。"""
如果键 \u003du003d arcade.key.UP 或键 \u003du003d arcade.key.DOWN:
self.player\sprite.change_ y \u003d 0
elif 键 \u003du003d arcade.key.LEFT 或键 \u003du003d arcade.key.RIGHT:
self.player_sprite.change_x \u003d 0
尽管该代码设置了玩家的速度,但它不会移动玩家。在Window
类的update
方法中,调用physics_engine.update()
将移动玩家,但不会穿过墙壁。
def 更新(自我,增量_time):
"""运动和游戏逻辑"""
self.physics_engine.update()
有关完整示例,请参见sprite_move_walls.py。
平台游戏
移动到侧视图平台游戏相当容易。程序员只需要将物理引擎切换到PhysicsEnginePlatformer
并添加重力常数。
self.physics_engine \u003d arcade.PhysicsEnginePlatformer(self.player_sprite,
self.wall_list,
重力_常数\u003d重力)
您可以使用Tiled之类的程序来铺设构成关卡的瓷砖/块。
例如,参见sprite_tiled_map.py。
对于完整的 2D 物理,您可以集成PyMunk库。
以身作则
最好的学习方法之一是通过例子。 Arcade 库有一长串示例程序,人们可以利用这些程序来创建游戏。这些例子都展示了多年来学生在我的课堂或在线上要求的游戏概念。
一旦安装了 Arcade,运行这些演示中的任何一个都很容易。每个示例在程序开头都有一个注释,您可以在命令行上键入一个命令来运行示例,例如:
python -m arcade.examples.sprite_moving_platforms
总结
Arcade 让您可以使用易于理解的代码开始对图形和游戏进行编程。很多新手程序员在上手没多久就创造了很棒的游戏。试试看!
要了解更多信息,请在PyCon Cleveland 2018参加 Paul Vincent Craven 的演讲使用 Arcade 轻松创建 2D 游戏。
更多推荐
所有评论(0)