clone and modify arcade to stop text scale and speed up text display

This commit is contained in:
2019-09-27 17:43:53 +02:00
parent f8e8336fa7
commit 55b6805c41
825 changed files with 31523 additions and 84 deletions

View File

View File

@ -0,0 +1,113 @@
"""
Array Backed Grid
Show how to use a two-dimensional list/array to back the display of a
grid on-screen.
Note: Regular drawing commands are slow. Particularly when drawing a lot of
items, like the rectangles in this example.
For faster drawing, create the shapes and then draw them as a batch.
See array_backed_grid_buffered.py
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.array_backed_grid
"""
import arcade
# Set how many rows and columns we will have
ROW_COUNT = 15
COLUMN_COUNT = 15
# This sets the WIDTH and HEIGHT of each grid location
WIDTH = 30
HEIGHT = 30
# This sets the margin between each cell
# and on the edges of the screen.
MARGIN = 5
# Do the math to figure out our screen dimensions
SCREEN_WIDTH = (WIDTH + MARGIN) * COLUMN_COUNT + MARGIN
SCREEN_HEIGHT = (HEIGHT + MARGIN) * ROW_COUNT + MARGIN
SCREEN_TITLE = "Array Backed Grid Example"
class MyGame(arcade.Window):
"""
Main application class.
"""
def __init__(self, width, height, title):
"""
Set up the application.
"""
super().__init__(width, height, title)
# Create a 2 dimensional array. A two dimensional
# array is simply a list of lists.
self.grid = []
for row in range(ROW_COUNT):
# Add an empty array that will hold each cell
# in this row
self.grid.append([])
for column in range(COLUMN_COUNT):
self.grid[row].append(0) # Append a cell
arcade.set_background_color(arcade.color.BLACK)
def on_draw(self):
"""
Render the screen.
"""
# This command has to happen before we start drawing
arcade.start_render()
# Draw the grid
for row in range(ROW_COUNT):
for column in range(COLUMN_COUNT):
# Figure out what color to draw the box
if self.grid[row][column] == 1:
color = arcade.color.GREEN
else:
color = arcade.color.WHITE
# Do the math to figure out where the box is
x = (MARGIN + WIDTH) * column + MARGIN + WIDTH // 2
y = (MARGIN + HEIGHT) * row + MARGIN + HEIGHT // 2
# Draw the box
arcade.draw_rectangle_filled(x, y, WIDTH, HEIGHT, color)
def on_mouse_press(self, x, y, button, modifiers):
"""
Called when the user presses a mouse button.
"""
# Change the x/y screen coordinates to grid coordinates
column = x // (WIDTH + MARGIN)
row = y // (HEIGHT + MARGIN)
print(f"Click coordinates: ({x}, {y}). Grid coordinates: ({row}, {column})")
# Make sure we are on-grid. It is possible to click in the upper right
# corner in the margin and go to a grid location that doesn't exist
if row < ROW_COUNT and column < COLUMN_COUNT:
# Flip the location between 1 and 0.
if self.grid[row][column] == 0:
self.grid[row][column] = 1
else:
self.grid[row][column] = 0
def main():
MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,111 @@
"""
Array Backed Grid
Show how to use a two-dimensional list/array to back the display of a
grid on-screen.
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.array_backed_grid_buffered
"""
import arcade
# Set how many rows and columns we will have
ROW_COUNT = 15
COLUMN_COUNT = 15
# This sets the WIDTH and HEIGHT of each grid location
WIDTH = 30
HEIGHT = 30
# This sets the margin between each cell
# and on the edges of the screen.
MARGIN = 5
# Do the math to figure out our screen dimensions
SCREEN_WIDTH = (WIDTH + MARGIN) * COLUMN_COUNT + MARGIN
SCREEN_HEIGHT = (HEIGHT + MARGIN) * ROW_COUNT + MARGIN
SCREEN_TITLE = "Array Backed Grid Buffered Example"
class MyGame(arcade.Window):
"""
Main application class.
"""
def __init__(self, width, height, title):
"""
Set up the application.
"""
super().__init__(width, height, title)
self.shape_list = None
# Create a 2 dimensional array. A two dimensional
# array is simply a list of lists.
self.grid = []
for row in range(ROW_COUNT):
# Add an empty array that will hold each cell
# in this row
self.grid.append([])
for column in range(COLUMN_COUNT):
self.grid[row].append(0) # Append a cell
arcade.set_background_color(arcade.color.BLACK)
self.recreate_grid()
def recreate_grid(self):
self.shape_list = arcade.ShapeElementList()
for row in range(ROW_COUNT):
for column in range(COLUMN_COUNT):
if self.grid[row][column] == 0:
color = arcade.color.WHITE
else:
color = arcade.color.GREEN
x = (MARGIN + WIDTH) * column + MARGIN + WIDTH // 2
y = (MARGIN + HEIGHT) * row + MARGIN + HEIGHT // 2
current_rect = arcade.create_rectangle_filled(x, y, WIDTH, HEIGHT, color)
self.shape_list.append(current_rect)
def on_draw(self):
"""
Render the screen.
"""
# This command has to happen before we start drawing
arcade.start_render()
self.shape_list.draw()
def on_mouse_press(self, x, y, button, modifiers):
"""
Called when the user presses a mouse button.
"""
# Change the x/y screen coordinates to grid coordinates
column = x // (WIDTH + MARGIN)
row = y // (HEIGHT + MARGIN)
print(f"Click coordinates: ({x}, {y}). Grid coordinates: ({row}, {column})")
# Make sure we are on-grid. It is possible to click in the upper right
# corner in the margin and go to a grid location that doesn't exist
if row < ROW_COUNT and column < COLUMN_COUNT:
# Flip the location between 1 and 0.
if self.grid[row][column] == 0:
self.grid[row][column] = 1
else:
self.grid[row][column] = 0
self.recreate_grid()
def main():
MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,392 @@
"""
Asteroid Smasher
Shoot space rocks in this demo program created with
Python and the Arcade library.
Artwork from http://kenney.nl
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.asteroid_smasher
"""
import random
import math
import arcade
import os
STARTING_ASTEROID_COUNT = 3
SCALE = 0.5
OFFSCREEN_SPACE = 300
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Asteroid Smasher"
LEFT_LIMIT = -OFFSCREEN_SPACE
RIGHT_LIMIT = SCREEN_WIDTH + OFFSCREEN_SPACE
BOTTOM_LIMIT = -OFFSCREEN_SPACE
TOP_LIMIT = SCREEN_HEIGHT + OFFSCREEN_SPACE
class TurningSprite(arcade.Sprite):
""" Sprite that sets its angle to the direction it is traveling in. """
def update(self):
super().update()
self.angle = math.degrees(math.atan2(self.change_y, self.change_x))
class ShipSprite(arcade.Sprite):
"""
Sprite that represents our space ship.
Derives from arcade.Sprite.
"""
def __init__(self, filename, scale):
""" Set up the space ship. """
# Call the parent Sprite constructor
super().__init__(filename, scale)
# Info on where we are going.
# Angle comes in automatically from the parent class.
self.thrust = 0
self.speed = 0
self.max_speed = 4
self.drag = 0.05
self.respawning = 0
# Mark that we are respawning.
self.respawn()
def respawn(self):
"""
Called when we die and need to make a new ship.
'respawning' is an invulnerability timer.
"""
# If we are in the middle of respawning, this is non-zero.
self.respawning = 1
self.center_x = SCREEN_WIDTH / 2
self.center_y = SCREEN_HEIGHT / 2
self.angle = 0
def update(self):
"""
Update our position and other particulars.
"""
if self.respawning:
self.respawning += 1
self.alpha = self.respawning
if self.respawning > 250:
self.respawning = 0
self.alpha = 255
if self.speed > 0:
self.speed -= self.drag
if self.speed < 0:
self.speed = 0
if self.speed < 0:
self.speed += self.drag
if self.speed > 0:
self.speed = 0
self.speed += self.thrust
if self.speed > self.max_speed:
self.speed = self.max_speed
if self.speed < -self.max_speed:
self.speed = -self.max_speed
self.change_x = -math.sin(math.radians(self.angle)) * self.speed
self.change_y = math.cos(math.radians(self.angle)) * self.speed
self.center_x += self.change_x
self.center_y += self.change_y
""" Call the parent class. """
super().update()
class AsteroidSprite(arcade.Sprite):
""" Sprite that represents an asteroid. """
def __init__(self, image_file_name, scale):
super().__init__(image_file_name, scale=scale)
self.size = 0
def update(self):
""" Move the asteroid around. """
super().update()
if self.center_x < LEFT_LIMIT:
self.center_x = RIGHT_LIMIT
if self.center_x > RIGHT_LIMIT:
self.center_x = LEFT_LIMIT
if self.center_y > TOP_LIMIT:
self.center_y = BOTTOM_LIMIT
if self.center_y < BOTTOM_LIMIT:
self.center_y = TOP_LIMIT
class BulletSprite(TurningSprite):
"""
Class that represents a bullet.
Derives from arcade.TurningSprite which is just a Sprite
that aligns to its direction.
"""
def update(self):
super().update()
if self.center_x < -100 or self.center_x > 1500 or \
self.center_y > 1100 or self.center_y < -100:
self.kill()
class MyGame(arcade.Window):
""" Main application class. """
def __init__(self):
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)
self.frame_count = 0
self.game_over = False
# Sprite lists
self.all_sprites_list = None
self.asteroid_list = None
self.bullet_list = None
self.ship_life_list = None
# Set up the player
self.score = 0
self.player_sprite = None
self.lives = 3
# Sounds
self.laser_sound = arcade.load_sound("sounds/laser1.wav")
def start_new_game(self):
""" Set up the game and initialize the variables. """
self.frame_count = 0
self.game_over = False
# Sprite lists
self.all_sprites_list = arcade.SpriteList()
self.asteroid_list = arcade.SpriteList()
self.bullet_list = arcade.SpriteList()
self.ship_life_list = arcade.SpriteList()
# Set up the player
self.score = 0
self.player_sprite = ShipSprite("images/playerShip1_orange.png", SCALE)
self.all_sprites_list.append(self.player_sprite)
self.lives = 3
# Set up the little icons that represent the player lives.
cur_pos = 10
for i in range(self.lives):
life = arcade.Sprite("images/playerLife1_orange.png", SCALE)
life.center_x = cur_pos + life.width
life.center_y = life.height
cur_pos += life.width
self.all_sprites_list.append(life)
self.ship_life_list.append(life)
# Make the asteroids
image_list = ("images/meteorGrey_big1.png",
"images/meteorGrey_big2.png",
"images/meteorGrey_big3.png",
"images/meteorGrey_big4.png")
for i in range(STARTING_ASTEROID_COUNT):
image_no = random.randrange(4)
enemy_sprite = AsteroidSprite(image_list[image_no], SCALE)
enemy_sprite.guid = "Asteroid"
enemy_sprite.center_y = random.randrange(BOTTOM_LIMIT, TOP_LIMIT)
enemy_sprite.center_x = random.randrange(LEFT_LIMIT, RIGHT_LIMIT)
enemy_sprite.change_x = random.random() * 2 - 1
enemy_sprite.change_y = random.random() * 2 - 1
enemy_sprite.change_angle = (random.random() - 0.5) * 2
enemy_sprite.size = 4
self.all_sprites_list.append(enemy_sprite)
self.asteroid_list.append(enemy_sprite)
def on_draw(self):
"""
Render the screen.
"""
# This command has to happen before we start drawing
arcade.start_render()
# Draw all the sprites.
self.all_sprites_list.draw()
# Put the text on the screen.
output = f"Score: {self.score}"
arcade.draw_text(output, 10, 70, arcade.color.WHITE, 13)
output = f"Asteroid Count: {len(self.asteroid_list)}"
arcade.draw_text(output, 10, 50, arcade.color.WHITE, 13)
def on_key_press(self, symbol, modifiers):
""" Called whenever a key is pressed. """
# Shoot if the player hit the space bar and we aren't respawning.
if not self.player_sprite.respawning and symbol == arcade.key.SPACE:
bullet_sprite = BulletSprite("images/laserBlue01.png", SCALE)
bullet_sprite.guid = "Bullet"
bullet_speed = 13
bullet_sprite.change_y = \
math.cos(math.radians(self.player_sprite.angle)) * bullet_speed
bullet_sprite.change_x = \
-math.sin(math.radians(self.player_sprite.angle)) \
* bullet_speed
bullet_sprite.center_x = self.player_sprite.center_x
bullet_sprite.center_y = self.player_sprite.center_y
bullet_sprite.update()
self.all_sprites_list.append(bullet_sprite)
self.bullet_list.append(bullet_sprite)
arcade.play_sound(self.laser_sound)
if symbol == arcade.key.LEFT:
self.player_sprite.change_angle = 3
elif symbol == arcade.key.RIGHT:
self.player_sprite.change_angle = -3
elif symbol == arcade.key.UP:
self.player_sprite.thrust = 0.15
elif symbol == arcade.key.DOWN:
self.player_sprite.thrust = -.2
def on_key_release(self, symbol, modifiers):
""" Called whenever a key is released. """
if symbol == arcade.key.LEFT:
self.player_sprite.change_angle = 0
elif symbol == arcade.key.RIGHT:
self.player_sprite.change_angle = 0
elif symbol == arcade.key.UP:
self.player_sprite.thrust = 0
elif symbol == arcade.key.DOWN:
self.player_sprite.thrust = 0
def split_asteroid(self, asteroid: AsteroidSprite):
""" Split an asteroid into chunks. """
x = asteroid.center_x
y = asteroid.center_y
self.score += 1
if asteroid.size == 4:
for i in range(3):
image_no = random.randrange(2)
image_list = ["images/meteorGrey_med1.png",
"images/meteorGrey_med2.png"]
enemy_sprite = AsteroidSprite(image_list[image_no],
SCALE * 1.5)
enemy_sprite.center_y = y
enemy_sprite.center_x = x
enemy_sprite.change_x = random.random() * 2.5 - 1.25
enemy_sprite.change_y = random.random() * 2.5 - 1.25
enemy_sprite.change_angle = (random.random() - 0.5) * 2
enemy_sprite.size = 3
self.all_sprites_list.append(enemy_sprite)
self.asteroid_list.append(enemy_sprite)
elif asteroid.size == 3:
for i in range(3):
image_no = random.randrange(2)
image_list = ["images/meteorGrey_small1.png",
"images/meteorGrey_small2.png"]
enemy_sprite = AsteroidSprite(image_list[image_no],
SCALE * 1.5)
enemy_sprite.center_y = y
enemy_sprite.center_x = x
enemy_sprite.change_x = random.random() * 3 - 1.5
enemy_sprite.change_y = random.random() * 3 - 1.5
enemy_sprite.change_angle = (random.random() - 0.5) * 2
enemy_sprite.size = 2
self.all_sprites_list.append(enemy_sprite)
self.asteroid_list.append(enemy_sprite)
elif asteroid.size == 2:
for i in range(3):
image_no = random.randrange(2)
image_list = ["images/meteorGrey_tiny1.png",
"images/meteorGrey_tiny2.png"]
enemy_sprite = AsteroidSprite(image_list[image_no],
SCALE * 1.5)
enemy_sprite.center_y = y
enemy_sprite.center_x = x
enemy_sprite.change_x = random.random() * 3.5 - 1.75
enemy_sprite.change_y = random.random() * 3.5 - 1.75
enemy_sprite.change_angle = (random.random() - 0.5) * 2
enemy_sprite.size = 1
self.all_sprites_list.append(enemy_sprite)
self.asteroid_list.append(enemy_sprite)
def update(self, x):
""" Move everything """
self.frame_count += 1
if not self.game_over:
self.all_sprites_list.update()
for bullet in self.bullet_list:
asteroids_plain = arcade.check_for_collision_with_list(bullet, self.asteroid_list)
asteroids_spatial = arcade.check_for_collision_with_list(bullet, self.asteroid_list)
if len(asteroids_plain) != len(asteroids_spatial):
print("ERROR")
asteroids = asteroids_spatial
for asteroid in asteroids:
self.split_asteroid(asteroid)
asteroid.kill()
bullet.kill()
if not self.player_sprite.respawning:
asteroids = arcade.check_for_collision_with_list(self.player_sprite, self.asteroid_list)
if len(asteroids) > 0:
if self.lives > 0:
self.lives -= 1
self.player_sprite.respawn()
self.split_asteroid(asteroids[0])
asteroids[0].kill()
self.ship_life_list.pop().kill()
print("Crash")
else:
self.game_over = True
print("Game over")
def main():
window = MyGame()
window.start_new_game()
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,97 @@
"""
Bounce a ball on the screen, using gravity.
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.bouncing_ball
"""
import arcade
# --- Set up the constants
# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Bouncing Ball Example"
# Size of the circle.
CIRCLE_RADIUS = 20
# How strong the gravity is.
GRAVITY_CONSTANT = 0.3
# Percent of velocity maintained on a bounce.
BOUNCINESS = 0.9
def draw(delta_time):
"""
Use this function to draw everything to the screen.
"""
# Start the render. This must happen before any drawing
# commands. We do NOT need an stop render command.
arcade.start_render()
# Draw our rectangle
arcade.draw_circle_filled(draw.x, draw.y, CIRCLE_RADIUS,
arcade.color.BLACK)
# Modify rectangles position based on the delta
# vector. (Delta means change. You can also think
# of this as our speed and direction.)
draw.x += draw.delta_x
draw.y += draw.delta_y
draw.delta_y -= GRAVITY_CONSTANT
# Figure out if we hit the left or right edge and need to reverse.
if draw.x < CIRCLE_RADIUS and draw.delta_x < 0:
draw.delta_x *= -BOUNCINESS
elif draw.x > SCREEN_WIDTH - CIRCLE_RADIUS and draw.delta_x > 0:
draw.delta_x *= -BOUNCINESS
# See if we hit the bottom
if draw.y < CIRCLE_RADIUS and draw.delta_y < 0:
# If we bounce with a decent velocity, do a normal bounce.
# Otherwise we won't have enough time resolution to accurate represent
# the bounce and it will bounce forever. So we'll divide the bounciness
# by half to let it settle out.
if draw.delta_y * -1 > GRAVITY_CONSTANT * 15:
draw.delta_y *= -BOUNCINESS
else:
draw.delta_y *= -BOUNCINESS / 2
# Below are function-specific variables. Before we use them
# in our function, we need to give them initial values. Then
# the values will persist between function calls.
#
# In other languages, we'd declare the variables as 'static' inside the
# function to get that same functionality.
#
# Later on, we'll use 'classes' to track position and velocity for multiple
# objects.
draw.x = CIRCLE_RADIUS
draw.y = SCREEN_HEIGHT - CIRCLE_RADIUS
draw.delta_x = 2
draw.delta_y = 0
def main():
# Open up our window
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.set_background_color(arcade.color.WHITE)
# Tell the computer to call the draw command at the specified interval.
arcade.schedule(draw, 1 / 80)
# Run the program
arcade.run()
# When done running the program, close the window.
arcade.close_window()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,113 @@
"""
Bounce balls on the screen.
Spawn a new ball for each mouse-click.
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.bouncing_balls
"""
import arcade
import random
# --- Set up the constants
# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Bouncing Balls Example"
class Ball:
"""
Class to keep track of a ball's location and vector.
"""
def __init__(self):
self.x = 0
self.y = 0
self.change_x = 0
self.change_y = 0
self.size = 0
self.color = None
def make_ball():
"""
Function to make a new, random ball.
"""
ball = Ball()
# Size of the ball
ball.size = random.randrange(10, 30)
# Starting position of the ball.
# Take into account the ball size so we don't spawn on the edge.
ball.x = random.randrange(ball.size, SCREEN_WIDTH - ball.size)
ball.y = random.randrange(ball.size, SCREEN_HEIGHT - ball.size)
# Speed and direction of rectangle
ball.change_x = random.randrange(-2, 3)
ball.change_y = random.randrange(-2, 3)
# Color
ball.color = (random.randrange(256), random.randrange(256), random.randrange(256))
return ball
class MyGame(arcade.Window):
""" Main application class. """
def __init__(self):
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
self.ball_list = []
ball = make_ball()
self.ball_list.append(ball)
def on_draw(self):
"""
Render the screen.
"""
# This command has to happen before we start drawing
arcade.start_render()
for ball in self.ball_list:
arcade.draw_circle_filled(ball.x, ball.y, ball.size, ball.color)
# Put the text on the screen.
output = "Balls: {}".format(len(self.ball_list))
arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)
def update(self, delta_time):
""" Movement and game logic """
for ball in self.ball_list:
ball.x += ball.change_x
ball.y += ball.change_y
if ball.x < ball.size:
ball.change_x *= -1
if ball.y < ball.size:
ball.change_y *= -1
if ball.x > SCREEN_WIDTH - ball.size:
ball.change_x *= -1
if ball.y > SCREEN_HEIGHT - ball.size:
ball.change_y *= -1
def on_mouse_press(self, x, y, button, modifiers):
"""
Called whenever the mouse button is clicked.
"""
ball = make_ball()
self.ball_list.append(ball)
def main():
MyGame()
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,95 @@
"""
This simple animation example shows how to bounce a rectangle
on the screen.
It assumes a programmer knows how to create functions already.
It does not assume a programmer knows how to create classes. If you do know
how to create classes, see the starting template for a better example:
http://arcade.academy/examples/starting_template.html
Or look through the examples showing how to use Sprites.
A video walk-through of this example is available at:
https://vimeo.com/168063840
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.bouncing_rectangle
"""
import arcade
# --- Set up the constants
# Size of the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Bouncing Rectangle Example"
# Size of the rectangle
RECT_WIDTH = 50
RECT_HEIGHT = 50
def on_draw(delta_time):
"""
Use this function to draw everything to the screen.
"""
# Start the render. This must happen before any drawing
# commands. We do NOT need a stop render command.
arcade.start_render()
# Draw a rectangle.
# For a full list of colors see:
# http://arcade.academy/arcade.color.html
arcade.draw_rectangle_filled(on_draw.center_x, on_draw.center_y,
RECT_WIDTH, RECT_HEIGHT,
arcade.color.ALIZARIN_CRIMSON)
# Modify rectangles position based on the delta
# vector. (Delta means change. You can also think
# of this as our speed and direction.)
on_draw.center_x += on_draw.delta_x * delta_time
on_draw.center_y += on_draw.delta_y * delta_time
# Figure out if we hit the edge and need to reverse.
if on_draw.center_x < RECT_WIDTH // 2 \
or on_draw.center_x > SCREEN_WIDTH - RECT_WIDTH // 2:
on_draw.delta_x *= -1
if on_draw.center_y < RECT_HEIGHT // 2 \
or on_draw.center_y > SCREEN_HEIGHT - RECT_HEIGHT // 2:
on_draw.delta_y *= -1
# Below are function-specific variables. Before we use them
# in our function, we need to give them initial values. Then
# the values will persist between function calls.
#
# In other languages, we'd declare the variables as 'static' inside the
# function to get that same functionality.
#
# Later on, we'll use 'classes' to track position and velocity for multiple
# objects.
on_draw.center_x = 100 # Initial x position
on_draw.center_y = 50 # Initial y position
on_draw.delta_x = 115 # Initial change in x
on_draw.delta_y = 130 # Initial change in y
def main():
# Open up our window
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.set_background_color(arcade.color.WHITE)
# Tell the computer to call the draw command at the specified interval.
arcade.schedule(on_draw, 1 / 80)
# Run the program
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,124 @@
"""
Example "Arcade" library code.
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.decorator_drawing_example
"""
# Library imports
import arcade
import random
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Drawing With Decorators Example"
window = arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
bird_list = []
def setup():
create_birds()
arcade.schedule(update, 1 / 60)
arcade.run()
def create_birds():
for bird_count in range(10):
x = random.randrange(SCREEN_WIDTH)
y = random.randrange(SCREEN_HEIGHT/2, SCREEN_HEIGHT)
bird_list.append([x, y])
def update(delta_time):
"""
This is run every 1/60 of a second or so. Do not draw anything
in this function.
"""
change_y = 0.3
for bird in bird_list:
bird[0] += change_y
if bird[0] > SCREEN_WIDTH + 20:
bird[0] = -20
@window.event
def on_draw():
"""
This is called every time we need to update our screen. About 60
times per second.
Just draw things in this function, don't update where they are.
"""
# Call our drawing functions.
draw_background()
draw_birds()
draw_trees()
def draw_background():
"""
This function draws the background. Specifically, the sky and ground.
"""
# Draw the sky in the top two-thirds
arcade.draw_rectangle_filled(SCREEN_WIDTH / 2, SCREEN_HEIGHT * 2 / 3,
SCREEN_WIDTH - 1, SCREEN_HEIGHT * 2 / 3,
arcade.color.SKY_BLUE)
# Draw the ground in the bottom third
arcade.draw_rectangle_filled(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 6,
SCREEN_WIDTH - 1, SCREEN_HEIGHT / 3,
arcade.color.DARK_SPRING_GREEN)
def draw_birds():
for bird in bird_list:
# Draw the bird.
draw_bird(bird[0], bird[1])
def draw_bird(x, y):
"""
Draw a bird using a couple arcs.
"""
arcade.draw_arc_outline(x, y, 20, 20, arcade.color.BLACK, 0, 90)
arcade.draw_arc_outline(x + 40, y, 20, 20, arcade.color.BLACK, 90, 180)
def draw_trees():
# Draw the top row of trees
for x in range(45, SCREEN_WIDTH, 90):
draw_pine_tree(x, SCREEN_HEIGHT / 3)
# Draw the bottom row of trees
for x in range(65, SCREEN_WIDTH, 90):
draw_pine_tree(x, (SCREEN_HEIGHT / 3) - 120)
def draw_pine_tree(center_x, center_y):
"""
This function draws a pine tree at the specified location.
Args:
:center_x: x position of the tree center.
:center_y: y position of the tree trunk center.
"""
# Draw the trunk center_x
arcade.draw_rectangle_filled(center_x, center_y, 20, 40, arcade.color.DARK_BROWN)
tree_bottom_y = center_y + 20
# Draw the triangle on top of the trunk
point_list = ((center_x - 40, tree_bottom_y),
(center_x, tree_bottom_y + 100),
(center_x + 40, tree_bottom_y))
arcade.draw_polygon_filled(point_list, arcade.color.DARK_GREEN)
if __name__ == "__main__":
setup()

