领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

如何使用Python和Arcade库创建2D游戏

nixiaole 2025-01-02 18:13:28 知识剖析 20 ℃

了解如何开始使用Arcade,这是一个易于使用的Python库,用于创建2D视频游戏。

对于学习编程的人来说,Python是一种出色的语言,对于那些希望“完成工作”而不想在样板代码上花费大量时间的人来说,Python是一种完美的语言。Arcade是一个用于创建2D视频游戏的Python库,它很容易开始使用,并且当你获得经验时非常有能力。在本文中,我将解释如何开始使用Python和Arcade来编写视频游戏。

安装

像许多其他软件包一样,可以通过PyPi使用Arcade,这意味着您可以使用pip命令(或pipenv命令)安装Arcade。如果您已经安装了Python,则可能只需在Windows上打开命令提示符并键入:

pip install arcade

或在MacOS和Linux上输入:

pip3 install arcade

有关更详细的安装说明,您可以参考Arcade安装文档(链接:http://arcade.academy/installation.html)。

简单绘图

您可以打开一个窗口,用几行代码创建简单的图形。让我们创建一个绘制笑脸的示例,如下图所示:

下面的脚本显示了如何使用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)

有关完整示例,请参见drawing with functions(链接:http://arcade.academy/examples/drawing_with_functions.html)。

经验更丰富的程序员会知道,现代图形程序会先将图形信息加载到图形卡上,然后再要求图形卡稍后批量绘制。Arcade也支持这一点。分别绘制10,000个矩形大约需要0.800秒。批量提取它们只需不到0.001秒的时间。

Window类

较大的程序通常将从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允许程序员设置当前可见的部分。

Sprites

Sprite是在Arcade中创建2D位图对象的简单方法。Arcade的方法可以轻松绘制、移动和设置精灵动画。您还可以轻松地使用sprites检测对象之间的碰撞。

1)创建一个精灵(sprite)

从图形创建Arcade Sprite类的实例很容易。程序员只需要图像的文件名即可基于sprite生成图像,还可以选择一个数字来按比例放大或缩小图像。例如:

SPRITE_SCALING_COIN = 0.2

coin = arcade.Sprite("coin_01.png", SPRITE_SCALING_COIN)

这段代码将使用存储在coin_01.png中的图像创建一个精灵。图像将缩小到原始高度和宽度的20%。

2)精灵列表(Sprite lists)

精灵通常被组织成列表。这些列表使管理精灵更加容易。列表中的精灵将使用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()

3)探测sprite碰撞

函数check_for_collision_with_list允许我们查看一个sprite是否遇到列表中的另一个sprite。我们可以使用它来查看玩家精灵与之接触的所有硬币。使用简单的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(链接:http://arcade.academy/examples/sprite_collect_coins.html)。

游戏物理学(Game physics)

许多游戏都包含某种物理原理。最简单的是自上而下的程序,它可以防止玩家穿过墙壁。有些游戏使用完整的2D物理引擎,包括质量、摩擦力、弹簧等。

1)自上而下的游戏(Top-down games)

对于基于自上而下的简单游戏,Arcade程序需要列出玩家(或其他任何人)无法穿过的墙壁列表,通常将其称为wall_list。然后在Window类的设置代码中使用以下命令创建一个物理引擎:

self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list)

给player_sprite一个运动向量,它有两个属性change_x和change_y。一个简单的例子就是让玩家随着键盘移动。例如,这可能在窗口类的自定义子类中:

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(链接:http://arcade.academy/examples/sprite_move_walls.html)。

2)平台游戏(Platformers)

移动到侧视图平台是相当容易的。程序员只需将物理引擎切换到PhysicsEnginePlatformer并添加重力常数。

self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite,
                                                     self.wall_list,
                                                     gravity_constant=GRAVITY)

您可以使用Tiled之类的程序来放置构成关卡的图块/块。

有关示例,请参见sprite_tiled_map.py(链接:http://arcade.academy/examples/sprite_tiled_map.html)。

对于完整的2D物理,您可以集成PyMunk库(链接:http://arcade.academy/examples/pymunk_platformer.html#pymunk-platformer)。

通过例子学习

Arcade库中有很多示例程序,人们可以借鉴这些示例程序来创建游戏。

安装Arcade后,运行这些演示中的任何一个都非常容易。每个示例在程序的开头都有一个注释,您可以在命令行上键入以下命令来运行该示例,例如:

python -m arcade.examples.sprite_moving_platforms

总结

Arcade使您可以使用易于理解的代码开始对图形和游戏进行编程。 许多新的程序员起步不久就创造了出色的游戏。试试看吧!

最近发表
标签列表