步骤4-添加重力
之前的例子对上上下下的效果很好,但是如果是带有跳跃的侧视图呢?我们需要增加重力。
下面的示例将允许用户在平台上跳跃和行走。
"""Platformer Game04_add_gravity.py - 添加重力"""
import arcade
# 定义常量,屏幕的宽、高和标题
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 650
SCREEN_TITLE = "Platformer"
# 用于缩放精灵原始大小的常数
CHARACTER_SCALING = 1
TILE_SCALING = 0.5
COIN_SCALING = 0.5
# 玩家的移动速度、重力以及跳跃速度,以每帧像素为单位
PLAYER_MOVEMENT_SPEED = 5
GRAVITY = 1
PLAYER_JUMP_SPEED = 20
class MyGame(arcade.Window):
"""封装成的主类"""
def __init__(self):
# 初始化父类并设置窗口
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
# 这些是跟踪我们精灵的“列表”。每个精灵应该
# 被放入列表.
self.coin_list = None
self.wall_list = None
self.player_list = None
# 保存玩家精灵的单独变量
self.player_sprite = None
# 我们的物理引擎
self.physics_engine = None
arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)
def setup(self):
""" 在这里设置游戏。调用此函数重新启动游戏. """
# 创建精灵列表
self.player_list = arcade.SpriteList()
self.wall_list = arcade.SpriteList()
self.coin_list = arcade.SpriteList()
# 设置玩家,注意将其放置在指定坐标处.
image_source = "images/player_1/player_stand.png"
self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING)
self.player_sprite.center_x = 64
self.player_sprite.center_y = 128
self.player_list.append(self.player_sprite)
# 创建背景
# 这显示了如何使用循环水平放置多个精灵
for x in range(0, 1250, 64):
wall = arcade.Sprite("images/tiles/grassMid.pngg", TILE_SCALING)
wall.center_x = x
wall.center_y = 32
self.wall_list.append(wall)
# 把一些板条箱放在地上
# 这显示了如何使用坐标列表来放置精灵
coordinate_list = [[512, 96],
[256, 96],
[768, 96]]
for coordinate in coordinate_list:
# 添加一个地板
wall = arcade.Sprite("images/tiles/boxCrate_double.png", TILE_SCALING)
wall.position = coordinate
self.wall_list.append(wall)
# 添加物理引擎
self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite,
self.wall_list,
GRAVITY)
def on_draw(self):
""" 渲染屏幕 """
# 将屏幕设置为背景色
arcade.start_render()
# 画出我们的精灵
self.wall_list.draw()
self.coin_list.draw()
self.player_list.draw()
def on_key_press(self, key, modifiers):
"""每当按下键时调用 . """
if key == arcade.key.UP or key == arcade.key.W:
if self.physics_engine.can_jump():
self.player_sprite.change_y = PLAYER_JUMP_SPEED
elif key == arcade.key.LEFT or key == arcade.key.A:
self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
elif key == arcade.key.RIGHT or key == arcade.key.D:
self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
def on_key_release(self, key, modifiers):
"""每当释放键时调用. """
elif key == arcade.key.LEFT or key == arcade.key.A:
self.player_sprite.change_x = 0
elif key == arcade.key.RIGHT or key == arcade.key.D:
self.player_sprite.change_x = 0
def on_update(self, delta_time):
""" 移动画面与游戏逻辑 """
# 用物理引擎移动玩家
self.physics_engine.update()
def main():
""" 主函数,大佬们往往把功能封装成类在main函数里写测试的代码,如果直接运行该脚本就会运行测试"""
window = MyGame()
window.setup()
arcade.run()
if __name__ == "__main__":
main()
备注:您可以通过更改重力和跳跃常数来更改用户跳跃的方式。两者的值越低,人物就越“浮动”。值越高,游戏节奏越快。
步骤5-添加滚动
通过添加滚动功能,我们可以让一个小的视窗,进入一个更大的世界。
在相机开始滚动之前,视野边距控制是通过和屏幕边缘的距离。
"""
Platformer Game
05_scrolling.py - 添加滚动
"""
import arcade
# 定义常量,屏幕的宽、高和标题
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 650
SCREEN_TITLE = "Platformer"
# 用于缩放精灵原始大小的常数
CHARACTER_SCALING = 1
TILE_SCALING = 0.5
COIN_SCALING = 0.5
# 玩家的移动速度、重力以及跳跃速度,以每帧像素为单位
PLAYER_MOVEMENT_SPEED = 5
GRAVITY = 1
PLAYER_JUMP_SPEED = 20
# 在人物和游戏边框之间保留多少像素作为最小边距
# 就是人物不能太靠近边框,太近就该移动摄像头了
LEFT_VIEWPORT_MARGIN = 250
RIGHT_VIEWPORT_MARGIN = 250
BOTTOM_VIEWPORT_MARGIN = 50
TOP_VIEWPORT_MARGIN = 100
class MyGame(arcade.Window):
"""
封装成的主类
"""
def __init__(self):
# 初始化父类并设置窗口
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
# 这些是跟踪我们精灵的“列表”。每个精灵应该
# 被放入列表.
self.coin_list = None
self.wall_list = None
self.player_list = None
# 保存玩家精灵的单独变量
self.player_sprite = None
# 我们的物理引擎
self.physics_engine = None
# 用来跟踪我们的滚动
self.view_bottom = 0
self.view_left = 0
arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)
def setup(self):
""" 在这里设置游戏。调用此函数重新启动游戏. """
# 用来跟踪我们的滚动
self.view_bottom = 0
self.view_left = 0
# 创建精灵列表
self.player_list = arcade.SpriteList()
self.wall_list = arcade.SpriteList()
self.coin_list = arcade.SpriteList()
# 设置玩家,注意将其放置在指定坐标处.
image_source = "images/player_1/player_stand.png"
self.player_sprite = arcade.Sprite(image_source, CHARACTER_SCALING)
self.player_sprite.center_x = 64
self.player_sprite.center_y = 128
self.player_list.append(self.player_sprite)
# 创建背景
# 这显示了如何使用循环水平放置多个精灵
for x in range(0, 1250, 64):
wall = arcade.Sprite("images/tiles/grassMid.pngg", TILE_SCALING)
wall.center_x = x
wall.center_y = 32
self.wall_list.append(wall)
# 把一些板条箱放在地上
# 这显示了如何使用坐标列表来放置精灵
coordinate_list = [[512, 96],
[256, 96],
[768, 96]]
for coordinate in coordinate_list:
# 添加一个地板
wall = arcade.Sprite("images/tiles/boxCrate_double.png", TILE_SCALING)
wall.position = coordinate
self.wall_list.append(wall)
# 添加物理引擎
self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite,
self.wall_list,
GRAVITY)
def on_draw(self):
""" 渲染屏幕 """
# 将屏幕设置为背景色
arcade.start_render()
# 画出我们的精灵
self.wall_list.draw()
self.coin_list.draw()
self.player_list.draw()
def on_key_press(self, key, modifiers):
"""每当按下键时调用 . """
if key == arcade.key.UP or key == arcade.key.W:
if self.physics_engine.can_jump():
self.player_sprite.change_y = PLAYER_JUMP_SPEED
elif key == arcade.key.LEFT or key == arcade.key.A:
self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED
elif key == arcade.key.RIGHT or key == arcade.key.D:
self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED
def on_key_release(self, key, modifiers):
"""每当释放键时调用. """
elif key == arcade.key.LEFT or key == arcade.key.A:
self.player_sprite.change_x = 0
elif key == arcade.key.RIGHT or key == arcade.key.D:
self.player_sprite.change_x = 0
def on_update(self, delta_time):
""" 移动画面与游戏逻辑 """
# 用物理引擎移动玩家
self.physics_engine.update()
# --- 实现画面滚动 ---
# 跟踪是否需要更改视区
changed = False
# 向左滚
left_boundary = self.view_left + LEFT_VIEWPORT_MARGIN
if self.player_sprite.left < left_boundary:
self.view_left -= left_boundary - self.player_sprite.left
changed = True
# 向右滚
right_boundary = self.view_left + SCREEN_WIDTH - RIGHT_VIEWPORT_MARGIN
if self.player_sprite.right > right_boundary:
self.view_left += self.player_sprite.right - right_boundary
changed = True
# 向上滚
top_boundary = self.view_bottom + SCREEN_HEIGHT - TOP_VIEWPORT_MARGIN
if self.player_sprite.top > top_boundary:
self.view_bottom += self.player_sprite.top - top_boundary
changed = True
# 向下滚
bottom_boundary = self.view_bottom + BOTTOM_VIEWPORT_MARGIN
if self.player_sprite.bottom < bottom_boundary:
self.view_bottom -= bottom_boundary - self.player_sprite.bottom
changed = True
if changed:
# 只滚动到整数。否则我们最终得到的像素不会在屏幕上显示
self.view_bottom = int(self.view_bottom)
self.view_left = int(self.view_left)
# 滚
arcade.set_viewport(self.view_left,
SCREEN_WIDTH + self.view_left,
self.view_bottom,
SCREEN_HEIGHT + self.view_bottom)
def main():
""" 主函数,大佬们往往把功能封装成类
在main函数里写测试的代码,如果直接运行该脚本就会运行测试
"""
window = MyGame()
window.setup()
arcade.run()
if __name__ == "__main__":
main()