View File

@ -0,0 +1,168 @@
"""
Example "Arcade" library code.
This example shows the drawing primitives and how they are used.
It does not assume the programmer knows how to define functions or classes
yet.
API documentation for the draw commands can be found here:
http://arcade.academy/quick_index.html#id1
A video explaining this example can be found here:
https://vimeo.com/167158158
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.drawing_primitives
"""
# Import the Arcade library. If this fails, then try following the instructions
# for how to install arcade:
# http://arcade.academy/installation.html
import arcade
import os
# 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)
# Open the window. Set the window title and dimensions (width and height)
arcade.open_window(600, 600, "Drawing Primitives Example")
# Set the background color to white
# For a list of named colors see
# http://arcade.academy/arcade.color.html
# Colors can also be specified in (red, green, blue) format and
# (red, green, blue, alpha) format.
arcade.set_background_color(arcade.color.WHITE)
# Start the render process. This must be done before any drawing commands.
arcade.start_render()
# Draw a grid
# Draw vertical lines every 120 pixels
for x in range(0, 601, 120):
arcade.draw_line(x, 0, x, 600, arcade.color.BLACK, 2)
# Draw horizontal lines every 200 pixels
for y in range(0, 601, 200):
arcade.draw_line(0, y, 800, y, arcade.color.BLACK, 2)
# Draw a point
arcade.draw_text("draw_point", 3, 405, arcade.color.BLACK, 12)
arcade.draw_point(60, 495, arcade.color.RED, 10)
# Draw a set of points
arcade.draw_text("draw_points", 123, 405, arcade.color.BLACK, 12)
point_list = ((165, 495),
(165, 480),
(165, 465),
(195, 495),
(195, 480),
(195, 465))
arcade.draw_points(point_list, arcade.color.ZAFFRE, 10)
# Draw a line
arcade.draw_text("draw_line", 243, 405, arcade.color.BLACK, 12)
arcade.draw_line(270, 495, 300, 450, arcade.color.WOOD_BROWN, 3)
# Draw a set of lines
arcade.draw_text("draw_lines", 363, 405, arcade.color.BLACK, 12)
point_list = ((390, 450),
(450, 450),
(390, 480),
(450, 480),
(390, 510),
(450, 510)
)
arcade.draw_lines(point_list, arcade.color.BLUE, 3)
# Draw a line strip
arcade.draw_text("draw_line_strip", 483, 405, arcade.color.BLACK, 12)
point_list = ((510, 450),
(570, 450),
(510, 480),
(570, 480),
(510, 510),
(570, 510)
)
arcade.draw_line_strip(point_list, arcade.color.TROPICAL_RAIN_FOREST, 3)
# Draw a polygon
arcade.draw_text("draw_polygon_outline", 3, 207, arcade.color.BLACK, 9)
point_list = ((30, 240),
(45, 240),
(60, 255),
(60, 285),
(45, 300),
(30, 300))
arcade.draw_polygon_outline(point_list, arcade.color.SPANISH_VIOLET, 3)
# Draw a filled in polygon
arcade.draw_text("draw_polygon_filled", 123, 207, arcade.color.BLACK, 9)
point_list = ((150, 240),
(165, 240),
(180, 255),
(180, 285),
(165, 300),
(150, 300))
arcade.draw_polygon_filled(point_list, arcade.color.SPANISH_VIOLET)
# Draw an outline of a circle
arcade.draw_text("draw_circle_outline", 243, 207, arcade.color.BLACK, 10)
arcade.draw_circle_outline(300, 285, 18, arcade.color.WISTERIA, 3)
# Draw a filled in circle
arcade.draw_text("draw_circle_filled", 363, 207, arcade.color.BLACK, 10)
arcade.draw_circle_filled(420, 285, 18, arcade.color.GREEN)
# Draw an ellipse outline, and another one rotated
arcade.draw_text("draw_ellipse_outline", 483, 207, arcade.color.BLACK, 10)
arcade.draw_ellipse_outline(540, 273, 15, 36, arcade.color.AMBER, 3)
arcade.draw_ellipse_outline(540, 336, 15, 36,
arcade.color.BLACK_BEAN, 3, 45)
# Draw a filled ellipse, and another one rotated
arcade.draw_text("draw_ellipse_filled", 3, 3, arcade.color.BLACK, 10)
arcade.draw_ellipse_filled(60, 81, 15, 36, arcade.color.AMBER)
arcade.draw_ellipse_filled(60, 144, 15, 36,
arcade.color.BLACK_BEAN, 45)
# Draw an arc, and another one rotated
arcade.draw_text("draw_arc/filled_arc", 123, 3, arcade.color.BLACK, 10)
arcade.draw_arc_outline(150, 81, 15, 36,
arcade.color.BRIGHT_MAROON, 90, 360)
arcade.draw_arc_filled(150, 144, 15, 36,
arcade.color.BOTTLE_GREEN, 90, 360, 45)
# Draw an rectangle outline
arcade.draw_text("draw_rect", 243, 3, arcade.color.BLACK, 10)
arcade.draw_rectangle_outline(295, 100, 45, 65,
arcade.color.BRITISH_RACING_GREEN)
arcade.draw_rectangle_outline(295, 160, 20, 45,
arcade.color.BRITISH_RACING_GREEN, 3, 45)
# Draw a filled in rectangle
arcade.draw_text("draw_filled_rect", 363, 3, arcade.color.BLACK, 10)
arcade.draw_rectangle_filled(420, 100, 45, 65, arcade.color.BLUSH)
arcade.draw_rectangle_filled(420, 160, 20, 40, arcade.color.BLUSH, 45)
# Load and draw an image to the screen
# Image from kenney.nl asset pack #1
arcade.draw_text("draw_bitmap", 483, 3, arcade.color.BLACK, 12)
texture = arcade.load_texture("images/playerShip1_orange.png")
scale = .6
arcade.draw_texture_rectangle(540, 120, scale * texture.width,
scale * texture.height, texture, 0)
arcade.draw_texture_rectangle(540, 60, scale * texture.width,
scale * texture.height, texture, 45)
# Finish the render.
# Nothing will be drawn without this.
# Must happen after all draw commands
arcade.finish_render()
# Keep the window up until someone closes it.
arcade.run()

