第5步-添加重力#
前面的例子对于自上而下的游戏来说是很棒的,但如果它是像我们的平台一样带有跳跃的侧视图呢?我们需要增加重力。首先,让我们定义一个常量来表示重力的加速度,一个常量来表示跳跃速度。
GRAVITY = 1
PLAYER_JUMP_SPEED = 20
现在,让我们更改我们在 __init__
函数设置为 arcade.PhysicsEnginePlatformer
而不是一个 arcade.PhysicsEngineSimple
。这个新的物理引擎将为我们处理跳跃和重力,并将在后面的章节中做更多的工作。
self.physics_engine = arcade.PhysicsEnginePlatformer(
self.player_sprite, walls=self.wall_list, gravity_constant=GRAVITY
)
这与我们最初创建简单物理引擎的方式非常相似,但有两个例外。首先,我们给它发来了我们的重力常数。第二个原因是我们已将Wall SpriteList显式发送到 walls
参数。这是非常重要的一步。Platform物理引擎有两个用于可碰撞对象的参数,其中一个名为 platforms
和一个名为 walls
。
不同之处在于发送到 platforms
是用来移动的。它们的移动方式与玩家相同,通过修改它们的 change_x
和 change_y
价值观。对象发送到 walls
参数将不会移动。这一点如此重要的原因是,不动的墙比可移动的平台具有更快的性能。
通过添加静态精灵 platforms
参数大致是一个O(N)运算,这意味着随着您添加更多的精灵,性能将线性下降。如果将静态精灵添加到 walls
参数,那么它几乎是O(1),并且例如100个和50,000个不移动的精灵之间基本上没有区别。
最后,我们将给我们的球员跳跃的能力。修改 on_key_press
和 on_key_release
功能。我们将删除以前的UP/DOWN语句,并使 UP
按下后跳跃。
if key == arcade.key.UP or key == arcade.key.W:
if self.physics_engine.can_jump():
self.player_sprite.change_y = PLAYER_JUMP_SPEED
这个 can_jump()
我们的物理引擎的检查将会成功,这样我们只有在接触地面时才能跳跃。您可以删除此功能,以允许跳到半空中以获得一些有趣的结果。想一想如何使用它来实现一个双跳系统。
备注
您可以通过更改重力和跳跃常量来更改用户的跳跃方式。两者的值越低,角色就越“漂浮”。值越高,游戏节奏越快。
源代码#
1"""
2Platformer Game
3
4python -m arcade.examples.platform_tutorial.05_add_gravity
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 = arcade.load_texture(":resources:images/animated_characters/female_adventurer/femaleAdventurer_idle.png")
34
35 # Separate variable that holds the player sprite
36 self.player_sprite = arcade.Sprite(self.player_texture)
37 self.player_sprite.center_x = 64
38 self.player_sprite.center_y = 128
39
40 # SpriteList for our player
41 self.player_list = arcade.SpriteList()
42 self.player_list.append(self.player_sprite)
43
44 # SpriteList for our boxes and ground
45 # Putting our ground and box Sprites in the same SpriteList
46 # will make it easier to perform collision detection against
47 # them later on. Setting the spatial hash to True will make
48 # collision detection much faster if the objects in this
49 # SpriteList do not move.
50 self.wall_list = arcade.SpriteList(use_spatial_hash=True)
51
52 # Create the ground
53 # This shows using a loop to place multiple sprites horizontally
54 for x in range(0, 1250, 64):
55 wall = arcade.Sprite(":resources:images/tiles/grassMid.png", scale=TILE_SCALING)
56 wall.center_x = x
57 wall.center_y = 32
58 self.wall_list.append(wall)
59
60 # Put some crates on the ground
61 # This shows using a coordinate list to place sprites
62 coordinate_list = [[512, 96], [256, 96], [768, 96]]
63
64 for coordinate in coordinate_list:
65 # Add a crate on the ground
66 wall = arcade.Sprite(
67 ":resources:images/tiles/boxCrate_double.png", scale=TILE_SCALING
68 )
69 wall.position = coordinate
70 self.wall_list.append(wall)
71
72 # Create a Platformer Physics Engine.
73 # This will handle moving our player as well as collisions between
74 # the player sprite and whatever SpriteList we specify for the walls.
75 # It is important to supply static platforms to the walls parameter. There is a
76 # platforms parameter that is intended for moving platforms.
77 # If a platform is supposed to move, and is added to the walls list,
78 # it will not be moved.
79 self.physics_engine = arcade.PhysicsEnginePlatformer(
80 self.player_sprite, walls=self.wall_list, gravity_constant=GRAVITY
81 )
82
83 self.background_color = arcade.csscolor.CORNFLOWER_BLUE
84
85 def setup(self):
86 """Set up the game here. Call this function to restart the game."""
87 pass
88
89 def on_draw(self):
90 """Render the screen."""
91
92 # Clear the screen to the background color
93 self.clear()
94
95 # Draw our sprites
96 self.player_list.draw()
97 self.wall_list.draw()
98
99 def on_update(self, delta_time):
100 """Movement and Game Logic"""
101
102 # Move the player using our physics engine
103 self.physics_engine.update()
104
105 def on_key_press(self, key, modifiers):
106 """Called whenever a key is pressed."""
107
108 if key == arcade.key.UP or key == arcade.key.W:
109 if self.physics_engine.can_jump():
110 self.player_sprite.change_y = PLAYER_JUMP_SPEED
111
112 if key == arcade.key.LEFT or key == arcade.key.A:
113 self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
114 elif key == arcade.key.RIGHT or key == arcade.key.D:
115 self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
116
117 def on_key_release(self, key, modifiers):
118 """Called whenever a key is released."""
119
120 if key == arcade.key.LEFT or key == arcade.key.A:
121 self.player_sprite.change_x = 0
122 elif key == arcade.key.RIGHT or key == arcade.key.D:
123 self.player_sprite.change_x = 0
124
125
126def main():
127 """Main function"""
128 window = MyGame()
129 window.setup()
130 arcade.run()
131
132
133if __name__ == "__main__":
134 main()
运行本章#
python -m arcade.examples.platform_tutorial.05_add_gravity