Objectives

The goal of this assignment is to learn the following:

Computer Science Principles Curriculum

Common Core Standards

Overview

Begin by downloading the template program for this challenge. This template will compile, but needs to be finished during the challenge. It can be found here:

Challenge 5.1 Template

In this assignment, you will have to complete an existing project to create a game using the Quorum game engine, and its primitive 3D shapes. In this game, you will move in first person in the terrain. The character is the camera moving in the 3D field. Most of the locations are already coded, but when you have finished the exercises, you can try modifying the game to make the world your own.

Goal 1: Practice with Class Actions

Your first goal will be to build a forest in your game. You have already been given the complete class Tree. A tree in this gameis composed of two boxes: one very thin, long, and brown box, and a green cube at the top of the first. They both are "added" to the Tree class so they are bound to each other, and one cannot exist without the other. This is the ideal way to create models that are made of several primitives.

Template: Tree class

Read through the Tree class, and see if you understand what the code says.

use Libraries.Game.Graphics.Model
use Libraries.Compute.Vector3
use Libraries.Game.Game
use Libraries.Game.Graphics.Color

class Tree is Model


    action createTree(number size, Vector3 vPos)  
        Color brown
            brown:SetColor(0.611, 0.4666, 0.31,1)
        Model trunk
            trunk:LoadBox(1.2*size,40*size,1.2*size,brown)

        Color green
            green:SetColor(0.08, 0.35, 0.04,1)
        Model branches
            branches:LoadBox(13*size,13*size,13*size,green)

        me:Add(trunk)
        trunk:Add(branches)

        me:SetPosition(vPos)
        trunk:SetPosition(0,20*size,0)
        branches:SetPosition(0,25*size,0)
    end

end

As you can see, when creating a tree, you choose its size, which will influence how the boxes are scaled when we create the trunk and the treetop. The other thing you have to choose is the position of the tree. The boxes are created by calling the LoadBox() action on a Model object. Here is an example of adding a tree in your own code.

//A Vector3 object allows you to set an object in 3D space.
Vector3 treePosition treePosition:SetPosition(0,0,0)
//This object references the Tree class we made.
Tree tree
//This line creates one tree with a size of 3 in the position we set earlier (0,0,0).
tree:createTree(3,treePosition)//As with all models, you have to add the tree
Add(tree)

Adding trees one by one would be tedious, so we will create a class Forest that will randomly generate trees in an area we define. The template has the start of this class, now you will finish it.

Example: Complete the private action randomX() action.
This action will use a Random object to create a random number for the X coordinate of a tree. The action has returns number after the () because this action gives, or returns, a number.

//This action is private, meaning it can only be used in the Forest class.
private action randomX() returns number
number r = random:RandomInteger(cast(integer,width/2)) r = r + random:RandomNumber() boolean b= random:RandomBoolean() if b =true return r else return -r end end

Activity: Complete the private action randomZ().
Use the example above to complete the private action randomZ().


Activity: Modify the createTrees() action, so that is generates trees in random positions and sizes.
Use private action randomX() and private action randomZ() to set the position of the trees. Use random:RandomIntegerBetween() for the size of the tree. Sizes can be between 1 and 3.


Activity: Use a loop to generate ntree trees.
Use a loop ntree times around your code to creat that many trees.

Goal 2: How to Use the List Structure

In every game, we want to have a goal. In this case, we will have checkpoints on several parts of the map. We will make the checkpoints spinning cubes on the ground that emit a sound. When you walk over a checkpoint, it disappears and the next one appears.

Here is an example of code for a single checkpoint, and how you put it in the game.

Vector3 checkPointPosition
checkPointPosition:Set(100,0,0)
AudioCheckPoint ACP 
ACP:createChecPoint(checkPointPosition)

There must be a call the checkPosition() action in the Update action of main.quourm. This is done for you in the program template.

As is, the program can only handle one checkPoint at a time. This is not practical if you want several checkPoints, so your need to create multiple objects. The simplest way to do so is to use a data structure. We will use the List structure. If you know arrays, this data structure will be used in a similar way. Here is an example.

