TetrArcade/arcade/examples/sprite_enemies_in_platformer.py

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()