Add Astronaut

Now we will add our target of rescue, the astronauts. All the code in the process will not introduce any new concepts, so lets get straight into the planning.

Planning

We want to:

  • create an Astronaut class

  • have Zork randomly spawn an Astronaut

  • upon spawn the Astronaut moves across the screen

  • if the Astronaut exits the screen left, is it deleted

  • when Astronauts collides with the Ship they are rescued and disappear

  • when Astronauts collide with the Laser they are vaporised and disappear

Lets look at all of these in IPO tables.

Astronaut IPO tables

Each of the parts of these IPO tables we have done before, the only difference is that they’re arranged differently. Therefore, we should be able to get on with the coding.

Coding

Objects.Astronaut.py

In the Objects folder create a new file and call it Astronaut.py, then add the code below.

 1from GameFrame import RoomObject
 2
 3class Astronaut(RoomObject):
 4    """
 5    Class for the astronauts escaping from Zork
 6    """
 7    
 8    def __init__(self,room,x,y):
 9        """
10        Initialise the astronaut instance
11        """
12        # include attirbutes and method from RoomObject
13        RoomObject.__init__(self,room,x,y)
14        
15        # set image
16        image = self.load_image("Astronaut.png")
17        self.set_image(image,50,49)
18        
19        # set travel direction
20        self.set_direction(180, 5)
21        
22        # handle events
23        self.register_collision_object("Ship")
24        
25    def step(self):
26        """
27        Determines what happend to the astronaut on each tick of the game clock
28        """
29        self.outside_of_room()
30        
31    # --- Event Handlers
32    def handle_collision(self, other, other_type):
33        """
34        Handles the collision event for Astronaut objects
35        """
36        # ship collision
37        if other_type == "Ship":
38            self.room.delete_object(self)
39            
40    def outside_of_room(self):
41        """
42        removes astronauts that have exited the room
43        """
44        if self.x + self.width < 0:
45            self.room.delete_object(self)

This code:

  • lines 1-17: creates the Astronaut class

  • lines 19-20: set the Astronaut travel direction

  • lines 22-23: registers collisions with Ship objects

  • lines 25-29: checks if the Astronaut is outside the room

  • lines 32-38: handles a collision with a Ship object

  • lines 40-45: deletes the Astronaut if it is outside of the room

Save Astronaut.py

Objects/__init__.py

We have just created a new RoomObject, so we need to let GameFrame know by editing the Objects/__init__.py.

Open Objects/__init__.py and then add the highlighted code:

1from Objects.Title import Title
2from Objects.Ship import Ship
3from Objects.Zork import Zork
4from Objects.Asteroid import Asteroid
5from Objects.Laser import Laser
6from Objects.Astronaut import Astronaut

Save and close Objects/__init__.py

Objects/Zork.py

We know need to make Zork randomly spawn Astronauts

Open Objects/Zork.py and add the highlighted code below to the __init__() method:

10    def __init__(self, room, x, y):
11        """
12        Initialise the Boss object
13        """
14        # include attributes and methods from RoomObject
15        RoomObject.__init__(self, room, x, y)
16        
17        # set image
18        image = self.load_image("Zork.png")
19        self.set_image(image,135,165)
20        
21        # set inital movement
22        self.y_speed = random.choice([-10, 10])
23        
24        # start asteroid timer
25        asteroid_spawn_time = random.randint(15, 150)
26        self.set_timer(asteroid_spawn_time, self.spawn_asteroid)
27        
28        # start astronaut timer
29        astronaut_spawn_time = random.randint(30, 200)
30        self.set_timer(astronaut_spawn_time, self.spawn_astronaut)

Then add the following code to the bottom of Objects/Zork.py:

58    def spawn_astronaut(self):
59        """
60        Randomly spawns a new astronaut
61        """
62        # spawn astronaut and add to room
63        new_astronaut = Astronaut(self.room, self.x, self.y + self.height/2)
64        self.room.add_room_object(new_astronaut)
65        
66        # reset timer for next astronaut spawn
67        astronaut_spawn_time = random.randint(30, 200)
68        self.set_timer(astronaut_spawn_time, self.spawn_astronaut)

Save Objects/Zork.py and the test it by running MainController.py

Objects/Laser.py

Finally we need to deal with the Astronaut and Laser collision.

Open Objects/Laser.py and the following highlighted code.

 1from GameFrame import RoomObject, Globals
 2
 3class Laser(RoomObject):
 4    """
 5    Class for the lasers shot by the Ship
 6    """
 7    
 8    def __init__(self, room, x, y):
 9        """
10        Inistialise the laser
11        """
12        # include attributes and methods from RoomObject
13        RoomObject.__init__(self, room, x, y)
14        
15        # set image
16        image = self.load_image("Laser.png")
17        self.set_image(image, 33, 9)
18        
19        # set movement
20        self.set_direction(0, 20)
21        
22        # handle events
23        self.register_collision_object("Asteroid")
24        self.register_collision_object("Astronaut")
25        
26    def step(self):
27        """
28        Determine what happens to the laser on each tick of the game clock
29        """
30        self.outside_of_room()
31        
32    def outside_of_room(self):
33        """
34        removes laser if it has exited the room
35        """
36        if self.x > Globals.SCREEN_WIDTH:
37            self.room.delete_object(self)
38            
39    # --- Event handlers
40    def handle_collision(self, other, other_type):
41        """
42        Handles laser collisions with other registered objects
43        """
44        if other_type == "Asteroid":
45            self.room.delete_object(other)
46        elif other_type == "Astronaut":
47            self.room.delete_object(other)