View File

@ -0,0 +1,107 @@
"""
Example showing how to draw text to the screen.
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.drawing_text
"""
import arcade
SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500
SCREEN_TITLE = "Drawing Text Example"
class MyGame(arcade.Window):
"""
Main application class.
"""
def __init__(self, width, height, title):
super().__init__(width, height, title)
arcade.set_background_color(arcade.color.WHITE)
self.text_angle = 0
self.time_elapsed = 0.0
def update(self, delta_time):
self.text_angle += 1
self.time_elapsed += delta_time
def on_draw(self):
"""
Render the screen.
"""
# This command should happen before we start drawing. It will clear
# the screen to the background color, and erase what we drew last frame.
arcade.start_render()
# start_x and start_y make the start point for the text. We draw a dot to make it easy too see
# the text in relation to its start x and y.
start_x = 50
start_y = 450
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text("Simple line of text in 12 point", start_x, start_y, arcade.color.BLACK, 12)
start_x = 50
start_y = 150
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text("Garamond Text", start_x, start_y, arcade.color.BLACK, 15, font_name='GARA')
start_x = 50
start_y = 400
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text("Text anchored 'top' and 'left'.",
start_x, start_y, arcade.color.BLACK, 12, anchor_x="left", anchor_y="top")
start_y = 350
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text("14 point multi\nline\ntext",
start_x, start_y, arcade.color.BLACK, 14, anchor_y="top")
start_y = 450
start_x = 300
width = 200
height = 20
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_lrtb_rectangle_outline(start_x, start_x + width,
start_y + height, start_y,
arcade.color.BLUE, 1)
arcade.draw_text("Centered Text.",
start_x, start_y, arcade.color.BLACK, 14, width=200, align="center")
start_y = 250
start_x = 300
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text("Text centered on\na point",
start_x, start_y, arcade.color.BLACK, 14, width=200, align="center",
anchor_x="center", anchor_y="center")
start_y = 150
start_x = 300
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text("Text rotated on\na point", start_x, start_y,
arcade.color.BLACK, 14, width=200, align="center", anchor_x="center",
anchor_y="center", rotation=self.text_angle)
start_y = 150
start_x = 20
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text("Sideways text", start_x, start_y,
arcade.color.BLACK, 14, width=200, align="center",
anchor_x="center", anchor_y="center", rotation=90.0)
start_y = 20
start_x = 50
arcade.draw_point(start_x, start_y, arcade.color.BLUE, 5)
arcade.draw_text(f"Time elapsed: {self.time_elapsed:7.1f}",
start_x, start_y, arcade.color.BLACK, 14)
def main():
MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,93 @@
"""
Example "Arcade" library code.
This example shows how to use functions to draw a scene.
It does not assume that the programmer knows how to use classes yet.
A video walk-through of this code is available at:
https://vimeo.com/167296062
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.drawing_with_functions
"""
# Library imports
import arcade
# Constants - variables that do not change
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Drawing With Functions Example"
def draw_background():
"""
This function draws the background. Specifically, the sky and ground.
"""
# Draw the sky in the top two-thirds
arcade.draw_lrtb_rectangle_filled(0,
SCREEN_WIDTH,
SCREEN_HEIGHT,
SCREEN_HEIGHT * (1 / 3),
arcade.color.SKY_BLUE)
# Draw the ground in the bottom third
arcade.draw_lrtb_rectangle_filled(0,
SCREEN_WIDTH,
SCREEN_HEIGHT / 3,
0,
arcade.color.DARK_SPRING_GREEN)
def draw_bird(x, y):
"""
Draw a bird using a couple arcs.
"""
arcade.draw_arc_outline(x, y, 20, 20, arcade.color.BLACK, 0, 90)
arcade.draw_arc_outline(x + 40, y, 20, 20, arcade.color.BLACK, 90, 180)
def draw_pine_tree(x, y):
"""
This function draws a pine tree at the specified location.
"""
# Draw the triangle on top of the trunk
arcade.draw_triangle_filled(x + 40, y,
x, y - 100,
x + 80, y - 100,
arcade.color.DARK_GREEN)
# Draw the trunk
arcade.draw_lrtb_rectangle_filled(x + 30, x + 50, y - 100, y - 140,
arcade.color.DARK_BROWN)
def main():
"""
This is the main program.
"""
# Open the window
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
# Start the render process. This must be done before any drawing commands.
arcade.start_render()
# Call our drawing functions.
draw_background()
draw_pine_tree(50, 250)
draw_pine_tree(350, 320)
draw_bird(70, 500)
draw_bird(470, 550)
# Finish the render.
# Nothing will be drawn without this.
# Must happen after all draw commands
arcade.finish_render()
# Keep the window up until someone closes it.
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,109 @@
"""
Example "Arcade" library code.
This example shows how to use functions and loops to draw a scene.
It does not assume that the programmer knows how to use classes yet.
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.drawing_with_loops
"""
# Library imports
import arcade
import random
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Drawing With Loops Example"
def draw_background():
"""
This function draws the background. Specifically, the sky and ground.
"""
# Draw the sky in the top two-thirds
arcade.draw_rectangle_filled(SCREEN_WIDTH / 2, SCREEN_HEIGHT * 2 / 3,
SCREEN_WIDTH - 1, SCREEN_HEIGHT * 2 / 3,
arcade.color.SKY_BLUE)
# Draw the ground in the bottom third
arcade.draw_rectangle_filled(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 6,
SCREEN_WIDTH - 1, SCREEN_HEIGHT / 3,
arcade.color.DARK_SPRING_GREEN)
def draw_bird(x, y):
"""
Draw a bird using a couple arcs.
"""
arcade.draw_arc_outline(x, y, 20, 20, arcade.color.BLACK, 0, 90)
arcade.draw_arc_outline(x + 40, y, 20, 20, arcade.color.BLACK, 90, 180)
def draw_pine_tree(center_x, center_y):
"""
This function draws a pine tree at the specified location.
Args:
:center_x: x position of the tree center.
:center_y: y position of the tree trunk center.
"""
# Draw the trunkcenter_x
arcade.draw_rectangle_filled(center_x, center_y, 20, 40,
arcade.color.DARK_BROWN)
tree_bottom_y = center_y + 20
# Draw the triangle on top of the trunk
point_list = ((center_x - 40, tree_bottom_y),
(center_x, tree_bottom_y + 100),
(center_x + 40, tree_bottom_y))
arcade.draw_polygon_filled(point_list, arcade.color.DARK_GREEN)
def main():
"""
This is the main program.
"""
# Open the window
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
# Start the render process. This must be done before any drawing commands.
arcade.start_render()
# Call our drawing functions.
draw_background()
# Loop to draw ten birds in random locations.
for bird_count in range(10):
# Any random x from 0 to the width of the screen
x = random.randrange(0, SCREEN_WIDTH)
# Any random y from in the top 2/3 of the screen.
# No birds on the ground.
y = random.randrange(SCREEN_HEIGHT / 3, SCREEN_HEIGHT - 20)
# Draw the bird.
draw_bird(x, y)
# Draw the top row of trees
for x in range(45, SCREEN_WIDTH, 90):
draw_pine_tree(x, SCREEN_HEIGHT / 3)
# Draw the bottom row of trees
for x in range(65, SCREEN_WIDTH, 90):
draw_pine_tree(x, (SCREEN_HEIGHT / 3) - 120)
# Finish the render.
# Nothing will be drawn without this.
# Must happen after all draw commands
arcade.finish_render()
# Keep the window up until someone closes it.
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,310 @@
"""
Dual-stick Shooter Example
A dual-analog stick joystick is the preferred method of input. If a joystick is
not present, the game will fail back to use keyboard controls (WASD to move, arrows to shoot)
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.dual_stick_shooter
"""
import arcade
import random
import math
import os
from typing import cast
import pprint
SCREEN_WIDTH = 1024
SCREEN_HEIGHT = 768
SCREEN_TITLE = "Dual-stick Shooter Example"
MOVEMENT_SPEED = 4
BULLET_SPEED = 10
BULLET_COOLDOWN_TICKS = 10
ENEMY_SPAWN_INTERVAL = 1
ENEMY_SPEED = 1
JOY_DEADZONE = 0.2
def dump_obj(obj):
for key in sorted(vars(obj)):
val = getattr(obj, key)
print("{:30} = {} ({})".format(key, val, type(val).__name__))
def dump_joystick(joy):
print("========== {}".format(joy))
print("x {}".format(joy.x))
print("y {}".format(joy.y))
print("z {}".format(joy.z))
print("rx {}".format(joy.rx))
print("ry {}".format(joy.ry))
print("rz {}".format(joy.rz))
print("hat_x {}".format(joy.hat_x))
print("hat_y {}".format(joy.hat_y))
print("buttons {}".format(joy.buttons))
print("========== Extra joy")
dump_obj(joy)
print("========== Extra joy.device")
dump_obj(joy.device)
print("========== pprint joy")
pprint.pprint(joy)
print("========== pprint joy.device")
pprint.pprint(joy.device)
def dump_joystick_state(ticks, joy):
# print("{:5.2f} {:5.2f} {:>20} {:5}_".format(1.234567, -8.2757272903, "hello", str(True)))
fmt_str = "{:6d} "
num_fmts = ["{:5.2f}"] * 6
fmt_str += " ".join(num_fmts)
fmt_str += " {:2d} {:2d} {}"
buttons = " ".join(["{:5}".format(str(b)) for b in joy.buttons])
print(fmt_str.format(ticks,
joy.x,
joy.y,
joy.z,
joy.rx,
joy.ry,
joy.rz,
joy.hat_x,
joy.hat_y,
buttons))
def get_joy_position(x, y):
"""Given position of joystick axes, return (x, y, angle_in_degrees).
If movement is not outside of deadzone, return (None, None, None)"""
if x > JOY_DEADZONE or x < -JOY_DEADZONE or y > JOY_DEADZONE or y < -JOY_DEADZONE:
y = -y
rad = math.atan2(y, x)
angle = math.degrees(rad)
return x, y, angle
return None, None, None
class Player(arcade.sprite.Sprite):
def __init__(self, filename):
super().__init__(filename=filename, scale=0.4, center_x=SCREEN_WIDTH/2, center_y=SCREEN_HEIGHT/2)
self.shoot_up_pressed = False
self.shoot_down_pressed = False
self.shoot_left_pressed = False
self.shoot_right_pressed = False
class Enemy(arcade.sprite.Sprite):
def __init__(self, x, y):
super().__init__(filename='images/bumper.png', scale=0.5, center_x=x, center_y=y)
def follow_sprite(self, player_sprite):
"""
This function will move the current sprite towards whatever
other sprite is specified as a parameter.
We use the 'min' function here to get the sprite to line up with
the target sprite, and not jump around if the sprite is not off
an exact multiple of ENEMY_SPEED.
"""
if self.center_y < player_sprite.center_y:
self.center_y += min(ENEMY_SPEED, player_sprite.center_y - self.center_y)
elif self.center_y > player_sprite.center_y:
self.center_y -= min(ENEMY_SPEED, self.center_y - player_sprite.center_y)
if self.center_x < player_sprite.center_x:
self.center_x += min(ENEMY_SPEED, player_sprite.center_x - self.center_x)
elif self.center_x > player_sprite.center_x:
self.center_x -= min(ENEMY_SPEED, self.center_x - player_sprite.center_x)
class MyGame(arcade.Window):
def __init__(self, width, height, title):
super().__init__(width, height, 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)
arcade.set_background_color(arcade.color.DARK_MIDNIGHT_BLUE)
self.game_over = False
self.score = 0
self.tick = 0
self.bullet_cooldown = 0
self.player = Player("images/playerShip2_orange.png")
self.bullet_list = arcade.SpriteList()
self.enemy_list = arcade.SpriteList()
self.joy = None
joys = arcade.get_joysticks()
for joy in joys:
dump_joystick(joy)
if joys:
self.joy = joys[0]
self.joy.open()
print("Using joystick controls: {}".format(self.joy.device))
arcade.window_commands.schedule(self.debug_joy_state, 0.1)
if not self.joy:
print("No joystick present, using keyboard controls")
arcade.window_commands.schedule(self.spawn_enemy, ENEMY_SPAWN_INTERVAL)
def debug_joy_state(self, delta_time):
dump_joystick_state(self.tick, self.joy)
def spawn_enemy(self, elapsed):
if self.game_over:
return
x = random.randint(0, SCREEN_WIDTH)
y = random.randint(0, SCREEN_HEIGHT)
self.enemy_list.append(Enemy(x, y))
def update(self, delta_time):
self.tick += 1
if self.game_over:
return
self.bullet_cooldown += 1
for enemy in self.enemy_list:
cast(Enemy, enemy).follow_sprite(self.player)
if self.joy:
# Joystick input - movement
move_x, move_y, move_angle = get_joy_position(self.joy.x, self.joy.y)
if move_angle:
self.player.change_x = move_x * MOVEMENT_SPEED
self.player.change_y = move_y * MOVEMENT_SPEED
# An angle of "0" means "right", but the player's image is drawn in the "up" direction.
# So an offset is needed.
self.player.angle = move_angle - 90
else:
self.player.change_x = 0
self.player.change_y = 0
# Joystick input - shooting
shoot_x, shoot_y, shoot_angle = get_joy_position(self.joy.z, self.joy.rz)
if shoot_angle:
self.spawn_bullet(shoot_angle)
else:
# Keyboard input - shooting
if self.player.shoot_right_pressed and self.player.shoot_up_pressed:
self.spawn_bullet(0+45)
elif self.player.shoot_up_pressed and self.player.shoot_left_pressed:
self.spawn_bullet(90+45)
elif self.player.shoot_left_pressed and self.player.shoot_down_pressed:
self.spawn_bullet(180+45)
elif self.player.shoot_down_pressed and self.player.shoot_right_pressed:
self.spawn_bullet(270+45)
elif self.player.shoot_right_pressed:
self.spawn_bullet(0)
elif self.player.shoot_up_pressed:
self.spawn_bullet(90)
elif self.player.shoot_left_pressed:
self.spawn_bullet(180)
elif self.player.shoot_down_pressed:
self.spawn_bullet(270)
self.enemy_list.update()
self.player.update()
self.bullet_list.update()
ship_death_hit_list = arcade.check_for_collision_with_list(self.player, self.enemy_list)
if len(ship_death_hit_list) > 0:
self.game_over = True
for bullet in self.bullet_list:
bullet_killed = False
enemy_shot_list = arcade.check_for_collision_with_list(bullet, self.enemy_list)
# Loop through each colliding sprite, remove it, and add to the score.
for enemy in enemy_shot_list:
enemy.kill()
bullet.kill()
bullet_killed = True
self.score += 1
if bullet_killed:
continue
def on_key_press(self, key, modifiers):
if key == arcade.key.W:
self.player.change_y = MOVEMENT_SPEED
self.player.angle = 0
elif key == arcade.key.A:
self.player.change_x = -MOVEMENT_SPEED
self.player.angle = 90
elif key == arcade.key.S:
self.player.change_y = -MOVEMENT_SPEED
self.player.angle = 180
elif key == arcade.key.D:
self.player.change_x = MOVEMENT_SPEED
self.player.angle = 270
elif key == arcade.key.RIGHT:
self.player.shoot_right_pressed = True
elif key == arcade.key.UP:
self.player.shoot_up_pressed = True
elif key == arcade.key.LEFT:
self.player.shoot_left_pressed = True
elif key == arcade.key.DOWN:
self.player.shoot_down_pressed = True
def on_key_release(self, key, modifiers):
if key == arcade.key.W:
self.player.change_y = 0
elif key == arcade.key.A:
self.player.change_x = 0
elif key == arcade.key.S:
self.player.change_y = 0
elif key == arcade.key.D:
self.player.change_x = 0
elif key == arcade.key.RIGHT:
self.player.shoot_right_pressed = False
elif key == arcade.key.UP:
self.player.shoot_up_pressed = False
elif key == arcade.key.LEFT:
self.player.shoot_left_pressed = False
elif key == arcade.key.DOWN:
self.player.shoot_down_pressed = False
def spawn_bullet(self, angle_in_deg):
# only allow bullet to spawn on an interval
if self.bullet_cooldown < BULLET_COOLDOWN_TICKS:
return
self.bullet_cooldown = 0
bullet = arcade.Sprite("images/laserBlue01.png", 0.75)
# Position the bullet at the player's current location
start_x = self.player.center_x
start_y = self.player.center_y
bullet.center_x = start_x
bullet.center_y = start_y
# angle the bullet visually
bullet.angle = angle_in_deg
angle_in_rad = math.radians(angle_in_deg)
# set bullet's movement direction
bullet.change_x = math.cos(angle_in_rad) * BULLET_SPEED
bullet.change_y = math.sin(angle_in_rad) * BULLET_SPEED
# Add the bullet to the appropriate lists
self.bullet_list.append(bullet)
def on_draw(self):
# clear screen and start render process
arcade.start_render()
# draw game items
self.bullet_list.draw()
self.enemy_list.draw()
self.player.draw()
# Put the score on the screen.
output = f"Score: {self.score}"
arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)
# Game over message
if self.game_over:
arcade.draw_text("Game Over", SCREEN_WIDTH/2, SCREEN_HEIGHT/2, arcade.color.WHITE, 100, width=SCREEN_WIDTH,
align="center", anchor_x="center", anchor_y="center")
if __name__ == "__main__":
game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.run()

777
arcade/examples/dungeon.tmx Normal file
View File

@ -0,0 +1,777 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" tiledversion="1.1.5" orientation="isometric" renderorder="right-down" width="10" height="10" tilewidth="256" tileheight="149" infinite="0" nextobjectid="1">
<tileset firstgid="1" name="Dungeon" tilewidth="256" tileheight="512" tilecount="252" columns="0">
<grid orientation="orthogonal" width="1" height="1"/>
<tile id="0">
<image width="256" height="512" source="isometric_dungeon/barrel_E.png"/>
</tile>
<tile id="1">
<image width="256" height="512" source="isometric_dungeon/barrel_N.png"/>
</tile>
<tile id="2">
<image width="256" height="512" source="isometric_dungeon/barrel_S.png"/>
</tile>
<tile id="3">
<image width="256" height="512" source="isometric_dungeon/barrel_W.png"/>
</tile>
<tile id="4">
<image width="256" height="512" source="isometric_dungeon/barrels_E.png"/>
</tile>
<tile id="5">
<image width="256" height="512" source="isometric_dungeon/barrels_N.png"/>
</tile>
<tile id="6">
<image width="256" height="512" source="isometric_dungeon/barrels_S.png"/>
</tile>
<tile id="7">
<image width="256" height="512" source="isometric_dungeon/barrels_W.png"/>
</tile>
<tile id="8">
<image width="256" height="512" source="isometric_dungeon/barrelsStacked_E.png"/>
</tile>
<tile id="9">
<image width="256" height="512" source="isometric_dungeon/barrelsStacked_N.png"/>
</tile>
<tile id="10">
<image width="256" height="512" source="isometric_dungeon/barrelsStacked_S.png"/>
</tile>
<tile id="11">
<image width="256" height="512" source="isometric_dungeon/barrelsStacked_W.png"/>
</tile>
<tile id="12">
<image width="256" height="512" source="isometric_dungeon/bridge_E.png"/>
</tile>
<tile id="13">
<image width="256" height="512" source="isometric_dungeon/bridge_N.png"/>
</tile>
<tile id="14">
<image width="256" height="512" source="isometric_dungeon/bridge_S.png"/>
</tile>
<tile id="15">
<image width="256" height="512" source="isometric_dungeon/bridge_W.png"/>
</tile>
<tile id="16">
<image width="256" height="512" source="isometric_dungeon/bridgeBroken_E.png"/>
</tile>
<tile id="17">
<image width="256" height="512" source="isometric_dungeon/bridgeBroken_N.png"/>
</tile>
<tile id="18">
<image width="256" height="512" source="isometric_dungeon/bridgeBroken_S.png"/>
</tile>
<tile id="19">
<image width="256" height="512" source="isometric_dungeon/bridgeBroken_W.png"/>
</tile>
<tile id="20">
<image width="256" height="512" source="isometric_dungeon/chair_E.png"/>
</tile>
<tile id="21">
<image width="256" height="512" source="isometric_dungeon/chair_N.png"/>
</tile>
<tile id="22">
<image width="256" height="512" source="isometric_dungeon/chair_S.png"/>
</tile>
<tile id="23">
<image width="256" height="512" source="isometric_dungeon/chair_W.png"/>
</tile>
<tile id="24">
<image width="256" height="512" source="isometric_dungeon/chestClosed_E.png"/>
</tile>
<tile id="25">
<image width="256" height="512" source="isometric_dungeon/chestClosed_N.png"/>
</tile>
<tile id="26">
<image width="256" height="512" source="isometric_dungeon/chestClosed_S.png"/>
</tile>
<tile id="27">
<image width="256" height="512" source="isometric_dungeon/chestClosed_W.png"/>
</tile>
<tile id="28">
<image width="256" height="512" source="isometric_dungeon/chestOpen_E.png"/>
</tile>
<tile id="29">
<image width="256" height="512" source="isometric_dungeon/chestOpen_N.png"/>
</tile>
<tile id="30">
<image width="256" height="512" source="isometric_dungeon/chestOpen_S.png"/>
</tile>
<tile id="31">
<image width="256" height="512" source="isometric_dungeon/chestOpen_W.png"/>
</tile>
<tile id="32">
<image width="256" height="512" source="isometric_dungeon/dirt_E.png"/>
</tile>
<tile id="33">
<image width="256" height="512" source="isometric_dungeon/dirt_N.png"/>
</tile>
<tile id="34">
<image width="256" height="512" source="isometric_dungeon/dirt_S.png"/>
</tile>
<tile id="35">
<image width="256" height="512" source="isometric_dungeon/dirt_W.png"/>
</tile>
<tile id="36">
<image width="256" height="512" source="isometric_dungeon/dirtTiles_E.png"/>
</tile>
<tile id="37">
<image width="256" height="512" source="isometric_dungeon/dirtTiles_N.png"/>
</tile>
<tile id="38">
<image width="256" height="512" source="isometric_dungeon/dirtTiles_S.png"/>
</tile>
<tile id="39">
<image width="256" height="512" source="isometric_dungeon/dirtTiles_W.png"/>
</tile>
<tile id="40">
<image width="256" height="512" source="isometric_dungeon/planks_E.png"/>
</tile>
<tile id="41">
<image width="256" height="512" source="isometric_dungeon/planks_N.png"/>
</tile>
<tile id="42">
<image width="256" height="512" source="isometric_dungeon/planks_S.png"/>
</tile>
<tile id="43">
<image width="256" height="512" source="isometric_dungeon/planks_W.png"/>
</tile>
<tile id="44">
<image width="256" height="512" source="isometric_dungeon/planksBroken_E.png"/>
</tile>
<tile id="45">
<image width="256" height="512" source="isometric_dungeon/planksBroken_N.png"/>
</tile>
<tile id="46">
<image width="256" height="512" source="isometric_dungeon/planksBroken_S.png"/>
</tile>
<tile id="47">
<image width="256" height="512" source="isometric_dungeon/planksBroken_W.png"/>
</tile>
<tile id="48">
<image width="256" height="512" source="isometric_dungeon/planksHole_E.png"/>
</tile>
<tile id="49">
<image width="256" height="512" source="isometric_dungeon/planksHole_N.png"/>
</tile>
<tile id="50">
<image width="256" height="512" source="isometric_dungeon/planksHole_S.png"/>
</tile>
<tile id="51">
<image width="256" height="512" source="isometric_dungeon/planksHole_W.png"/>
</tile>
<tile id="52">
<image width="256" height="512" source="isometric_dungeon/stairs_E.png"/>
</tile>
<tile id="53">
<image width="256" height="512" source="isometric_dungeon/stairs_N.png"/>
</tile>
<tile id="54">
<image width="256" height="512" source="isometric_dungeon/stairs_S.png"/>
</tile>
<tile id="55">
<image width="256" height="512" source="isometric_dungeon/stairs_W.png"/>
</tile>
<tile id="56">
<image width="256" height="512" source="isometric_dungeon/stairsAged_E.png"/>
</tile>
<tile id="57">
<image width="256" height="512" source="isometric_dungeon/stairsAged_N.png"/>
</tile>
<tile id="58">
<image width="256" height="512" source="isometric_dungeon/stairsAged_S.png"/>
</tile>
<tile id="59">
<image width="256" height="512" source="isometric_dungeon/stairsAged_W.png"/>
</tile>
<tile id="60">
<image width="256" height="512" source="isometric_dungeon/stairsSpiral_E.png"/>
</tile>
<tile id="61">
<image width="256" height="512" source="isometric_dungeon/stairsSpiral_N.png"/>
</tile>
<tile id="62">
<image width="256" height="512" source="isometric_dungeon/stairsSpiral_S.png"/>
</tile>
<tile id="63">
<image width="256" height="512" source="isometric_dungeon/stairsSpiral_W.png"/>
</tile>
<tile id="64">
<image width="256" height="512" source="isometric_dungeon/stone_E.png"/>
</tile>
<tile id="65">
<image width="256" height="512" source="isometric_dungeon/stone_N.png"/>
</tile>
<tile id="66">
<image width="256" height="512" source="isometric_dungeon/stone_S.png"/>
</tile>
<tile id="67">
<image width="256" height="512" source="isometric_dungeon/stone_W.png"/>
</tile>
<tile id="68">
<image width="256" height="512" source="isometric_dungeon/stoneColumn_E.png"/>
</tile>
<tile id="69">
<image width="256" height="512" source="isometric_dungeon/stoneColumn_N.png"/>
</tile>
<tile id="70">
<image width="256" height="512" source="isometric_dungeon/stoneColumn_S.png"/>
</tile>
<tile id="71">
<image width="256" height="512" source="isometric_dungeon/stoneColumn_W.png"/>
</tile>
<tile id="72">
<image width="256" height="512" source="isometric_dungeon/stoneColumnWood_E.png"/>
</tile>
<tile id="73">
<image width="256" height="512" source="isometric_dungeon/stoneColumnWood_N.png"/>
</tile>
<tile id="74">
<image width="256" height="512" source="isometric_dungeon/stoneColumnWood_S.png"/>
</tile>
<tile id="75">
<image width="256" height="512" source="isometric_dungeon/stoneColumnWood_W.png"/>
</tile>
<tile id="76">
<image width="256" height="512" source="isometric_dungeon/stoneLeft_E.png"/>
</tile>
<tile id="77">
<image width="256" height="512" source="isometric_dungeon/stoneLeft_N.png"/>
</tile>
<tile id="78">
<image width="256" height="512" source="isometric_dungeon/stoneLeft_S.png"/>
</tile>
<tile id="79">
<image width="256" height="512" source="isometric_dungeon/stoneLeft_W.png"/>
</tile>
<tile id="80">
<image width="256" height="512" source="isometric_dungeon/stoneMissingTiles_E.png"/>
</tile>
<tile id="81">
<image width="256" height="512" source="isometric_dungeon/stoneMissingTiles_N.png"/>
</tile>
<tile id="82">
<image width="256" height="512" source="isometric_dungeon/stoneMissingTiles_S.png"/>
</tile>
<tile id="83">
<image width="256" height="512" source="isometric_dungeon/stoneMissingTiles_W.png"/>
</tile>
<tile id="84">
<image width="256" height="512" source="isometric_dungeon/stoneRight_E.png"/>
</tile>
<tile id="85">
<image width="256" height="512" source="isometric_dungeon/stoneRight_N.png"/>
</tile>
<tile id="86">
<image width="256" height="512" source="isometric_dungeon/stoneRight_S.png"/>
</tile>
<tile id="87">
<image width="256" height="512" source="isometric_dungeon/stoneRight_W.png"/>
</tile>
<tile id="88">
<image width="256" height="512" source="isometric_dungeon/stoneSide_E.png"/>
</tile>
<tile id="89">
<image width="256" height="512" source="isometric_dungeon/stoneSide_N.png"/>
</tile>
<tile id="90">
<image width="256" height="512" source="isometric_dungeon/stoneSide_S.png"/>
</tile>
<tile id="91">
<image width="256" height="512" source="isometric_dungeon/stoneSide_W.png"/>
</tile>
<tile id="92">
<image width="256" height="512" source="isometric_dungeon/stoneSideUneven_E.png"/>
</tile>
<tile id="93">
<image width="256" height="512" source="isometric_dungeon/stoneSideUneven_N.png"/>
</tile>
<tile id="94">
<image width="256" height="512" source="isometric_dungeon/stoneSideUneven_S.png"/>
</tile>
<tile id="95">
<image width="256" height="512" source="isometric_dungeon/stoneSideUneven_W.png"/>
</tile>
<tile id="96">
<image width="256" height="512" source="isometric_dungeon/stoneStep_E.png"/>
</tile>
<tile id="97">
<image width="256" height="512" source="isometric_dungeon/stoneStep_N.png"/>
</tile>
<tile id="98">
<image width="256" height="512" source="isometric_dungeon/stoneStep_S.png"/>
</tile>
<tile id="99">
<image width="256" height="512" source="isometric_dungeon/stoneStep_W.png"/>
</tile>
<tile id="100">
<image width="256" height="512" source="isometric_dungeon/stoneSteps_E.png"/>
</tile>
<tile id="101">
<image width="256" height="512" source="isometric_dungeon/stoneSteps_N.png"/>
</tile>
<tile id="102">
<image width="256" height="512" source="isometric_dungeon/stoneSteps_S.png"/>
</tile>
<tile id="103">
<image width="256" height="512" source="isometric_dungeon/stoneSteps_W.png"/>
</tile>
<tile id="104">
<image width="256" height="512" source="isometric_dungeon/stoneTile_E.png"/>
</tile>
<tile id="105">
<image width="256" height="512" source="isometric_dungeon/stoneTile_N.png"/>
</tile>
<tile id="106">
<image width="256" height="512" source="isometric_dungeon/stoneTile_S.png"/>
</tile>
<tile id="107">
<image width="256" height="512" source="isometric_dungeon/stoneTile_W.png"/>
</tile>
<tile id="108">
<image width="256" height="512" source="isometric_dungeon/stoneUneven_E.png"/>
</tile>
<tile id="109">
<image width="256" height="512" source="isometric_dungeon/stoneUneven_N.png"/>
</tile>
<tile id="110">
<image width="256" height="512" source="isometric_dungeon/stoneUneven_S.png"/>
</tile>
<tile id="111">
<image width="256" height="512" source="isometric_dungeon/stoneUneven_W.png"/>
</tile>
<tile id="112">
<image width="256" height="512" source="isometric_dungeon/stoneWall_E.png"/>
</tile>
<tile id="113">
<image width="256" height="512" source="isometric_dungeon/stoneWall_N.png"/>
</tile>
<tile id="114">
<image width="256" height="512" source="isometric_dungeon/stoneWall_S.png"/>
</tile>
<tile id="115">
<image width="256" height="512" source="isometric_dungeon/stoneWall_W.png"/>
</tile>
<tile id="116">
<image width="256" height="512" source="isometric_dungeon/stoneWallAged_E.png"/>
</tile>
<tile id="117">
<image width="256" height="512" source="isometric_dungeon/stoneWallAged_N.png"/>
</tile>
<tile id="118">
<image width="256" height="512" source="isometric_dungeon/stoneWallAged_S.png"/>
</tile>
<tile id="119">
<image width="256" height="512" source="isometric_dungeon/stoneWallAged_W.png"/>
</tile>
<tile id="120">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedLeft_E.png"/>
</tile>
<tile id="121">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedLeft_N.png"/>
</tile>
<tile id="122">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedLeft_S.png"/>
</tile>
<tile id="123">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedLeft_W.png"/>
</tile>
<tile id="124">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedRight_E.png"/>
</tile>
<tile id="125">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedRight_N.png"/>
</tile>
<tile id="126">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedRight_S.png"/>
</tile>
<tile id="127">
<image width="256" height="512" source="isometric_dungeon/stoneWallAgedRight_W.png"/>
</tile>
<tile id="128">
<image width="256" height="512" source="isometric_dungeon/stoneWallArchway_E.png"/>
</tile>
<tile id="129">
<image width="256" height="512" source="isometric_dungeon/stoneWallArchway_N.png"/>
</tile>
<tile id="130">
<image width="256" height="512" source="isometric_dungeon/stoneWallArchway_S.png"/>
</tile>
<tile id="131">
<image width="256" height="512" source="isometric_dungeon/stoneWallArchway_W.png"/>
</tile>
<tile id="132">
<image width="256" height="512" source="isometric_dungeon/stoneWallBroken_E.png"/>
</tile>
<tile id="133">
<image width="256" height="512" source="isometric_dungeon/stoneWallBroken_N.png"/>
</tile>
<tile id="134">
<image width="256" height="512" source="isometric_dungeon/stoneWallBroken_S.png"/>
</tile>
<tile id="135">
<image width="256" height="512" source="isometric_dungeon/stoneWallBroken_W.png"/>
</tile>
<tile id="136">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenLeft_E.png"/>
</tile>
<tile id="137">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenLeft_N.png"/>
</tile>
<tile id="138">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenLeft_S.png"/>
</tile>
<tile id="139">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenLeft_W.png"/>
</tile>
<tile id="140">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenRight_E.png"/>
</tile>
<tile id="141">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenRight_N.png"/>
</tile>
<tile id="142">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenRight_S.png"/>
</tile>
<tile id="143">
<image width="256" height="512" source="isometric_dungeon/stoneWallBrokenRight_W.png"/>
</tile>
<tile id="144">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumn_E.png"/>
</tile>
<tile id="145">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumn_N.png"/>
</tile>
<tile id="146">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumn_S.png"/>
</tile>
<tile id="147">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumn_W.png"/>
</tile>
<tile id="148">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumnIn_E.png"/>
</tile>
<tile id="149">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumnIn_N.png"/>
</tile>
<tile id="150">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumnIn_S.png"/>
</tile>
<tile id="151">
<image width="256" height="512" source="isometric_dungeon/stoneWallColumnIn_W.png"/>
</tile>
<tile id="152">
<image width="256" height="512" source="isometric_dungeon/stoneWallCorner_E.png"/>
</tile>
<tile id="153">
<image width="256" height="512" source="isometric_dungeon/stoneWallCorner_N.png"/>
</tile>
<tile id="154">
<image width="256" height="512" source="isometric_dungeon/stoneWallCorner_S.png"/>
</tile>
<tile id="155">
<image width="256" height="512" source="isometric_dungeon/stoneWallCorner_W.png"/>
</tile>
<tile id="156">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoor_E.png"/>
</tile>
<tile id="157">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoor_N.png"/>
</tile>
<tile id="158">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoor_S.png"/>
</tile>
<tile id="159">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoor_W.png"/>
</tile>
<tile id="160">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorBars_E.png"/>
</tile>
<tile id="161">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorBars_N.png"/>
</tile>
<tile id="162">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorBars_S.png"/>
</tile>
<tile id="163">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorBars_W.png"/>
</tile>
<tile id="164">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorClosed_E.png"/>
</tile>
<tile id="165">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorClosed_N.png"/>
</tile>
<tile id="166">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorClosed_S.png"/>
</tile>
<tile id="167">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorClosed_W.png"/>
</tile>
<tile id="168">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorOpen_E.png"/>
</tile>
<tile id="169">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorOpen_N.png"/>
</tile>
<tile id="170">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorOpen_S.png"/>
</tile>
<tile id="171">
<image width="256" height="512" source="isometric_dungeon/stoneWallDoorOpen_W.png"/>
</tile>
<tile id="172">
<image width="256" height="512" source="isometric_dungeon/stoneWallGate_E.png"/>
</tile>
<tile id="173">
<image width="256" height="512" source="isometric_dungeon/stoneWallGate_N.png"/>
</tile>
<tile id="174">
<image width="256" height="512" source="isometric_dungeon/stoneWallGate_S.png"/>
</tile>
<tile id="175">
<image width="256" height="512" source="isometric_dungeon/stoneWallGate_W.png"/>
</tile>
<tile id="176">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateBars_E.png"/>
</tile>
<tile id="177">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateBars_N.png"/>
</tile>
<tile id="178">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateBars_S.png"/>
</tile>
<tile id="179">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateBars_W.png"/>
</tile>
<tile id="180">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateClosed_E.png"/>
</tile>
<tile id="181">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateClosed_N.png"/>
</tile>
<tile id="182">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateClosed_S.png"/>
</tile>
<tile id="183">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateClosed_W.png"/>
</tile>
<tile id="184">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateOpen_E.png"/>
</tile>
<tile id="185">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateOpen_N.png"/>
</tile>
<tile id="186">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateOpen_S.png"/>
</tile>
<tile id="187">
<image width="256" height="512" source="isometric_dungeon/stoneWallGateOpen_W.png"/>
</tile>
<tile id="188">
<image width="256" height="512" source="isometric_dungeon/stoneWallHole_E.png"/>
</tile>
<tile id="189">
<image width="256" height="512" source="isometric_dungeon/stoneWallHole_N.png"/>
</tile>
<tile id="190">
<image width="256" height="512" source="isometric_dungeon/stoneWallHole_S.png"/>
</tile>
<tile id="191">
<image width="256" height="512" source="isometric_dungeon/stoneWallHole_W.png"/>
</tile>
<tile id="192">
<image width="256" height="512" source="isometric_dungeon/stoneWallTop_E.png"/>
</tile>
<tile id="193">
<image width="256" height="512" source="isometric_dungeon/stoneWallTop_N.png"/>
</tile>
<tile id="194">
<image width="256" height="512" source="isometric_dungeon/stoneWallTop_S.png"/>
</tile>
<tile id="195">
<image width="256" height="512" source="isometric_dungeon/stoneWallTop_W.png"/>
</tile>
<tile id="196">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindow_E.png"/>
</tile>
<tile id="197">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindow_N.png"/>
</tile>
<tile id="198">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindow_S.png"/>
</tile>
<tile id="199">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindow_W.png"/>
</tile>
<tile id="200">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindowBars_E.png"/>
</tile>
<tile id="201">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindowBars_N.png"/>
</tile>
<tile id="202">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindowBars_S.png"/>
</tile>
<tile id="203">
<image width="256" height="512" source="isometric_dungeon/stoneWallWindowBars_W.png"/>
</tile>
<tile id="204">
<image width="256" height="512" source="isometric_dungeon/tableChairsBroken_E.png"/>
</tile>
<tile id="205">
<image width="256" height="512" source="isometric_dungeon/tableChairsBroken_N.png"/>
</tile>
<tile id="206">
<image width="256" height="512" source="isometric_dungeon/tableChairsBroken_S.png"/>
</tile>
<tile id="207">
<image width="256" height="512" source="isometric_dungeon/tableChairsBroken_W.png"/>
</tile>
<tile id="208">
<image width="256" height="512" source="isometric_dungeon/tableRound_E.png"/>
</tile>
<tile id="209">
<image width="256" height="512" source="isometric_dungeon/tableRound_N.png"/>
</tile>
<tile id="210">
<image width="256" height="512" source="isometric_dungeon/tableRound_S.png"/>
</tile>
<tile id="211">
<image width="256" height="512" source="isometric_dungeon/tableRound_W.png"/>
</tile>
<tile id="212">
<image width="256" height="512" source="isometric_dungeon/tableRoundChairs_E.png"/>
</tile>
<tile id="213">
<image width="256" height="512" source="isometric_dungeon/tableRoundChairs_N.png"/>
</tile>
<tile id="214">
<image width="256" height="512" source="isometric_dungeon/tableRoundChairs_S.png"/>
</tile>
<tile id="215">
<image width="256" height="512" source="isometric_dungeon/tableRoundChairs_W.png"/>
</tile>
<tile id="216">
<image width="256" height="512" source="isometric_dungeon/tableShort_E.png"/>
</tile>
<tile id="217">
<image width="256" height="512" source="isometric_dungeon/tableShort_N.png"/>
</tile>
<tile id="218">
<image width="256" height="512" source="isometric_dungeon/tableShort_S.png"/>
</tile>
<tile id="219">
<image width="256" height="512" source="isometric_dungeon/tableShort_W.png"/>
</tile>
<tile id="220">
<image width="256" height="512" source="isometric_dungeon/tableShortChairs_E.png"/>
</tile>
<tile id="221">
<image width="256" height="512" source="isometric_dungeon/tableShortChairs_N.png"/>
</tile>
<tile id="222">
<image width="256" height="512" source="isometric_dungeon/tableShortChairs_S.png"/>
</tile>
<tile id="223">
<image width="256" height="512" source="isometric_dungeon/tableShortChairs_W.png"/>
</tile>
<tile id="224">
<image width="256" height="512" source="isometric_dungeon/woodenCrate_E.png"/>
</tile>
<tile id="225">
<image width="256" height="512" source="isometric_dungeon/woodenCrate_N.png"/>
</tile>
<tile id="226">
<image width="256" height="512" source="isometric_dungeon/woodenCrate_S.png"/>
</tile>
<tile id="227">
<image width="256" height="512" source="isometric_dungeon/woodenCrate_W.png"/>
</tile>
<tile id="228">
<image width="256" height="512" source="isometric_dungeon/woodenCrates_E.png"/>
</tile>
<tile id="229">
<image width="256" height="512" source="isometric_dungeon/woodenCrates_N.png"/>
</tile>
<tile id="230">
<image width="256" height="512" source="isometric_dungeon/woodenCrates_S.png"/>
</tile>
<tile id="231">
<image width="256" height="512" source="isometric_dungeon/woodenCrates_W.png"/>
</tile>
<tile id="232">
<image width="256" height="512" source="isometric_dungeon/woodenPile_E.png"/>
</tile>
<tile id="233">
<image width="256" height="512" source="isometric_dungeon/woodenPile_N.png"/>
</tile>
<tile id="234">
<image width="256" height="512" source="isometric_dungeon/woodenPile_S.png"/>
</tile>
<tile id="235">
<image width="256" height="512" source="isometric_dungeon/woodenPile_W.png"/>
</tile>
<tile id="236">
<image width="256" height="512" source="isometric_dungeon/woodenSupportBeams_E.png"/>
</tile>
<tile id="237">
<image width="256" height="512" source="isometric_dungeon/woodenSupportBeams_N.png"/>
</tile>
<tile id="238">
<image width="256" height="512" source="isometric_dungeon/woodenSupportBeams_S.png"/>
</tile>
<tile id="239">
<image width="256" height="512" source="isometric_dungeon/woodenSupportBeams_W.png"/>
</tile>
<tile id="240">
<image width="256" height="512" source="isometric_dungeon/woodenSupports_E.png"/>
</tile>
<tile id="241">
<image width="256" height="512" source="isometric_dungeon/woodenSupports_N.png"/>
</tile>
<tile id="242">
<image width="256" height="512" source="isometric_dungeon/woodenSupports_S.png"/>
</tile>
<tile id="243">
<image width="256" height="512" source="isometric_dungeon/woodenSupports_W.png"/>
</tile>
<tile id="244">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBeam_E.png"/>
</tile>
<tile id="245">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBeam_N.png"/>
</tile>
<tile id="246">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBeam_S.png"/>
</tile>
<tile id="247">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBeam_W.png"/>
</tile>
<tile id="248">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBlock_E.png"/>
</tile>
<tile id="249">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBlock_N.png"/>
</tile>
<tile id="250">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBlock_S.png"/>
</tile>
<tile id="251">
<image width="256" height="512" source="isometric_dungeon/woodenSupportsBlock_W.png"/>
</tile>
</tileset>
<layer name="Floor" width="10" height="10">
<data encoding="base64" compression="zlib">
eJxtkEsOgCAMRLmN5+CzNuGzceMBVIT7ryzJa0KIi5d2YEpHgzHGCYl6CV3wYH9qEF5qE25mdN6iA7qiI9487fT4duHEVznzE453N+HgfujCO1obvWXG4Y30mtNPnkzOTL7hf7iLyzdqrsZMXPZ1+sY/KvgTWndrpoo/c/4BPasgKg==
</data>
</layer>
<layer name="Walls" width="10" height="10">
<data encoding="base64" compression="zlib">
eJybxcDAUATFM5HYRWjiJQwIsJMBOyiFqpuIxC9Hws1QejaaeaUkmIdPHQxspdC8nSS6jxh1c4C4GIpnI7GL0cQBoyMZ0g==
</data>
</layer>
<layer name="Furniture" width="10" height="10">
<data encoding="base64" compression="zlib">
eJx7wUB98IBC/d/R+GcpNG8oAQAw7AON
</data>
</layer>
</map>

