第7步-添加摄像头#

现在我们的玩家可以移动和跳跃,我们需要给他们一种方法来探索原始窗口之外的世界。如果你玩过平台游戏,你可能对屏幕滚动的概念很熟悉,当玩家移动时,屏幕滚动可以显示更多的地图。

为了实现这一点,我们可以使用摄像头,Arade提供了 arcade.SimpleCameraarcade.Camera 。它们都有相同的基本功能,但Camera有一些SimpleCamera没有的额外功能。目前,我们只使用SimpleCamera。

首先,让我们继续并在我们的 __init__ 用于保持它的函数:

self.camera = None

接下来,我们可以转到设置函数,并按如下方式对其进行初始化:

self.camera = arcade.SimpleCamera(viewport=(0, 0, self.width, self.height))

这个 viewport 此处的参数定义了摄像机的大小。在大多数情况下,您会希望这是您的窗口大小。因此,我们将摄影机视口中的底部和左侧坐标指定为(0,0),并为其提供窗口的宽度和高度。

为了在将东西绘制到屏幕上时使用我们的相机,我们只需要在 on_draw 功能。这条线通常应该出现在您要用相机绘制的任何内容之前。在后面的章节中,我们将探索使用多个摄像头在不同位置绘制物体。在绘制SpriteList之前,请继续添加此行

self.camera.use()

如果你在这一点上运行游戏,你可能会注意到什么都没有改变,我们的游戏仍然是一个静止不动的屏幕。这是因为我们永远不会更新相机的位置。在我们的Platform游戏中,我们希望摄像头跟随玩家,并将他们保持在屏幕的中心。Arade提供了一个有用的函数,只需一行代码即可完成此任务。在其他类型的游戏或更高级的用法中,您可能想要直接设置摄像头的位置以创建有趣的效果,但目前我们所需要的是 center() 我们的相机的功能。

如果我们将以下行添加到我们的 on_update() 功能和运行游戏,你现在应该看到玩家停留在屏幕的中心,同时能够滚动屏幕到我们地图的其余部分。有趣的是,看看如果你从地图上掉下来会发生什么!稍后,我们将重温一种更先进的相机设置,它将考虑到我们世界的边界。

self.camera.center(self.player_sprite.position)

源代码#

添加摄像头#
  1"""
  2Platformer Game
  3
  4python -m arcade.examples.platform_tutorial.07_camera
  5"""
  6import arcade
  7
  8# Constants
  9SCREEN_WIDTH = 800
 10SCREEN_HEIGHT = 600
 11SCREEN_TITLE = "Platformer"
 12
 13# Constants used to scale our sprites from their original size
 14TILE_SCALING = 0.5
 15
 16# Movement speed of player, in pixels per frame
 17PLAYER_MOVEMENT_SPEED = 5
 18GRAVITY = 1
 19PLAYER_JUMP_SPEED = 20
 20
 21
 22class MyGame(arcade.Window):
 23    """
 24    Main application class.
 25    """
 26
 27    def __init__(self):
 28
 29        # Call the parent class and set up the window
 30        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
 31
 32        # Variable to hold our texture for our player
 33        self.player_texture = None
 34
 35        # Separate variable that holds the player sprite
 36        self.player_sprite = None
 37
 38        # SpriteList for our player
 39        self.player_list = None
 40
 41        # SpriteList for our boxes and ground
 42        # Putting our ground and box Sprites in the same SpriteList
 43        # will make it easier to perform collision detection against
 44        # them later on. Setting the spatial hash to True will make
 45        # collision detection much faster if the objects in this
 46        # SpriteList do not move.
 47        self.wall_list = None
 48
 49        # A variable to store our camera object
 50        self.camera = None
 51
 52    def setup(self):
 53        """Set up the game here. Call this function to restart the game."""
 54        self.player_texture = arcade.load_texture(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png")
 55
 56        self.player_sprite = arcade.Sprite(self.player_texture)
 57        self.player_sprite.center_x = 64
 58        self.player_sprite.center_y = 128
 59
 60        self.player_list = arcade.SpriteList()
 61        self.player_list.append(self.player_sprite)
 62
 63        self.wall_list = arcade.SpriteList(use_spatial_hash=True)
 64
 65        # Create the ground
 66        # This shows using a loop to place multiple sprites horizontally
 67        for x in range(0, 1250, 64):
 68            wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=TILE_SCALING)
 69            wall.center_x = x
 70            wall.center_y = 32
 71            self.wall_list.append(wall)
 72
 73        # Put some crates on the ground
 74        # This shows using a coordinate list to place sprites
 75        coordinate_list = [[512, 96], [256, 96], [768, 96]]
 76
 77        for coordinate in coordinate_list:
 78            # Add a crate on the ground
 79            wall = arcade.Sprite(
 80                ":resources:images/tiles/boxCrate_double.png", scale=TILE_SCALING
 81            )
 82            wall.position = coordinate
 83            self.wall_list.append(wall)
 84
 85        # Create a Platformer Physics Engine, this will handle moving our
 86        # player as well as collisions between the player sprite and
 87        # whatever SpriteList we specify for the walls.
 88        # It is important to supply static to the walls parameter. There is a
 89        # platforms parameter that is intended for moving platforms.
 90        # If a platform is supposed to move, and is added to the walls list,
 91        # it will not be moved.
 92        self.physics_engine = arcade.PhysicsEnginePlatformer(
 93            self.player_sprite, walls=self.wall_list, gravity_constant=GRAVITY
 94        )
 95
 96        # Initialize our camera, setting a viewport the size of our window.
 97        self.camera = arcade.camera.Camera2D()
 98
 99        self.background_color = arcade.csscolor.CORNFLOWER_BLUE
100
101    def on_draw(self):
102        """Render the screen."""
103
104        # Clear the screen to the background color
105        self.clear()
106
107        # Activate our camera before drawing
108        self.camera.use()
109
110        # Draw our sprites
111        self.player_list.draw()
112        self.wall_list.draw()
113
114    def on_update(self, delta_time):
115        """Movement and Game Logic"""
116
117        # Move the player using our physics engine
118        self.physics_engine.update()
119
120        # Center our camera on the player
121        self.camera.position = self.player_sprite.position
122
123    def on_key_press(self, key, modifiers):
124        """Called whenever a key is pressed."""
125
126        if key == arcade.key.ESCAPE:
127            self.setup()
128
129        if key == arcade.key.UP or key == arcade.key.W:
130            if self.physics_engine.can_jump():
131                self.player_sprite.change_y = PLAYER_JUMP_SPEED
132
133        if key == arcade.key.LEFT or key == arcade.key.A:
134            self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
135        elif key == arcade.key.RIGHT or key == arcade.key.D:
136            self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
137
138    def on_key_release(self, key, modifiers):
139        """Called whenever a key is released."""
140
141        if key == arcade.key.LEFT or key == arcade.key.A:
142            self.player_sprite.change_x = 0
143        elif key == arcade.key.RIGHT or key == arcade.key.D:
144            self.player_sprite.change_x = 0
145
146
147def main():
148    """Main function"""
149    window = MyGame()
150    window.setup()
151    arcade.run()
152
153
154if __name__ == "__main__":
155    main()

运行本章#

python -m arcade.examples.platform_tutorial.07_camera