Save Objects/Laser.py and the test it by running MainController.py

Commit and Push

We have finished and tested another section of code so we should make a Git commit.

To do this:

  1. In GitHub Desktop go to the bottom left-hand box and write into the summary Added astronaut.

  2. Click on Commit to main

  3. Click on Push origin

Now the work from this lesson is committed and synced with the online repo.

Completed File States

Below are all the files we used in this lesson in their finished state. Use this to check if your code is correct.

Objects/Astronaut.py

 1from GameFrame import RoomObject
 2
 3class Astronaut(RoomObject):
 4    """
 5    Class for the astronauts escaping from Zork
 6    """
 7    
 8    def __init__(self,room,x,y):
 9        """
10        Initialise the astronaut instance
11        """
12        # include attirbutes and method from RoomObject
13        RoomObject.__init__(self,room,x,y)
14        
15        # set image
16        image = self.load_image("Astronaut.png")
17        self.set_image(image,50,49)
18        
19        # set travel direction
20        self.set_direction(180, 5)
21        
22        # handle events
23        self.register_collision_object("Ship")
24        
25    def step(self):
26        """
27        Determines what happend to the astronaut on each tick of the game clock
28        """
29        self.outside_of_room()
30        
31    # --- Event Handlers
32    def handle_collision(self, other, other_type):
33        """
34        Handles the collision event for Astronaut objects
35        """
36        # ship collision
37        if other_type == "Ship":
38            self.room.delete_object(self)
39            
40    def outside_of_room(self):
41        """
42        removes astronauts that have exited the room
43        """
44        if self.x + self.width < 0:
45            self.room.delete_object(self)

Objects/__init__.py

1from Objects.Title import Title
2from Objects.Ship import Ship
3from Objects.Zork import Zork
4from Objects.Asteroid import Asteroid
5from Objects.Laser import Laser
6from Objects.Astronaut import Astronaut

Objects/Zork.py

 1from GameFrame import RoomObject, Globals
 2from Objects.Asteroid import Asteroid
 3from Objects.Astronaut import Astronaut
 4import random
 5
 6class Zork(RoomObject):
 7    """
 8    A class for the game's antagoist
 9    """
10    def __init__(self, room, x, y):
11        """
12        Initialise the Boss object
13        """
14        # include attributes and methods from RoomObject
15        RoomObject.__init__(self, room, x, y)
16        
17        # set image
18        image = self.load_image("Zork.png")
19        self.set_image(image,135,165)
20        
21        # set inital movement
22        self.y_speed = random.choice([-10, 10])
23        
24        # start asteroid timer
25        asteroid_spawn_time = random.randint(15, 150)
26        self.set_timer(asteroid_spawn_time, self.spawn_asteroid)
27        
28        # start astronaut timer
29        astronaut_spawn_time = random.randint(30, 200)
30        self.set_timer(astronaut_spawn_time, self.spawn_astronaut)
31        
32        
33    def keep_in_room(self):
34        """
35        Keeps the Zork inside the top and bottom room limits
36        """
37        if self.y < 0 or self.y > Globals.SCREEN_HEIGHT - self.height:
38            self.y_speed *= -1
39            
40    def step(self):
41        """
42        Determine what happens to the Dragon on each tick of the game clock
43        """
44        self.keep_in_room()
45        
46    def spawn_asteroid(self):
47        """
48        Randomly spawns a new Asteroid
49        """
50        # spawn Asteroid and add to room
51        new_asteroid = Asteroid(self.room, self.x, self.y + self.height/2)
52        self.room.add_room_object(new_asteroid)
53        
54        # reset time for next Asteroid spawn
55        asteroid_spawn_time = random.randint(15, 150)
56        self.set_timer(asteroid_spawn_time, self.spawn_asteroid)
57        
58    def spawn_astronaut(self):
59        """
60        Randomly spawns a new astronaut
61        """
62        # spawn astronaut and add to room
63        new_astronaut = Astronaut(self.room, self.x, self.y + self.height/2)
64        self.room.add_room_object(new_astronaut)
65        
66        # reset timer for next astronaut spawn
67        astronaut_spawn_time = random.randint(30, 200)
68        self.set_timer(astronaut_spawn_time, self.spawn_astronaut)

Objects/Laser.py

 1from GameFrame import RoomObject, Globals
 2
 3class Laser(RoomObject):
 4    """
 5    Class for the lasers shot by the Ship
 6    """
 7    
 8    def __init__(self, room, x, y):
 9        """
10        Inistialise the laser
11        """
12        # include attributes and methods from RoomObject
13        RoomObject.__init__(self, room, x, y)
14        
15        # set image
16        image = self.load_image("Laser.png")
17        self.set_image(image, 33, 9)
18        
19        # set movement
20        self.set_direction(0, 20)
21        
22        # handle events
23        self.register_collision_object("Asteroid")
24        self.register_collision_object("Astronaut")
25        
26    def step(self):
27        """
28        Determine what happens to the laser on each tick of the game clock
29        """
30        self.outside_of_room()
31        
32    def outside_of_room(self):
33        """
34        removes laser if it has exited the room
35        """
36        if self.x > Globals.SCREEN_WIDTH:
37            self.room.delete_object(self)
38            
39    # --- Event handlers
40    def handle_collision(self, other, other_type):
41        """
42        Handles laser collisions with other registered objects
43        """
44        if other_type == "Asteroid":
45            self.room.delete_object(other)
46        elif other_type == "Astronaut":
47            self.room.delete_object(other)