View File

@ -0,0 +1,58 @@
"""
Helper class to track length of time taken for each frame and draw a graph when application exits.
Also able to add events at arbitrary times across the graph.
"""
import time
import matplotlib.pyplot as plt
import statistics
class FrametimePlotter:
EVENT_POINT_Y = -0.05
EVENT_MSG_Y = -0.045
def __init__(self):
self.times = []
self.events = []
self.start = time.perf_counter()
def add_event(self, event_msg):
self.events.append((len(self.times), event_msg))
def end_frame(self, time_delta):
self.times.append(time_delta)
def _show_stats(self):
end = time.perf_counter()
print("Min : {:.5f}".format(min(self.times)))
print("Max : {:.5f}".format(max(self.times)))
print("Avg : {:.5f}".format(statistics.mean(self.times)))
print("Median: {:.5f}".format(statistics.median(self.times)))
try:
print("Mode : {:.5f}".format(statistics.mode(self.times)))
except statistics.StatisticsError as e:
print("Mode : {}".format(e))
print("StdDev: {:.5f}".format(statistics.stdev(self.times)))
frame_count = len(self.times)
elapsed_time = end - self.start
print("Frame count: {}".format(frame_count))
print("Elapsed time: {:.5f}".format(elapsed_time))
print("FPS: {:.5f}".format(frame_count / elapsed_time))
def show(self):
if len(self.times) <= 1:
return
self._show_stats()
frame_idxs = range(0, len(self.times))
event_idxs = [e[0] for e in self.events]
event_point_y = [self.EVENT_POINT_Y] * len(self.events)
plt.figure("Frame durations", figsize=(8, 6))
plt.plot(frame_idxs, self.times, event_idxs, event_point_y, "k|")
plt.xlabel("frames")
plt.ylabel("frame duration")
plt.ylim(self.EVENT_POINT_Y - 0.005, 0.5)
plt.tight_layout()
for frame_idx, msg in self.events:
plt.text(frame_idx, self.EVENT_MSG_Y, msg, horizontalalignment="center", verticalalignment="bottom",
size="smaller", rotation="vertical")
plt.show()

