Easy 2D Game Creation
With Python And Arcade
Paul Vincent Craven
Explore On-Line!
Installation
pip install arcade
Requires
- Python 3.6+
- OpenGL Capable Hardware
For detailed installation instructions on Windows, MacOS, and Linux, see:
import arcade
# Set constants for the screen size
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
# Open the window. Set the window title and dimensions
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing Example")
# --- Drawing Code Will Go Here ---
# Keep the window open until the user hits the 'close' button
arcade.run()
1
2
3
Open a Window
import arcade
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
# Open the window. Set the window title and dimensions
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing Example")
# 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 ---
# Finish drawing and display the result
arcade.finish_render()
# Keep the window open until the user hits the 'close' button
arcade.run()
1
2
Drawing Setup
3
# 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; line_width = 10
arcade.draw_arc_outline(x, y, width, height, arcade.color.BLACK,
start_angle, end_angle, line_width)
Drawing
1
2
3
4
draw_arc_filled()
draw_arc_outline()
draw_circle_filled()
draw_circle_outline()
draw_ellipse_filled()
draw_ellipse_outline()
draw_line()
draw_line_strip()
draw_lines()
draw_parabola_filled()
draw_parabola_outline()
draw_point()
draw_points()
Drawing Commands
draw_rectangle_filled()
draw_rectangle_outline()
draw_lrtb_rectangle_filled()
draw_lrtb_rectangle_outline()
draw_xywh_rectangle_filled()
draw_xywh_rectangle_outline()
draw_polygon_filled()
draw_polygon_outline()
draw_text()
load_texture()
draw_texture_rectangle()
draw_xywh_rectangle_textured()
draw_triangle_filled()
draw_triangle_outline()
Sample Images
Wait!
Put code in functions!
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)
Draw With Functions
1
2
3
def main():
arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT,
"Drawing With Functions")
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)
arcade.finish_render()
arcade.run()
if __name__ == "__main__":
main()
The Main Function
1
2
3
Wait!
That's not fast...
Explore using buffered shapes
class MyGame(arcade.Window):
def __init__(self, width, height, title):
""" Initialize everything """
# Initialize the parent class
super().__init__(width, height, title)
arcade.set_background_color(arcade.color.AMAZON)
def setup(self):
""" Create the sprites and set up the game """
pass
def on_draw(self):
""" Render the screen. """
arcade.start_render()
# TODO: Drawing code goes here
Use Classes
2
3
4
1
def update(self, delta_time):
""" All the logic to move, and the game logic goes here. """
pass
def on_key_press(self, key, key_modifiers):
""" Called whenever a key on the keyboard is pressed. """
pass
def on_mouse_motion(self, x, y, delta_x, delta_y):
""" Called whenever the mouse moves. """
pass
def on_mouse_press(self, x, y, button, key_modifiers):
""" Called when the user presses a mouse button. """
pass
Use Classes
1
2
3
4
def main():
""" Main method """
game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, "My Game Title")
game.setup()
arcade.run()
if __name__ == "__main__":
main()
Use Classes
1
2
3
Use Sprites
Images from Kenney.nl
# This code goes in the setup() method of our MyGame class
# Set up the player
self.player_sprite = arcade.Sprite("images/character.png")
self.player_sprite.center_x = 50
self.player_sprite.center_y = 50
# Add player to a sprite list
self.player_list = arcade.SpriteList()
self.player_list.append(self.player_sprite)
Create Sprites
1
2
3
The SpriteList Class
- Optimizes drawing by using vertex buffers and more
- Optimizes collision detection by using spatial hashing
- Allows you to control drawing order
- Easier management of your game logic
# This code goes in the setup() method of our MyGame class
COIN_COUNT = 50
self.coin_list = arcade.SpriteList()
# Create the coins
for i in range(COIN_COUNT):
# Create the coin instance
coin = arcade.Sprite("images/coin_01.png")
# Position the coin
coin.center_x = random.randrange(SCREEN_WIDTH)
coin.center_y = random.randrange(SCREEN_HEIGHT)
# Add the coin to the lists
self.coin_list.append(coin)
Create Sprites
1
2
def on_draw(self):
"""
Render the screen.
"""
# This command has to happen before we start drawing
arcade.start_render()
# Draw all the sprites.
self.wall_list.draw()
self.coin_list.draw()
self.player_sprite_list.draw()
Drawing Sprites
1
2
def update(self, delta_time):
# Generate a list of all coin sprites that collided with the player.
coins_hit_list = arcade.check_for_collision_with_list(self.player_sprite,
self.coin_list)
# Loop through each colliding sprite, remove it, and add to the score.
for coin in coins_hit_list:
coin.kill()
self.score += 1
Sprite Collisions
1
2
Moving Sprites
Moving Coins Down
0
599
620
700
799
0
Y
X
On-Screen
Where Coins Respawn
def on_mouse_motion(self, x, y, dx, dy):
""" Handle Mouse Motion """
# Move the center of the player sprite to match the mouse x, y
self.player_sprite.center_x = x
self.player_sprite.center_y = y
Moving The Player
1
2
class Coin(arcade.Sprite):
def reset_pos(self):
# Reset the coin to a random spot above the screen
self.center_y = random.randrange(SCREEN_HEIGHT + 20,
SCREEN_HEIGHT + 100)
self.center_x = random.randrange(SCREEN_WIDTH)
def update(self):
# Move the coin
self.center_y -= 1
# See if the coin has fallen off the bottom of the screen.
# If so, reset it.
if self.top < 0:
self.reset_pos()
Moving Coins Down
1
2
4
3
5
6
# This code goes in the setup() method of our MyGame class
COIN_COUNT = 50
self.coin_list = arcade.SpriteList()
# Create the coins
for i in range(COIN_COUNT):
# Create the coin instance
coin = arcade.Sprite("images/coin_01.png")
# Position the coin
coin.center_x = random.randrange(SCREEN_WIDTH)
coin.center_y = random.randrange(SCREEN_HEIGHT)
# Add the coin to the lists
self.coin_list.append(coin)
Moving Coins Down
1
2
Coin
def update(self, delta_time):
""" Movement and game logic """
# Call update on all sprites (The sprites don't do much in this
# example though.)
self.coin_sprite_list.update()
# Generate a list of all sprites that collided with the player.
hit_list = arcade.check_for_collision_with_list(self.player_sprite,
self.coin_sprite_list)
# Loop through each colliding sprite, remove it, and add to the score.
for coin in hit_list:
coin.kill()
self.score += 1
Moving a Sprite
1
2
Learn By Example
Learn By Example
Learn By Example
What's Next?
- Immediate:
- Isometric map examples and support
- Better support for the Tiled Map Editor
- Soon:
- Better decorator support
- Particle support
- Lighting / shader support
How Does It Compare To PyGame?
- Easier
- Arcade is based on OpenGL, PyGame SDL1
- Uses modern design, Python features like type hinting
Want To Contribute?
- Use GitHub!
- Code and documentation open for pull requests.
- There's also an open-source book on learning to program with Arcade and Python.
Contact Me:
Paul Vincent Craven
paul@cravenfamily.com
@professorcraven
Learn More:
http://arcade.academy
Support:
www.reddit.com://r/pythonarcade
Easy 2D Game Creation With Python And Arcade
By Paul Craven
Easy 2D Game Creation With Python And Arcade
- 2,212