198 lines
6.1 KiB
Python
198 lines
6.1 KiB
Python
"""
|
|
Show how to do enemies in a platformer
|
|
|
|
Artwork from: http://kenney.nl
|
|
Tiled available from: http://www.mapeditor.org/
|
|
|
|
If Python and Arcade are installed, this example can be run from the command line with:
|
|
python -m arcade.examples.sprite_enemies_in_platformer
|
|
"""
|
|
|
|
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 = "Sprite Enemies in a Platformer Example"
|
|
|
|
# How many pixels to keep as a minimum margin between the character
|
|
# and the edge of the screen.
|
|
VIEWPORT_MARGIN = 40
|
|
RIGHT_MARGIN = 150
|
|
|
|
# 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)
|
|
|
|
# Set the working directory (where we expect to find files) to the same
|
|
# directory this .py file is in. You can leave this out of your own
|
|
# code, but it is needed to easily run the examples using "python -m"
|
|
# as mentioned at the top of this program.
|
|
file_path = os.path.dirname(os.path.abspath(__file__))
|
|
os.chdir(file_path)
|
|
|
|
# Sprite lists
|
|
self.wall_list = None
|
|
self.enemy_list = None
|
|
self.player_list = None
|
|
|
|
# Set up the player
|
|
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. """
|
|
|
|
# Sprite lists
|
|
self.wall_list = arcade.SpriteList()
|
|
self.enemy_list = arcade.SpriteList()
|
|
self.player_list = arcade.SpriteList()
|
|
|
|
# Draw the walls on the bottom
|
|
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)
|
|
|
|
# Draw the platform
|
|
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)
|
|
|
|
# Draw the crates
|
|
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)
|
|
|
|
# -- Draw an enemy on the ground
|
|
enemy = arcade.Sprite("images/wormGreen.png", SPRITE_SCALING)
|
|
|
|
enemy.bottom = SPRITE_SIZE
|
|
enemy.left = SPRITE_SIZE * 2
|
|
|
|
# Set enemy initial speed
|
|
enemy.change_x = 2
|
|
self.enemy_list.append(enemy)
|
|
|
|
# -- Draw a enemy on the platform
|
|
enemy = arcade.Sprite("images/wormGreen.png", SPRITE_SCALING)
|
|
|
|
enemy.bottom = SPRITE_SIZE * 4
|
|
enemy.left = SPRITE_SIZE * 4
|
|
|
|
# Set boundaries on the left/right the enemy can't cross
|
|
enemy.boundary_right = SPRITE_SIZE * 8
|
|
enemy.boundary_left = SPRITE_SIZE * 3
|
|
enemy.change_x = 2
|
|
self.enemy_list.append(enemy)
|
|
|
|
# -- Set up the player
|
|
self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING)
|
|
self.player_list.append(self.player_sprite)
|
|
|
|
# Starting position of the player
|
|
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):
|
|
"""
|
|
Render the screen.
|
|
"""
|
|
|
|
# This command has to happen before we start drawing
|
|
arcade.start_render()
|
|
|
|
# Draw all the sprites.
|
|
self.player_list.draw()
|
|
self.wall_list.draw()
|
|
self.enemy_list.draw()
|
|
|
|
def on_key_press(self, key, modifiers):
|
|
"""
|
|
Called whenever the mouse moves.
|
|
"""
|
|
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):
|
|
"""
|
|
Called when the user presses a mouse button.
|
|
"""
|
|
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()
|
|
|
|
# Check each enemy
|
|
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
|
|
# If the enemy hit the left boundary, reverse
|
|
elif enemy.boundary_left is not None and enemy.left < enemy.boundary_left:
|
|
enemy.change_x *= -1
|
|
# If the enemy hit the right boundary, reverse
|
|
elif enemy.boundary_right is not None and enemy.right > enemy.boundary_right:
|
|
enemy.change_x *= -1
|
|
|
|
# Update the player using the physics engine
|
|
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
|
|
|
|
|
|
def main():
|
|
window = MyGame()
|
|
window.setup()
|
|
arcade.run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|