有敌人的平台游戏演示

"""
有敌人的平台游戏演示
"""

import arcade
import os

SPRITE_SCALING = 0.5
SPRITE_NATIVE_SIZE = 128
SPRITE_SIZE = int(SPRITE_NATIVE_SIZE * SPRITE_SCALING)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "有敌人的平台游戏演示"

 
# Physics
MOVEMENT_SPEED = 5
JUMP_SPEED = 14
GRAVITY = 0.5


class MyGame(arcade.Window):
    """ Main application class. """

    def __init__(self):
        """
        Initializer
        """
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)

        # 角色列表定义
        self.wall_list = None
        self.enemy_list = None
        self.player_list = None

        # 玩家的相关属性定义
        self.player_sprite = None
        self.physics_engine = None
        self.view_left = 0
        self.view_bottom = 0
        self.game_over = False

    def setup(self):
        """ Set up the game and initialize the variables. """

        # 角色列表定义
        self.wall_list = arcade.SpriteList()
        self.enemy_list = arcade.SpriteList()
        self.player_list = arcade.SpriteList()

        # 实例化地面
        for x in range(0, SCREEN_WIDTH, SPRITE_SIZE):
            wall = arcade.Sprite("images/grassMid.png", SPRITE_SCALING)

            wall.bottom = 0
            wall.left = x
            self.wall_list.append(wall)

        # 画墙
        for x in range(SPRITE_SIZE * 3, SPRITE_SIZE* 8, SPRITE_SIZE):
            wall = arcade.Sprite("images/grassMid.png", SPRITE_SCALING)

            wall.bottom = SPRITE_SIZE * 3
            wall.left = x
            self.wall_list.append(wall)

        # 实例化箱子
        for x in range(0, SCREEN_WIDTH, SPRITE_SIZE * 5):
            wall = arcade.Sprite("images/boxCrate_double.png", SPRITE_SCALING)

            wall.bottom = SPRITE_SIZE
            wall.left = x
            self.wall_list.append(wall)

        # 实例化一个地上的敌人
        enemy = arcade.Sprite("images/wormGreen.png", SPRITE_SCALING)

        enemy.bottom = SPRITE_SIZE
        enemy.left = SPRITE_SIZE * 2

        # 设置敌人的初始速度
        enemy.change_x = 2
        self.enemy_list.append(enemy)

        # 实例化一个敌人角色
        enemy = arcade.Sprite("images/wormGreen.png", SPRITE_SCALING)

        enemy.bottom = SPRITE_SIZE * 4
        enemy.left = SPRITE_SIZE * 4

        # 设置敌人的左右边界
        enemy.boundary_right = SPRITE_SIZE * 8
        enemy.boundary_left = SPRITE_SIZE * 3
        enemy.change_x = 2
        self.enemy_list.append(enemy)

        # 实例化玩家
        self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING)
        self.player_list.append(self.player_sprite)

        # 玩家角色的起始坐标
        self.player_sprite.center_x = 64
        self.player_sprite.center_y = 270

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

        # Set the background color
        arcade.set_background_color(arcade.color.AMAZON)

    def on_draw(self):
        """
        渲染屏幕
        """

        # 开始渲染
        arcade.start_render()

        # 画所有的角色
        self.player_list.draw()
        self.wall_list.draw()
        self.enemy_list.draw()


    def on_key_press(self, key, modifiers):
        """
        按键时调用此方法
        """
        if key == arcade.key.UP:
            if self.physics_engine.can_jump():
                self.player_sprite.change_y = JUMP_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.LEFT or key == arcade.key.RIGHT:
            self.player_sprite.change_x = 0

    def update(self, delta_time):
        """ Movement and game logic """

        # Update the player based on the physics engine
        if not self.game_over:
            # Move the enemies
            self.enemy_list.update()

            # 检测每个敌人是否碰到墙
            for enemy in self.enemy_list:
                # If the enemy hit a wall, reverse
                if len(arcade.check_for_collision_with_list(enemy, self.wall_list)) > 0:
                    enemy.change_x *= -1
                # 如果碰到左边界把change_x也取反
                elif enemy.boundary_left is not None and enemy.left < enemy.boundary_left:
                    enemy.change_x *= -1
                # 如果碰到右边界把change_x也取反
                elif enemy.boundary_right is not None and enemy.right > enemy.boundary_right:
                    enemy.change_x *= -1

            # 使用物理引擎更新玩家和墙
            self.physics_engine.update()

            # See if the player hit a worm. If so, game over.
            if len(arcade.check_for_collision_with_list(self.player_sprite, self.enemy_list)) > 0:
                #  碰到移动的绿虫则回到初始位置,或者游戏结束 self.game_over = True   
                self.player_sprite.center_x = 64
                self.player_sprite.center_y = 270



def main():
    window = MyGame()
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()