View File

@ -0,0 +1,108 @@
"""
Use sprites to scroll around a large screen.
Simple program to show basic sprite usage.
Artwork from http://kenney.nl
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.full_screen_example
"""
import arcade
import os
SPRITE_SCALING = 0.5
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Full Screen Example"
# How many pixels to keep as a minimum margin between the character
# and the edge of the screen.
VIEWPORT_MARGIN = 40
MOVEMENT_SPEED = 5
class MyGame(arcade.Window):
""" Main application class. """
def __init__(self):
"""
Initializer
"""
# Open a window in full screen mode. Remove fullscreen=True if
# you don't want to start this way.
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, fullscreen=True)
# 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)
# This will get the size of the window, and set the viewport to match.
# So if the window is 1000x1000, then so will our viewport. If
# you want something different, then use those coordinates instead.
width, height = self.get_size()
self.set_viewport(0, width, 0, height)
arcade.set_background_color(arcade.color.AMAZON)
self.example_image = arcade.load_texture("images/boxCrate_double.png")
def on_draw(self):
"""
Render the screen.
"""
arcade.start_render()
# Get viewport dimensions
left, screen_width, bottom, screen_height = self.get_viewport()
text_size = 18
# Draw text on the screen so the user has an idea of what is happening
arcade.draw_text("Press F to toggle between full screen and windowed mode, unstretched.",
screen_width // 2, screen_height // 2 - 20,
arcade.color.WHITE, text_size, anchor_x="center")
arcade.draw_text("Press S to toggle between full screen and windowed mode, stretched.",
screen_width // 2, screen_height // 2 + 20,
arcade.color.WHITE, text_size, anchor_x="center")
# Draw some boxes on the bottom so we can see how they change
for x in range(64, 800, 128):
y = 64
width = 128
height = 128
arcade.draw_texture_rectangle(x, y, width, height, self.example_image)
def on_key_press(self, key, modifiers):
"""Called whenever a key is pressed. """
if key == arcade.key.F:
# User hits f. Flip between full and not full screen.
self.set_fullscreen(not self.fullscreen)
# Get the window coordinates. Match viewport to window coordinates
# so there is a one-to-one mapping.
width, height = self.get_size()
self.set_viewport(0, width, 0, height)
if key == arcade.key.S:
# User hits s. Flip between full and not full screen.
self.set_fullscreen(not self.fullscreen)
# Instead of a one-to-one mapping, stretch/squash window to match the
# constants. This does NOT respect aspect ratio. You'd need to
# do a bit of math for that.
self.set_viewport(0, SCREEN_WIDTH, 0, SCREEN_HEIGHT)
def main():
""" Main method """
MyGame()
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,92 @@
"""
Drawing Gradients
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.gradients
"""
import arcade
# Do the math to figure out our screen dimensions
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Gradients Example"
class MyGame(arcade.Window):
"""
Main application class.
"""
def __init__(self, width, height, title):
"""
Set up the application.
"""
super().__init__(width, height, title)
arcade.set_background_color(arcade.color.BLACK)
self.shapes = arcade.ShapeElementList()
# This is a large rectangle that fills the whole
# background. The gradient goes between the two colors
# top to bottom.
color1 = (215, 214, 165)
color2 = (219, 166, 123)
points = (0, 0), (SCREEN_WIDTH, 0), (SCREEN_WIDTH, SCREEN_HEIGHT), (0, SCREEN_HEIGHT)
colors = (color1, color1, color2, color2)
rect = arcade.create_rectangle_filled_with_colors(points, colors)
self.shapes.append(rect)
# Another rectangle, but in this case the color doesn't change. Just the
# transparency. This time it goes from left to right.
color1 = (165, 92, 85, 255)
color2 = (165, 92, 85, 0)
points = (100, 100), (SCREEN_WIDTH - 100, 100), (SCREEN_WIDTH - 100, 300), (100, 300)
colors = (color2, color1, color1, color2)
rect = arcade.create_rectangle_filled_with_colors(points, colors)
self.shapes.append(rect)
# Two lines
color1 = (7, 67, 88)
color2 = (69, 137, 133)
points = (100, 400), (SCREEN_WIDTH - 100, 400), (SCREEN_WIDTH - 100, 500), (100, 500)
colors = (color2, color1, color2, color1)
shape = arcade.create_lines_with_colors(points, colors, line_width=5)
self.shapes.append(shape)
# Triangle
color1 = (215, 214, 165)
color2 = (219, 166, 123)
color3 = (165, 92, 85)
points = (SCREEN_WIDTH // 2, 500), (SCREEN_WIDTH // 2 - 100, 400), (SCREEN_WIDTH // 2 + 100, 400)
colors = (color1, color2, color3)
shape = arcade.create_triangles_filled_with_colors(points, colors)
self.shapes.append(shape)
# Ellipse, gradient between center and outside
color1 = (69, 137, 133, 127)
color2 = (7, 67, 88, 127)
shape = arcade.create_ellipse_filled_with_colors(SCREEN_WIDTH // 2, 350, 50, 50,
inside_color=color1, outside_color=color2)
self.shapes.append(shape)
def on_draw(self):
"""
Render the screen.
"""
# This command has to happen before we start drawing
arcade.start_render()
self.shapes.draw()
# arcade.draw_rectangle_filled(500, 500, 50, 50, (255, 0, 0, 127))
def main():
MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,238 @@
"""
Buttons with text on them
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.gui_text_button
"""
import arcade
import random
import os
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "GUI Text Buton Example"
class TextButton:
""" Text-based button """
def __init__(self,
center_x, center_y,
width, height,
text,
font_size=18,
font_face="Arial",
face_color=arcade.color.LIGHT_GRAY,
highlight_color=arcade.color.WHITE,
shadow_color=arcade.color.GRAY,
button_height=2):
self.center_x = center_x
self.center_y = center_y
self.width = width
self.height = height
self.text = text
self.font_size = font_size
self.font_face = font_face
self.pressed = False
self.face_color = face_color
self.highlight_color = highlight_color
self.shadow_color = shadow_color
self.button_height = button_height
def draw(self):
""" Draw the button """
arcade.draw_rectangle_filled(self.center_x, self.center_y, self.width,
self.height, self.face_color)
if not self.pressed:
color = self.shadow_color
else:
color = self.highlight_color
# Bottom horizontal
arcade.draw_line(self.center_x - self.width / 2, self.center_y - self.height / 2,
self.center_x + self.width / 2, self.center_y - self.height / 2,
color, self.button_height)
# Right vertical
arcade.draw_line(self.center_x + self.width / 2, self.center_y - self.height / 2,
self.center_x + self.width / 2, self.center_y + self.height / 2,
color, self.button_height)
if not self.pressed:
color = self.highlight_color
else:
color = self.shadow_color
# Top horizontal
arcade.draw_line(self.center_x - self.width / 2, self.center_y + self.height / 2,
self.center_x + self.width / 2, self.center_y + self.height / 2,
color, self.button_height)
# Left vertical
arcade.draw_line(self.center_x - self.width / 2, self.center_y - self.height / 2,
self.center_x - self.width / 2, self.center_y + self.height / 2,
color, self.button_height)
x = self.center_x
y = self.center_y
if not self.pressed:
x -= self.button_height
y += self.button_height
arcade.draw_text(self.text, x, y,
arcade.color.BLACK, font_size=self.font_size,
width=self.width, align="center",
anchor_x="center", anchor_y="center")
def on_press(self):
self.pressed = True
def on_release(self):
self.pressed = False
def check_mouse_press_for_buttons(x, y, button_list):
""" Given an x, y, see if we need to register any button clicks. """
for button in button_list:
if x > button.center_x + button.width / 2:
continue
if x < button.center_x - button.width / 2:
continue
if y > button.center_y + button.height / 2:
continue
if y < button.center_y - button.height / 2:
continue
button.on_press()
def check_mouse_release_for_buttons(x, y, button_list):
""" If a mouse button has been released, see if we need to process
any release events. """
for button in button_list:
if button.pressed:
button.on_release()
class StartTextButton(TextButton):
def __init__(self, center_x, center_y, action_function):
super().__init__(center_x, center_y, 100, 40, "Start", 18, "Arial")
self.action_function = action_function
def on_release(self):
super().on_release()
self.action_function()
class StopTextButton(TextButton):
def __init__(self, center_x, center_y, action_function):
super().__init__(center_x, center_y, 100, 40, "Stop", 18, "Arial")
self.action_function = action_function
def on_release(self):
super().on_release()
self.action_function()
class MyGame(arcade.Window):
"""
Main application class.
NOTE: Go ahead and delete the methods you don't need.
If you do need a method, delete the 'pass' and replace it
with your own code. Don't leave 'pass' in this program.
"""
def __init__(self, width, height, title):
super().__init__(width, height, 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)
arcade.set_background_color(arcade.color.AMAZON)
self.pause = False
self.coin_list = None
self.button_list = None
def setup(self):
# Create your sprites and sprite lists here
self.coin_list = arcade.SpriteList()
for i in range(10):
coin = arcade.Sprite("images/coin_01.png", 0.25)
coin.center_x = random.randrange(SCREEN_WIDTH)
coin.center_y = random.randrange(SCREEN_HEIGHT)
coin.change_y = -1
self.coin_list.append(coin)
# Create our on-screen GUI buttons
self.button_list = []
play_button = StartTextButton(60, 570, self.resume_program)
self.button_list.append(play_button)
quit_button = StopTextButton(60, 515, self.pause_program)
self.button_list.append(quit_button)
def on_draw(self):
"""
Render the screen.
"""
arcade.start_render()
# Draw the coins
self.coin_list.draw()
# Draw the buttons
for button in self.button_list:
button.draw()
def update(self, delta_time):
"""
All the logic to move, and the game logic goes here.
Normally, you'll call update() on the sprite lists that
need it.
"""
if self.pause:
return
self.coin_list.update()
for coin in self.coin_list:
if coin.top < 0:
coin.bottom = SCREEN_HEIGHT
def on_mouse_press(self, x, y, button, key_modifiers):
"""
Called when the user presses a mouse button.
"""
check_mouse_press_for_buttons(x, y, self.button_list)
def on_mouse_release(self, x, y, button, key_modifiers):
"""
Called when a user releases a mouse button.
"""
check_mouse_release_for_buttons(x, y, self.button_list)
def pause_program(self):
self.pause = True
def resume_program(self):
self.pause = False
def main():
""" Main method """
game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
game.setup()
arcade.run()
if __name__ == "__main__":
main()

View File

@ -0,0 +1,48 @@
"""
Drawing an example happy face
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.happy_face
"""
import arcade
# Set constants for the screen size
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
SCREEN_TITLE = "Happy Face Example"
# Open the window. Set the window title and dimensions
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
# Set the background color
arcade.set_background_color(arcade.color.WHITE)
# Clear screen and start render process
arcade.start_render()
# --- Drawing Commands Will Go Here ---
# Draw the face
x = 300; y = 300; radius = 200
arcade.draw_circle_filled(x, y, radius, arcade.color.YELLOW)
# Draw the right eye
x = 370; y = 350; radius = 20
arcade.draw_circle_filled(x, y, radius, arcade.color.BLACK)
# Draw the left eye
x = 230; y = 350; radius = 20
arcade.draw_circle_filled(x, y, radius, arcade.color.BLACK)
# Draw the smile
x = 300; y = 280; width = 120; height = 100
start_angle = 190; end_angle = 350
arcade.draw_arc_outline(x, y, width, height, arcade.color.BLACK,
start_angle, end_angle, 10)
# Finish drawing and display the result
arcade.finish_render()
# Keep the window open until the user hits the 'close' button
arcade.run()

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="95.954338"
height="95.954338"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="bumper.svg"
inkscape:export-filename="C:\Users\craven\Desktop\WebServer\arcade\examples\images\bumper.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="-18.856048"
inkscape:cy="41.144234"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1422"
inkscape:window-height="895"
inkscape:window-x="26"
inkscape:window-y="26"
inkscape:window-maximized="0"
showguides="true"
inkscape:guide-bbox="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-62.129459,-72.014217)">
<path
sodipodi:type="arc"
style="fill:#ff0000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path2985"
sodipodi:cx="110.10663"
sodipodi:cy="119.99139"
sodipodi:rx="47.477169"
sodipodi:ry="47.477169"
d="m 157.5838,119.99139 c 0,26.22091 -21.25626,47.47717 -47.47717,47.47717 -26.220918,0 -47.477171,-21.25626 -47.477171,-47.47717 0,-26.22092 21.256253,-47.477173 47.477171,-47.477173 26.22091,0 47.47717,21.256253 47.47717,47.477173 z" />
<path
sodipodi:type="star"
style="fill:#ffff00;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path2991"
sodipodi:sides="10"
sodipodi:cx="78.286819"
sodipodi:cy="98.525642"
sodipodi:r1="50.346378"
sodipodi:r2="25.173187"
sodipodi:arg1="0.70372968"
sodipodi:arg2="1.0178889"
inkscape:flatsided="false"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 116.67262,131.10306 -25.165757,-11.155 -1.313808,27.49588 -13.802775,-23.81665 -17.224565,21.47239 2.832396,-27.38114 -26.556123,7.24719 18.385687,-20.48697 -25.744146,-9.746198 26.916272,-5.76747 -15.09878,-23.01687 25.165755,11.155007 1.313808,-27.495879 13.802775,23.816649 17.224564,-21.472396 -2.832395,27.381141 26.556122,-7.247188 -18.38569,20.486968 25.74415,9.746196 -26.91627,5.76747 z"
transform="matrix(0.90275471,0,0,0.91785308,38.801484,29.938127)" />
<path
sodipodi:type="arc"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path2995"
sodipodi:cx="110.35917"
sodipodi:cy="121.75915"
sodipodi:rx="22.475895"
sodipodi:ry="22.475895"
d="m 132.83506,121.75915 c 0,12.41309 -10.0628,22.47589 -22.47589,22.47589 -12.413095,0 -22.475896,-10.0628 -22.475896,-22.47589 0,-12.4131 10.062801,-22.475897 22.475896,-22.475897 12.41309,0 22.47589,10.062797 22.47589,22.475897 z"
transform="translate(-0.75761441,-1.767767)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show More