06 Loading the World

This exercise builds on the previous exercise named 05_pickling_the_world_TVR. Be sure to complete the previous exercise before you attempt this exercise.

Here we will practice reading in the file of a previously saved world. This is helpful in the event that you create a super cool world and want to save it for future use or share with friends. The code presented in this exercise will assume the file to read is called “composite_world_TVR.txt” and that the file exists. If this file does not exist the method will fail.

To get started with this programming exercise first copy the file 05_saving_the_world_TVR.py python code to a new file 06_loading_the_world_TVR.py but replace TVR with your initials using the following command:

cp 05_saving_the_world_TVR.py 06_loading_the_world_TVR.py

In this new file, jump down to line 421, just below the process_entire_queue function, and create a new method called load_txt which will read a text file created from the previous chapter 05_saving_the_world. The load_txt method calls the add_block method for each new block. The new load_txt method is shown below:

    def load_txt(self):
        """
        Load composite blocks from a .txt file
        """
        file_name = 'composite_world.txt'
        with open(file_name, 'r') as file:
            line = file.readline()
            while line:
                line = line.split(" ")
                x, y, z = int(line[0]), int(line[1]), int(line[2])
                block_type = self.get_block_index(num=int(line[3]))
                self.add_block((x, y, z), block_type)
                line = file.readline()
        print("world is loaded from file name: %s" % file_name)

The last thing we need to do is modify the method on_key_press so when the “L” key is pressed which will call the load_txt method. The new on_key_press method is listed below:

    def on_key_press(self, symbol, modifiers):
        """ Called when the player presses a key. See pyglet docs for key
        mappings.

        Parameters
        ----------
        symbol : int
            Number representing the key that was pressed.
        modifiers : int
            Number representing any modifying keys that were pressed.

        """
        if symbol == key.W:
            self.strafe[0] -= 1
        elif symbol == key.S:
            self.strafe[0] += 1
        elif symbol == key.A:
            self.strafe[1] -= 1
        elif symbol == key.D:
            self.strafe[1] += 1
        elif symbol == key.SPACE:
            if self.dy == 0:
                self.dy = JUMP_SPEED
        elif symbol == key.ESCAPE:
            self.set_exclusive_mouse(False)
        elif symbol == key.TAB:
            self.flying = not self.flying
        elif symbol == key.Y:
            self.position = (0, 0, 0)
            dx, dy, dz = self.get_motion_vector()
            self.dy = 0
        elif symbol in self.num_keys:
            index = (symbol - self.num_keys[0]) % len(self.inventory)
            self.block = self.inventory[index]
        elif symbol == key.B:
            self.buildWall()
        elif symbol == key.O:
            self.model.save_txt()
        elif symbol == key.L:
            self.model.load_txt()

Testing Load and Save

We should now be able to save and load a world with the changes suggested above. Let’s test this out before moving on. First, run the program 05_loading_the_world.py in IDLE, then make some simple changes to the world. Recall that the save and load methods will only account for COMPOSITE blocks, so if you build something out of grass, you won’t be able to save it. Walk around a while and try adding a few composite blocks to the world.

Once you have customized the world, press “O” to save the world. Close the window and then run the program again. Any changes you have made will be gone! Now we want to load the world you had made by pressing “L”. This should load the world that you had previously made.