//This line declares a List of numbers.
List list
//Use the action Add() to add to a list. The first position is 0, the second is 1, and so on. //The number you want to add is the parameter, and goes in the ().
list:Add(3) list:Add(7)
//You retrieve something from the list with the Get() action. //The position you want to retieve from is the parameter, and goes in the ()
number positionOne = list:Get(1)

Activity: Modify the AudioCheckPoint class to use a List instead of one object.
First, you need to change the object "coor" to a List object, to create the list for the checkpoints. Then, in the AudiCheckPoint class, you need to change parameter to "List lst", so the action will use the List. Finally set "coor" to "1st".


Activity: Modify the checkPosition() action.
Replace the template code with the code below. This will make checkpoints disappear after the player reaches them. It will also set an exception for when the player reaches the final checkpoint and wins.

//This line keeps the listener going after each checkpoint
aud:EnableLooping() aud:SetListenerPosition(cam:GetPosition()) aud:SetListenerDirection(cam:GetDirection())//The loop uses a counter to track the number of checkpoints, and compare it to the coordinates in the List //It also hides the old checkpoint, and sets the new one.
if count < coor:GetSize() if cam:GetPosition():GetX() > GetX() + 50 or cam:GetPosition():GetX() < GetX() - 50 or cam:GetPosition():GetZ() > GetZ() + 50 or cam:GetPosition():GetZ() < GetZ() - 50 aud:Stream() else count = count +1 if count < coor:GetSize() aud:SetPosition(coor:Get(count)) SetPosition(coor:Get(count)) else me:Hide() end end end

Goal 3: How to Add Actions Using the Keyboard

If you ever get lost in the game, you might need assistance to find your way to the next checkpoint. This is why we need a way for the player to know where the next checkpoint is. We will use the LookAt() action of the Camera class. This will get called when we press a certain key. We will need a KeyboardListener to do this.

This is what is in the Main class, which is already a KeyboardListener. The action that detects when you press a key is already coded.

action PressedKey(KeyboardEvent event)
//This line checks if the letter B was pressed.
if event:keyCode = event:B Vector3 point point:Set(100,100,100) camera:LookAt(point) end end

Here, when you press B, the camera looks at the point you just created: (100, 100, 100). You can also directly pass the x,y,z coordinates as a parameter of the action (example: LookAt(100,100,100)).

Activity: Modify the action, so the player will look towards the next checkpoint.
Modify the LookAt() action in the PressedKey() action, so the player will look at the current checkpoint. You will need to use ACP:getCount() action to check which checkpoint is up. Setting that action to a new variable, such as count, will simplify your code. Remember to set a condition for if count = -1, as the winning condition.

Collaborate

Collaboration is an important part of programming. When you work with other programmers, you get other points-of-view that make your programs even better. The final part of this assignment requires Git, a tool for collaborating. Look at the Teams and Version Control Tutorial if you want more information on Git:

Teams and Version Control Tutorial

Collaboration Activity:

Adding two more checkpoints is not a lot of work, but imagine how much help collaboration could be on bigger, more complex projects. When you collaborate, the amount of work each individual programmer has to do gets smaller. However, each programmer is also responsible for communicating what they are doing and what they expect others to do. If you did not tell your friend that he, or she needed to add two checkpoints, the collaboration would not have worked. Communication skills are essential when collaborating. This especially applies to documenting programs. Make sure that your program has informative variable names and comments that help others understand your code. Remember, comments are created with //. Look at your templates for examples of comments. When you ask your friend to add two checkpoints, be clear and thank them for collaborating with you.

Because collaborating means that we work with other programmers more, we have to develop different skills than we need to write programs on our own. Think about your program in sections. What parts of your program depend on other parts? How could you divide the work on one program between two people? Collaborating can help us think of ways to make parts of our program more independent. Think about all of the different classes you were given in this program template. Discuss with a friend, write an email, or post on a social media about how classes can help make program components more independent. While you are sharing, share your Quorum Game. Invite your friends to download and play your game.

Next Tutorial

In the next tutorial, we will discuss Challenge 5.2, which describes a technique called A * (star) for navigation..