arcade 物理系统
对于那些学习编程的人来说, Python是一种出色的语言,它对于想要“完成工作”并且不花很多时间在样板代码上的人来说是完美的语言。 Arcade是一个用于创建2D视频游戏的Python库,该库易于开始使用,并且在您获得经验时非常有能力。 在本文中,我将解释如何开始使用Python和Arcade对视频游戏进行编程。
在使用PyGame库教了学生之后,我开始在Arcade上进行开发。 我使用PyGame进行了近十年的现场教学,并开发了ProgramArcadeGames.com进行在线教学。 PyGame很棒,但是最终我觉得我在浪费时间去掩盖那些从未修复过的错误 。
我担心教诸如事件循环之类的事情 ,而这不再是我们编写代码的方式。 我在整个章节中解释了为什么将y坐标反转。 因为PyGame很少更新,并且它基于旧的SDL 1库,而不是像OpenGL这样的更现代的库,所以我对未来并不抱太大希望。
像许多其他软件包一样,可以通过PyPi使用Arcade,这意味着您可以使用pip
命令(或pipenv命令)安装Arcade。 如果您已经安装了Python,则可能只需在Windows上打开命令提示符并键入:
pip install arcade
或在MacOS和Linux上输入:
pip3 install arcade
有关更详细的安装说明,您可以参考Arcade安装文档 。
您可以打开一个窗口并仅需几行代码即可创建简单的图形。 让我们创建一个绘制笑脸的示例,如下图所示:
下面的脚本显示了如何使用Arcade的绘图命令来执行此操作。 注意,您不需要知道如何使用类 ,甚至不需要定义函数 。 带有快速视觉反馈的编程非常适合想要开始学习编程的任何人。
import arcade
# Set constants for the screen size
SCREEN_WIDTH
=
600
SCREEN_HEIGHT
=
600
# Open the window. Set the window title and dimensions (width and height)
arcade.
open_window
( SCREEN_WIDTH
, SCREEN_HEIGHT
,
"Drawing Example"
)
# Set the background color to white.
# For a list of named colors see:
# http://arcade.academy/arcade.color.html
# Colors can also be specified in (red, green, blue) format and
# (red, green, blue, alpha) format.
arcade.
set_background_color
( arcade.
color .
WHITE
)
# Start the render process. This must be done before any drawing commands.
arcade.
start_render
(
)
# Draw the face
x
=
300
y
=
300
radius
=
200
arcade.
draw_circle_filled
( x
, y
, radius
, arcade.
color .
YELLOW
)
# Draw the right eye
x
=
370
y
=
350
radius
=
20
arcade.
draw_circle_filled
( x
, y
, radius
, arcade.
color .
BLACK
)
# Draw the left eye
x
=
230
y
=
350
radius
=
20
arcade.
draw_circle_filled
( x
, y
, radius
, arcade.
color .
BLACK
)
# Draw the smile
x
=
300
y
=
280
width
=
120
height
=
100
start_angle
=
190
end_angle
=
350
arcade.
draw_arc_outline
( x
, y
, width
, height
, arcade.
color .
BLACK
, start_angle
, end_angle
,
10
)
# Finish drawing and display the result
arcade.
finish_render
(
)
# Keep the window open until the user hits the 'close' button
arcade.
run
(
)
当然,在全局上下文中编写代码不是一种好形式。 值得庆幸的是,通过使用函数来改进程序很容易。 在这里,我们可以看到使用函数在特定(x,y)位置绘制松树的示例:
def draw_pine_tree
( x
, y
) :
""" This function draws a pine tree at the specified location. """
# Draw the triangle on top of the trunk.
# We need three x, y points for the triangle.
arcade.
draw_triangle_filled
( x +
40
, y
,
# Point 1
x
, y -
100
,
# Point 2
x +
80
, y -
100
,
# Point 3
arcade.
color .
DARK_GREEN
)
# Draw the trunk
arcade.
draw_lrtb_rectangle_filled
( x +
30
, x +
50
, y -
100
, y -
140
,
arcade.
color .
DARK_BROWN
)
有关完整示例,请参见带有功能的图纸 。
经验更丰富的程序员将知道,现代图形程序首先将图形信息加载到图形卡上,然后要求图形卡稍后批量绘制。 Arcade也支持这一点。 分别绘制10,000个矩形大约需要0.800秒。 批量提取它们只需不到0.001秒的时间。
较大的程序通常会从Window类派生,或使用装饰器 。 这使程序员可以编写代码来处理绘图,更新和处理来自用户的输入。 下面是用于启动基于Window
的程序的模板。
import arcade
SCREEN_WIDTH
=
800
SCREEN_HEIGHT
=
600
class MyGame
( arcade.
Window
) :
""" Main application class. """
def
__init__
(
self
, width
, height
) :
super
(
) .
__init__
( width
, height
)
arcade.
set_background_color
( arcade.
color .
AMAZON
)
def setup
(
self
) :
# Set up your game here
pass
def on_draw
(
self
) :
""" Render the screen. """
arcade.
start_render
(
)
# Your drawing code goes here
def update
(
self
, delta_time
) :
""" All the logic to move, and the game logic goes here. """
pass
def main
(
) :
game
= MyGame
( SCREEN_WIDTH
, SCREEN_HEIGHT
)
game.
setup
(
)
arcade.
run
(
)
if __name__
==
"__main__" :
main
(
)
Window
类具有几种方法,您的程序可以覆盖这些方法来为程序提供功能。 以下是一些最常用的方法:
on_draw
:所有绘制屏幕的代码都在这里。 update
:所有用于移动物品并执行游戏逻辑的代码都在此处。 每秒大约称为60次。 on_key_press
:按下按键时处理事件,例如为玩家提供速度。 on_key_release
:释放键时处理,在这里您可能会阻止播放器移动。 on_mouse_motion
:每次鼠标移动时都会调用它。 on_mouse_press
:按下鼠标按钮时调用。 set_viewport
:当您拥有比一个屏幕上可以看到的世界大得多的世界时,此功能可用于滚动游戏。 调用set_viewport
允许程序员设置该世界的哪个部分当前可见。 Sprite是在Arcade中创建2D位图对象的简单方法。 Arcade的方法可以轻松绘制,移动和设置精灵动画。 您还可以轻松地使用精灵检测对象之间的碰撞。
从图形创建Arcade Sprite类的实例很容易。 程序员只需要图像的文件名即可基于其精灵,还可以选择一个数字来按比例放大或缩小图像。 例如:
SPRITE_SCALING_COIN
=
0.2
coin
= arcade.
Sprite
(
"coin_01.png"
, SPRITE_SCALING_COIN
)
这段代码将使用存储在coin_01.png
的图像创建一个精灵。 图像将缩小到其原始高度和宽度的20%。
精灵通常被组织成列表。 这些列表使管理精灵更加容易。 列表中的精灵将使用OpenGL批量绘制精灵。 下面的代码设置了一个具有玩家的游戏,以及一堆硬币供玩家收集。 我们使用两个列表,一个用于玩家,一个用于硬币。
def setup
(
self
) :
""" Set up the game and initialize the variables. """
# Create the sprite lists
self .
player_list
= arcade.
SpriteList
(
)
self .
coin_list
= arcade.
SpriteList
(
)
# Score
self .
score
=
0
# Set up the player
# Character image from kenney.nl
self .
player_sprite
= arcade.
Sprite
(
"images/character.png"
, SPRITE_SCALING_PLAYER
)
self .
player_sprite .
center_x
=
50
# Starting position
self .
player_sprite .
center_y
=
50
self .
player_list .
append
(
self .
player_sprite
)
# Create the coins
for i
in
range
( COIN_COUNT
) :
# Create the coin instance
# Coin image from kenney.nl
coin
= arcade.
Sprite
(
"images/coin_01.png"
, SPRITE_SCALING_COIN
)
# Position the coin
coin.
center_x
=
random .
randrange
( SCREEN_WIDTH
)
coin.
center_y
=
random .
randrange
( SCREEN_HEIGHT
)
# Add the coin to the lists
self .
coin_list .
append
( coin
)
我们可以轻松地绘制硬币列表中的所有硬币:
def on_draw
(
self
) :
""" Draw everything """
arcade.
start_render
(
)
self .
coin_list .
draw
(
)
self .
player_list .
draw
(
)
函数check_for_collision_with_list
允许我们查看一个精灵是否运行到列表中的另一个精灵。 我们可以使用它来查看玩家精灵与之接触的所有硬币。 使用简单的for
循环,我们可以摆脱游戏中的硬币并提高得分。
def update
(
self
, delta_time
) :
# Generate a list of all coin sprites that collided with the player.
coins_hit_list
= arcade.
check_for_collision_with_list
(
self .
player_sprite
,
self .
coin_list
)
# Loop through each colliding sprite, remove it, and add to the score.
for coin
in coins_hit_list:
coin.
kill
(
)
self .
score +
=
1
有关完整示例,请参见collect_coins.py 。
许多游戏都包含某种物理学。 最简单的是自上而下的程序,可防止播放器穿过墙壁。 平台开发人员通过重力和移动平台增加了更多的复杂性。 有些游戏使用具有质量,摩擦力,弹簧等的完整2D物理引擎。
对于简单的自上而下的游戏,街机程序需要玩家(或其他任何人)无法穿过的墙壁列表。 我通常将其称为wall_list
。 然后在Window
类的设置代码中使用以下命令创建一个物理引擎:
self .
physics_engine
= arcade.
PhysicsEngineSimple
(
self .
player_sprite
,
self .
wall_list
)
给player_sprite
一个运动矢量,它具有两个属性change_x
和change_y
。 一个简单的例子就是让玩家随键盘移动。 例如,这可能在Window
类的自定义子级中:
MOVEMENT_SPEED
=
5
def on_key_press
(
self
, key
, modifiers
) :
"""Called whenever a key is pressed. """
if key
== arcade.
key .
UP :
self .
player_sprite .
change_y
= MOVEMENT_SPEED
elif key
== arcade.
key .
DOWN :
self .
player_sprite .
change_y
= -MOVEMENT_SPEED
elif key
== arcade.
key .
LEFT :
self .
player_sprite .
change_x
= -MOVEMENT_SPEED
elif key
== arcade.
key .
RIGHT :
self .
player_sprite .
change_x
= MOVEMENT_SPEED
def on_key_release
(
self
, key
, modifiers
) :
"""Called when the user releases a key. """
if key
== arcade.
key .
UP
or key
== arcade.
key .
DOWN :
self .
player_sprite .
change_y
=
0
elif key
== arcade.
key .
LEFT
or key
== arcade.
key .
RIGHT :
self .
player_sprite .
change_x
=
0
尽管该代码设置了播放器的速度,但它不会移动播放器。 在Window
类的update
方法中,调用physics_engine.update()
将移动播放器,但不会移动穿过墙壁。
def update
(
self
, delta_time
) :
""" Movement and game logic """
self .
physics_engine .
update
(
)
有关完整示例,请参见sprite_move_walls.py 。
移至侧视图Platformer相当容易。 程序员只需要将物理引擎切换到PhysicsEnginePlatformer
并添加重力常数即可。
self .
physics_engine
= arcade.
PhysicsEnginePlatformer
(
self .
player_sprite
,
self .
wall_list
,
gravity_constant
= GRAVITY
)
您可以使用Tiled之类的程序来放置构成关卡的图块/块。
有关示例,请参见sprite_tiled_map.py 。
对于完整的2D物理,您可以集成PyMunk库。
最好的学习方法之一就是以身作则。 Arcade库中有很多示例程序 ,人们可以借鉴这些示例程序来创建游戏。 这些示例均显示了多年来学生在我的课堂或在线上要求的游戏概念。
安装Arcade后,运行这些演示中的任何一个都非常容易。 每个样本在程序的开头都有注释,您可以在命令行上键入以下命令来运行样本,例如:
python -m arcade.examples.sprite_moving_platforms
Arcade使您可以使用易于理解的代码开始对图形和游戏进行编程。 许多新的程序员起步不久就创造了出色的游戏 。 试试看!
要了解更多信息,请在2018年PyCon克利夫兰参加Paul Vincent Craven的演讲`` 使用Arcade轻松进行2D游戏创作'' 。
翻译自: https://opensource.com/article/18/4/easy-2d-game-creation-python-and-arcade
arcade 物理系统