"""arcade 带屏幕滚动的角色移动游戏.py ,使用方向箭头控制角色,背景会滚动,适合于大地图类游戏。
"""
import random
import arcade
import os
SPRITE_SCALING = 0.5
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "带屏幕滚动的角色移动游戏"
# 当角色到达屏幕边缘时与边的距离
VIEWPORT_MARGIN = 40
MOVEMENT_SPEED = 5
class MyGame(arcade.Window):
"""主应用程序类. """
def __init__(self, width, height, title):
"""
初始化方法
"""
super().__init__(width, height, title)
# 新建角色列表
self.player_list = None
self.coin_list = None
# 设置玩家
self.score = 0
self.player_sprite = None
self.wall_list = None
self.physics_engine = None
self.view_bottom = 0
self.view_left = 0
def setup(self):
""" 设置游戏和初始化变量. """
# 新建角色列表
self.player_list = arcade.SpriteList()
self.wall_list = arcade.SpriteList()
# 设置玩家操作的角色
self.score = 0
self.player_sprite = arcade.Sprite("images/character.png", 0.4)
self.player_sprite.center_x = 64
self.player_sprite.center_y = 270
self.player_list.append(self.player_sprite)
# -- 设置墙块
for x in range(200, 1650, 210):
for y in range(0, 1000, 64):
# 随机跳过一个方块,这样角色就能过去
if random.randrange(5) > 0:
wall = arcade.Sprite("images/boxCrate_double.png", SPRITE_SCALING)
wall.center_x = x
wall.center_y = y
self.wall_list.append(wall)
self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list)
# 设置背景颜色
arcade.set_background_color(arcade.color.AMAZON)
# 设置视区边界
# These numbers set where we have 'scrolled' to.
self.view_left = 0
self.view_bottom = 0
def on_draw(self):
"""
渲染屏幕
"""
# 画角色之前这个命令要先执行
arcade.start_render()
# 画所有的角色
self.wall_list.draw()
self.player_list.draw()
def on_key_press(self, key, modifiers):
"""按键时这个方法执行 """
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):
"""松开键时这个方法执行 """
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
def update(self, delta_time):
""" 移动与游戏逻辑"""
# 调用更新所有的角色 (在此例中角色无其它行为)
self.physics_engine.update()
# --- 管理滚动 ---
# 跟踪以决定是否需要改变社区
# arcade以左下角为坐标原点,y的最大值就是屏幕高度,x的最大值就是屏幕宽度。
changed = False
# Scroll left
left_bndry = self.view_left + VIEWPORT_MARGIN
if self.player_sprite.left < left_bndry:
self.view_left -= left_bndry - self.player_sprite.left
changed = True
# Scroll right
right_bndry = self.view_left + SCREEN_WIDTH - VIEWPORT_MARGIN
if self.player_sprite.right > right_bndry:
self.view_left += self.player_sprite.right - right_bndry
changed = True
# Scroll up
top_bndry = self.view_bottom + SCREEN_HEIGHT - VIEWPORT_MARGIN
if self.player_sprite.top > top_bndry:
self.view_bottom += self.player_sprite.top - top_bndry
changed = True
# Scroll down
bottom_bndry = self.view_bottom + VIEWPORT_MARGIN
if self.player_sprite.bottom < bottom_bndry:
self.view_bottom -= bottom_bndry - self.player_sprite.bottom
changed = True
if changed: # 左视区最小值
arcade.set_viewport(self.view_left,
SCREEN_WIDTH + self.view_left, # 右视区最大值
self.view_bottom, # 下区最小值
SCREEN_HEIGHT + self.view_bottom)# 下区最大值
def main():
""" Main method """
window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
window.setup()
arcade.run()
if __name__ == "__main__":
main()