27/11/2024

Week 9 Learning Summary

Week 9 subject: Your first Arcade game from scratch

Step 1: Define the problem

In a playground (SCRWID * SCRHGT), draw a shape (ellipse to start with), let it move within the playground, bounce off each side of the playground.  Easy!

In order to create that game, you obviously need:

  • The Arcade package,
  • An Arcade program template,
  • Your own Shape class which has properties and actions

Step 2: An 'Empty' Arcade program

import arcade

# Constants
SCRWID = 800
SCRHGT = 600
SCREEN_TITLE = "My First Arcade Game"

# MyGame class exists in each arcade program
class MyGame(arcade.Window):
    def __init__(self):
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
        arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)

    def on_update(self):
        pass

    def on_draw(self):
        self.clear()

# Main program, first initalise the MyGame class, then call arcade.run()
game = MyGame()
arcade.run()

Don't forget to add then more code to actually initialise your shapes (in our case only one shape) in the shape_list data member of the MyGame class.  Each member of the list is an object of the Shape class.  Don't forget to provide the values used by the initialiser of the Shape class.  Like this:

    def __init__(self):
        super().__init__(SCRWID, SCRHGT, SCRTTL)
        arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE)

        # Initialise your list of shapes, we are going to use only 1
        self.shape_list = []

        # Set all initial values used to initalise shapes in the list
        x = SCRWID / 2
        # All other intialisation...
        c = (255, 0, 0, 127)

        # Initialise shape
        shape = Shape(x, y, w, h, a, dx, dy, da, c)

        # Add to list of shapes
        self.shape_list.append(shape)

Step 3: Define the Shape class

The shape, presumably an ellipse, will have a number of properties (data members), including x, y, w, h, dx (speed on the x-axis), dy (speed on the y-axis), a (angle from horizontal) and c.  It will also need to have a method to move(), based on x, y, dx and dy, and to bounce of the 4 walls.

class   Shape:
    # called when the Shape object is created, make sure you pass all parameters!
    def __init__(self, x, y, w, h, a, dx, dy, da, c):
        self.x = x
        self.y = y
        # all other initialisation...
        self.c = c

    # called by the MyGame class on_update() method
    def move(self):
        # update location based on current location and direction of move 
        self.x += self.dx
        self.y += self.dy
        self.a += self.da

        # bounce is literally just reversing direction
        if (self.x < 0 and self.dx < 0) or (self.x > SCRWID and self.dx >0):
            self.dx *= -1
        if (self.y < 0 and self.dy < 0) or (self.y > SCRHGT and self.dy >0):
            self.dy *= -1

    def draw(self):
        arcade.draw_ellipse_filled(self.x, self.y, self.w, self.h, self.c, self.a)

Step 4: Add movement (event handling)

Arcade calls the on_update() method of MyGame class at a certain interval.  (Look up the Arcade docs to see how to set this interval.)  Movement must be handled in on_update(), by simply calling Shape.move() where the real work is done.

However, the drawing of the moved shape is done in another event handler on_draw(), which is also called by Arcade whenever there's anything to draw.

    def on_update(self, dt):
        for shape in self.shape_list:
            shape.move()

    def on_draw(self):
        self.clear()

        for shape in self.shape_list:
            shape.draw()

Step 5: Let's go!

Check your code again, make sure all elements are updated.  Then run the program, please the first Arcade game you create.

No comments: