Objectives

The goal of this assignment is to learn the following:

Computer Science Principles Curriculum

Common Core Standards

Vocabulary

Overview

In this assignment, you will learn how to use the File class in order to open a file and use Read() and Write() actions on it. You will also take advantage of a technique known as action overloading, which allows you to define multiple actions with the same name that differ in their parameters.

You will need a template. The template adds on the scene a blue cube and a red cylinder (with buttons on them). The user can choose between one of them, or load a Model that was already chosen in a previous run. When the choice is made, both Models are removed from the scene, and a KeyboardListener is added, so the game can save and load the chosen model. Once the model is loaded, the player can make it move using the directional keys, and save its last positions in a file (using the S key), to load it later (using the L key).

Goal 1: Save text or a number in a file

Example: Write to a file
First, create an empty file where we will save the data. Create a file called form.txt. In action Save, you will use objects from the File, andFileWriter classes to open form.txt.

action Save(text objectForm)    
    File f
    f:SetPath("File/form.txt")
    FileWriter writer
    writer:OpenForWrite(f)
end

To write in the file, we will use the WriteLine(text yourText) from the FileWriter class.

writer:WriteLine(objectForm)
writer:Close()

This retrieves the model the player chose, and writes it to the form.txt file.

Activity: Write to the position.txt file.
Use the same code from the example above in action Save(). Make sure you use the action with no parameters. Also, pass "f"to the OpenForWrite action, and replace form.txt with position.txt, to write to the position file.

Now, you will try to save the X, Y and Z coordinates of the Model, so that we can load it on its previous place. Since these coordinates are number, you need to use GetText() action from the number class when you write it on the file. We will overload the Save() action, since we write in a different file and save more than one line.

Example: Save the X coordinate of the Model
Write the following line of code in action Save() after OpenForWrite.

writer:WriteLine(finalChoice:GetX():GetText())

Activity: Add code to save the Y and Z coordinates, and to tell players the posiiton was saved.
Use the example to add code to save the Y and Z coordinates. Use a Say action on the talk object to tell the player the position was saved.

Goal 2 : Load a number or a text from a file.

The action Load() is called when the player presses the L key after choosing one of the two Models. You now have to write what it should do. Like the Save action, you need a object from the Fileclass. Instead of the FileWriter object, we will use the FileReader. The following code is already in your template.

File file
file:SetPath("File/form.txt")
FileReader reader
reader:OpenForRead(file)

The FileReader class works the same as the FileWriter one, you can read a file line per line using the ReadLine() action.

finalChoice = table:GetValue(reader:ReadLine())
finalChoice:SetPosition(9, -2, 5)
Add(finalChoice)

The table is a HashTable field we used to stock the two Models, and the keys are "cube" and "cylinder" which are on the buttons. We saved one of them in a file with the previous activity. So if the user clicked on cube, this code will take the Model which is associated to the keyword "cube" in the HashTable. We choose to set its position. Finally, we have to add on the scene the chosen Model.

Activity: Add a conditional to handle choices

The example above is called when a Model is not load yet. Add the conditional to handle this.

action Load()
    File file
    file:SetPath("File/form.txt")
    FileReader reader
    reader:OpenForRead(file)
    if not isLoaded
        finalChoice = table:GetValue(reader:ReadLine())
        finalChoice:SetPosition(9, -2, 5)
        Add(finalChoice)
        isLoaded = true
    else
        // TO DO
    end
    reader:Close()
end

If there is already a model, then we want to load the last position we saved in position.txt. You will write the code that allows you to get the three coordinates of the Model. Since the values get the text type, we have to cast them into number using the ParseNumber() action from the text class.

Example: Use ParseNumber() action to load a position.
Add this code after the else to start reading the saved position.

//These two lines set the path for the FileReader to read the postion.txt file.
file:SetPath("File/position.txt") reader:OpenForRead(file)
//This line will set a variable for the X coordinate.
number positionX = reader:ReadLine():ParseNumber()
//These set the position, and add a Say statement to let the user know the position was loaded.
finalChoice:SetPosition(positionX, positionY, positionZ) talk:Say("Last position loaded")

Activity: Add code to read the Y and Z coordinates.
Use the example above to add code for the Y and Z coordinates.

There is the case where the user chooses to load a previous model. In this case, the Load action will have to be a bit different, since we will look into both txt files without conditions. To do that, you will overload the Load action. Find this action:

action Load(text fileName1, text fileName2)
    // TO DO
end

Example: Overlaod the Load() action to read two files.
Add this code to the new Load() action.

File f1
File f2
f1:SetPath("File/"+fileName1)
f2:SetPath("File/"+fileName2)
FileReader reader
reader:OpenForRead(f1)
finalChoice = table:GetValue(reader:ReadLine())
Add(finalChoice)
isLoaded = true
reader:OpenForRead(f2)
number positionX = reader:ReadLine():ParseNumber()

reader:Close()

Actvitiy: Add code for the Y and Z coordinates, as well as to set the position.
Use what you know to complete the action.

Goal 3: Load a path for the Model.

Now we will load a path which is defined in a file called path.txt. We call this action LoadPath(). First of all, we add these fields in the program above the Main action.

integer indexOfTab = 0
integer tabSize = 56 // number of line in path.txt

Then, in the Update action, add the following lines :

if isLoaded
    if not pIsPressed
        finalChoice:Move(positionX*seconds, positionY*seconds, positionZ*seconds)
    else
        if indexOfTab < tabSize // 56 = number of line in path.txt
            LoadPath(indexOfTab)
            indexOfTab = indexOfTab + 1
        end
    end
end

The LoadPath action will read the same file line by line each time it is called, and will set the position of the Model using the coordinates got from the indexOfTab-th line. Use this method because it would be too fast in a loop in the LoadPath action, and you wouldn't see the Model moving.

action LoadPath(integer index)
    File file
    file:SetPath("File/path.txt")
    FileReader reader
    reader:OpenForRead(file)
    // TO DO
end

Activity: Finish the action.
Add the following code to finish the action.

Array tab
// 56 is the number of line in the path_copy.txt file
repeat 56 times tab:Add(reader:ReadLine()) end integer waitCounter = 0 Array position = tab:Get(index):Split(" ") finalChoice:SetPosition(position:Get(0):ParseNumber(), position:Get(1):ParseNumber(), position:Get(2):ParseNumber()) if index = 55 pIsPressed = false talk:Say("Path loading finished") end

Next Tutorial

In the next tutorial, we will discuss Assignment 4.3, which describes an introduction to creating trees of dialog in games..