3. More Sophisticated Programming

What We Will Cover


Illuminations

Announcements

  • Register to vote: vote like your freedom and rights depend on it!
  • Library has voter registration forms if you prefer paper
  • There is a measure on the ballot regarding Cabrillo--inform yourself
  • Cabrillo Fresh Market: 10:30 on the first Mondays each month through May at the Watsonville Quad
  • Remember to bring headphones as we will be introducing sounds on Thursday

Questions from last class or the reading?

Homework Questions?

3.1: Variables Revisited

Learner Outcomes

At the end of the lesson the student will be able to:

  • Create variable names according to the rules of Java
  • Write code for declaring variables and assigning them values
  • Trace variable assignment operations

3.1.1: Review of Variables

  • Memory is important in a computer program, just like in real life
  • We can do very little without memory in computer programs (or real life)
  • To remember something in Java, we use a variable

    variable: the name of a place to store data in a computer's memory

Variable Classifications

  • Java has two main classifications of variables:
    • local variables: visible only inside a method like act()
    • instance variables: visible to all methods in the class
  • We place a local variable declaration statement inside the method in which we use it
    public void act()
    {
        int x;
        // more code here
    }
    
  • A local variable is visible only inside the braces in which it was declared
  • Other methods in the class are not even aware that the variable exists
  • Thus we cannot use a local variable declared in one method inside another method
  • An instance variable is visible inside any method of the class
  • We declare an instance variable with a statement like this:
    private int speed;
    
  • We place the variable declaration statement inside the class but outside any method like:
    public class Hero extends Actor
    {
        private int speed;
    
        public void act()
        {
            // more code here
        }
    

Variable Declaration

  • The following statement declares a local variable:
    int x;
    
  • When we declare a variable we tell the computer to set aside space to store data in its memory
  • Notice that a local variable has only two parts:
    dataType variableName;
  • Where:
    • dataType: the type of data the variable will store
    • variableName: the name of the variables
  • In our example
    int x;
    
    • int: the data type telling the computer to store integer values
    • x: a name we made up for the variable

Storing a Value

  • After declaring a variable, we give it a value with an assignment statement
    x = 42;
    
  • The equals (=) sign is how we make an assignment statement
  • An assignment statement sets or resets the value stored in a variable
  • The variable in which to store the data is always on the left-hand side of the equals (=) sign
  • The value to assign is on the right-hand side of the equals (=) sign
  • Notice that we can both declare a variable and assign it a value in one statement:
    int x = 42; // declaration + assignment
    
  • Good programming practice says we should assign a value when we declare a variable

Check Yourself

  1. The name of a location to store data in a computer's memory is known as a(n) ________.
  2. To specify the type of data stored in a variable, variable declarations include a(n) ________ ________.
  3. If we want to store data in a variable only visible inside a single method, we declare a(n) ________ variable.
  4. If we want to store data in a variable visible inside any method of a class, we declare a(n) ________ variable.

3.1.2: Variable Names

  • A variable name is a sequence of letters, digits, underscores ( _ ) and currency symbols like: $, ¢, £, ¥
  • However, the name must start with either a letter, underscore character ("_") or currency symbol
    • Cannot start with a number
    • A currency symbol is allowed but its use is discouraged
  • Also, a variable name cannot be one of the Java reserved words (keywords)
    • For a list of reserved words, see: keywords
    • Keywords have a predefined meaning in the Java language
  • Note that we cannot have spaces in a variable name
    • A space is NOT a letter, digit, underscore character or currency symbol
  • Also, variable names are cAsE sEnSiTiVe
    • id, ID, iD and Id are all valid but different names
  • Always choose variable names that describes the data stored in the variable
    int randomNumber;
    

Program Style

camelCase

  • In addition to valid code, professional programmers often follow certain style conventions in naming
  • By convention, variable names in Java always start with a lower case letter
  • If the name has multiple words, use capital letters to mark the start of a new word
  • A program will still work without following these style conventions
  • However, the code will look amateurish rather than professional

Group Activity

Which of the following are valid variable names?

  1. int myHello2;
  2. int 2myHello;
  3. int My_HeLlO;
  4. int my hello;
  5. int _a_very_long_variable_name_that_is_hard_to_read;
  6. int hel-lo;

Check Yourself

  1. True or false: a variable is how a program stores data in a computer's main memory.
  2. True or false: a data type like int tells a computer program the kind of data we want to work with.
  3. answer

3.1.3: Data Types

  • Like human memory, a computer must encode information before storage
  • The data type tells the computer how to encode the data and how much memory space to set aside
  • Java has many different data types including the following:
Type Bytes Use
boolean 1 A true or false value.
int 4 Integers from -2,147,483,647 to 2,147,483,647.
double 8 Numbers like 12.345 that contain decimal points.
  • In addition, data types can be class types like World, Actor and Hero
  • A class type is a blueprint or template for creating objects
  • We make new class types whenever we subclass World or Actor
Type Bytes Use
Actor 4+ An Actor object or its subclasses like Hero.
Hero 4+ An Hero object.
World 4+ A World or its subclasses like LessonWorld.

Data Type Analogy

  • We can think of a data type as a child's game where we match shapes to holes
  • Java does not allow square data pegs in round memory holes

Matching shapes to holes

Integer Data Type Example

  • A commonly used numeric data type is int which is shorthand for integer
  • An int is a whole number with no fractions or decimal points
  • Thus we can store values in variables like:
    int x = getX();
    int y = getY();
    setLocation(x + 2, y);
    
  • However, if we try to store a number with a decimal point, we get an error
    int x = 12.34; // error: incompatible types
    
  • The problem is that we cannot store the decimal part in an int variable
  • The compiler with check and verify we do not make this type of an error
  • Variables can store many other types of data including non-numeric types
  • We simply specify the data type for the variable name

Group Activity: Name that Data Type!

Value Data Type
Hero
-213.555
42
42.0
true
Wombat
false

Solo Activity (2m)

On a piece of paper write a variable declaration for:

  1. A variable to store dollars and cents
  2. A variable to store the count of the number of people in a room
  3. A variable to store whether or not a light bulb is on or off
  4. A variable to store a Hero object

Have your deskmate verify your variable declarations and write their name on your paper as having verified your work.

3.1.4: Variable Assignment

  • After declaring a variable, we give it a value with an assignment statement like:
    x = 42;
    
  • To assign values, we use an assignment operator which is the "equals sign" (=)
  • An assignment statement sets or resets the value stored in a variable
  • The assignment is made in an assignment statement in this form:
    variable = expression;
  • Where:
    • variable: the name of the variable
    • expression: the data we want to store in the variable
  • An assignment statement assigns the value of expression (right side) to the variable (left side)
  • The simplest expression is a literal value:
    length = 25;
    width = 17.5;
    
  • Numbers like 25 and 17.5 are called literals because they represent exactly what they are literally
  • In each statement above, the value on right is assigned to the variable on the left
  • We may assign results of more complex expressions to a variable like:
    total = num1 + num2;
    slope = (y2 - y1) / (x2 - x1);
    
  • The expression on the right is evaluated (computed) before assignment to the variable on the left
  • Assignment causes the value in a variable to change

Assigning Initial Values to Variables

  • Initial values may or may not be assigned when variables are declared:
    // Not initialized when declared and have unknown values
    int sum;
    double amount;
    
    // Initialized when declared with assigned values
    int sum = 0;
    double amount = 42 * 2;
    
  • Good programming practice: initialize variables when declared

Variable Assignment Flow

  • A computer is a machine with a memory that follows a set of instructions
  • For a computer, or anyone, to follow a set of instructions it must know two things
    1. the actions to be taken
    2. the order of the actions
  • A computer always follows a set of instructions in order from first to last
  • When working with variables, we must keeps this property of computers in mind
  • First, a variable must be declared
  • Next a variable must be assigned a value with an assignment statement
  • To change the value of a variable we can reassign a value with another assignment statement
  • The original value is overwritten and replaced by the new value
  • The equals (=) sign does not express equality as it does in math

Variable Assignment Flow Example

int x = 5;
int y = 7;
x = y;
System.out.println("x=" + x + " y=" + y);

Solo Activity (2m)

On your paper from the last activity, write a statement to assign a value to each variable you declared. For the Hero object, assume there is a method named getHero() that returns a Hero object.

Check Yourself

  1. True or false: the "equals sign" (=) is the assignment operator.
  2. True or false: in an assignment statement, the value on the left is assigned to the variable on the right.
  3. After executing the following statement, the value of number is ________.
    int number;

Exercise 3.1: Variable Assignment Tracing (16m)

Understanding variables and assignment is critical to being able to program but is an easy thing to be confused about. Get over this hurdle and programming will be far easier.

In this exercise we complete a series of dry run exercises where we step through short fragments of code. This is an important activity to reinforce your understanding of variables. The instructor will step through the first exercise with you.

Specifications

  1. Take out a piece of paper to record your answers, making sure to put the exercise name and your name on the paper.
  2. Open the Variable Assignment Tracing Exercises.
  3. Click the first problem and follow the steps, filling in the boxes to get the final answers.
  4. After completing a problem and before continuing to the next, compare your answers with another student.
  5. If there is a disagreement, ask the instructor for clarification.
  6. After verifying your answer, record the problem number and final values of all variables on your paper.
  7. Repeat for the remaining exercise problems.
  8. After finishing all the exercise problems, answer the Check Understanding questions and record the question number and answer on your paper.

When finished, please help those around you.

3.1.5: Summary

  • Variables are how we can store data in our programs
  • Variables must be declared before use like:
    int x;
    
  • One declared we can assign a value to the variable like:
    x = 42;
    
  • Simple assignment statements have a variable, equals sign and an expression:
    variable = expression;
  • The expression is computed before the assignment
  • Variables can be assigned new values while our program executes
  • The following is an example of variable values changing with the program flow

Variable Assignment Flow Example

  • Variables can be assigned new values while our program executes
  • When assigning values, programs execute in order from top to bottom
    int x = 5;
    int y = 7;
    x = y;
    System.out.println("x=" + x + " y=" + y);
    
  • Variables can only hold one value at a time
  • Thus old values disappear when a variable is assigned a new value
  • Values placed into a variable replace (overwrite) previous values:

    Assigning a value to a variable

Check Yourself

Answer these questions to check your understanding. If you are not sure, then follow the links to the section and review the material.

  1. How do you store information in a computer's main memory? (3.1.1)
  2. What code would you write to declare an int variable named foo and assign it a value of 10? (3.1.1)
  3. Which of the following are valid variable names? (3.1.2)
    1. int myHello2;
    2. int 2myHello;
    3. int My_HeLlO;
    4. int my hello;
    5. int _a_very_long_variable_name_that_is_hard_to_read;
    6. int hel-lo;
  4. What is the purpose of a data type like int or double? (3.1.3)
  5. What data values can you store in each of the following data types? (3.1.3)
    1. bool
    2. char
    3. int
    4. double
  6. Which symbol is the assignment operator? (3.1.4)
  7. What does the assignment operation do? (3.1.4)

3.2: Creating Random Behavior

Learner Outcomes

At the end of the lesson the student will be able to:

  • Write code that generates random numbers
  • Write code for declaring variables and assigning them values
  • Write code using relational operators
  • Apply random numbers to change actor behavior

3.2.1: Random Behavior and Random Numbers Click for link

  • Recall our Hero scenario from lesson 2
  • We have looked at the basics of starting to program games and simulations
  • Now we look at how to add more interesting behavior to our actors
  • We will start with adding random behavior

Need for Random Behavior

  • In our current games, our actors walk across our worlds in straight lines
  • However, most animals and people do not always walk in a straight line
  • Instead they tend to wander around or amble towards a destination
  • We can simulate wandering by having our actors turn a little off course now and then
  • The amount of the turn can be random
  • Also the choice of when to turn off course can be random
  • These two factors simulate the natural actions of many animals and heroes
  • To simulate random behavior, we use random numbers

Random Numbers

  • Random numbers are a series of numbers without any apparent pattern
  • This means that we cannot predict the next number in the sequence
  • Greenfoot has a method for generating random numbers:
    Greenfoot.getRandomNumber(limit)
    
  • Where:
    • limit: the upper limit of the random number generated (limit not included)
  • The method returns a random integer between 0 and up to, but not including, limit
  • For example, the following statement returns a random number between 0 and 9:
    Greenfoot.getRandomNumber(10);
    

Dot Notation

  • Let us briefly discuss the notation of the method call:
    Greenfoot.getRandomNumber(10);
    
  • In this example, Greenfoot is the name of a class and getRandomNumber is the name of a method
  • Notice the dot (period) between the class name and the method name
  • This notation is called dot notation
  • When we call methods that are defined in our own class or inherited, just using the method name is enough
  • When we call methods from other classes, we must specify the class or object that has the method
  • The dot is used to separate the class or object name from the method name
  • Since the getRandomNumber() method is from the Greenfoot class, we write Greenfoot in front of the method call
  • We can call the method this way because the getRandomNumber() method is declared with the keyword static
  • There are other times to use dot notation and we will learn about these situations later in the course
  • For now, memorize the syntax for generating random numbers

Check Yourself

  1. One of a series of numbers without any apparent pattern is known as a(n) ________ number.
  2. To call a static method of another class, we place a(n) ________ between the class name and the method name.
  3. What code do you write to get the following result, including the end points?
    1. A random number between 0 and 9. answer
    2. A random number between 0 and 10. answer
    3. A random number between 1 and 10. answer
    4. A random number between -10 and 10. answer
  4. The problem with this random number generator from xkcd is that ________.
    1. dice rolling is not a fair way to get random numbers
    2. it was not selected randomly
    3. you can predict the number ahead of time
    4. nothing is wrong

3.2.2: Applying Random Numbers

  • Let us look at how to apply random numbers to create random behavior
  • The code for the Hero class at the end of lesson 2 is listed below
  • The hero moves in a straight line until it hits the edge of the world

Hero with Straight Line Movement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Hero here.
 * 
 * @author Ed Parrish
 * @version 1.1
 */
public class Hero extends Actor
{
    /**
     * Act - do whatever the Hero wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        move(2);
        if (isAtEdge())
        {
            turn(17);
        }
    }    
}

Randomizing the Turns

  • We can add some randomization by adjusting the amount of the turn by a random number
  • For example, we can change the way the hero turns with:
    int degrees = Greenfoot.getRandomNumber(35);
    // other code omitted
    turn(degrees);
    
  • Now the hero will turn between 0 and 34 degrees when it is at the edge of the world
  • We can get an actor to turn randomly either right or left using code like:
    int degrees = Greenfoot.getRandomNumber(91) - 45;
    // other code omitted
    turn(degrees);
    
  • We can write these commands without a variable by nesting the method calls:
    turn(Greenfoot.getRandomNumber(91) - 45);
    
  • Nested method calls are executed from the innermost parenthesis outwards
  • The sequence of operations is:
    1. Greenfoot.getRandomNumber(91) returns a number between 0 and 90
    2. Our code then subtracts 45 from the returned number
    3. The turn() method executes and turns between -45 and +45 degrees
  • Which approach is easier to understand -- using variables or nesting method calls?

Check Yourself

  1. answer

  2. To cause an actor to make a random right-turn between 0 and 45 degrees inclusive write ________.
    1. turn(random(45));
    2. turn(getRandomNumber(45));
    3. turn(Greenfoot.getRandomNumber(45));
    4. turn(Greenfoot.getRandomNumber(46));
  3. With the following code, an actor will turn between ________ and ________ degrees.
    int randNum = Greenfoot.getRandomNumber(91) - 45;
    turn(randNum);
    

3.2.3: Relational Operators

  • Another interesting behavior we can add is to sometimes turn and sometimes not turn
  • For this behavior, we need to discuss relational operators for if-statements

Reviewing if-statements

  • Remember that to make an if-statement we need to code a test condition
    if (test)
    {
       statement1
       statement2
       ...
    }
    
  • Where:
    • test: the test condition that evaluates to true or false
    • statementX: the statements to execute depending on the test condition
  • The computer uses the test to decide whether or not to execute the statement
  • The test must evaluate to either true or false
  • Last time we discussed a simple test condition:
    if (isAtEdge())
    {
        turn(17);
    }
    
  • Another way to code a test condition is to use a relational (boolean) expression

Boolean Expressions

Relational Expressions

  • All computers can compare two numbers using a relational (comparison) operator
  • Expressions that compare numbers are called a relational expression
  • The relational operator compares two operands like:

    relational expression

  • Algebra uses relational operators and relational operators in Java are similar
  • The following table shows the similarities and differences between algebra and Java
Relational Operators
Math Name Java Examples   Result Notes
= Equal to == 5 == 10
2 == 2
false
true
Do not confuse with = which is assignment.
Not equal to != 5 != 10
2 != 2
true
false
The ! is like the line that "crosses through" the equal sign.
< Less than < 5 < 10
5 < 5
5 < 2
true
false
false
Less than or equal to <= 5 <= 10
5 <= 5
5 <= 2
true
true
false
Be careful not to write =<. Code the symbols in the order people normally say them.
> Greater than > 5 > 10
5 > 5
5 > 2
false
false
true
Greater than or equal to >= 5 >= 10
5 >= 5
5 >= 2
false
true
true
Be careful not to write =>. Code the symbols in the order people normally say them.

Boolean Variables and Relationships

  • Notice that relational expressions always evaluate to either true or false
  • To store a condition that can only be true or false, we use a Boolean variable
  • Boolean variables are named after George Boole (1815-1864), a pioneer in the study of logic
  • We specify a Boolean variable using the boolean data type, which holds just one of two values: true or false
    boolean isCool = true;
    boolean lies = false;
    
  • Thus we can assign a relational expression to a Boolean variable
    boolean test = 5 > 2;
    System.out.println(test);
    

Test Condition Activity (2m)

Formulate the following test conditions in Java, then check your answer by pressing the answer link. Press Submit Work when correct.

answer
answer
answer
answer
answer
answer

More Information

Check Yourself

  1. What is the value of the following test conditions, given x = 3, y = 7?
    1. (x != y)
    2. (x == y)
    3. (x < y)
    4. (x >= y)
  2. The problem with the following test condition is ________.
    if (x =< 42)
    
  3. The value of x after the following code executes is ________.
    int x = 3;
    int y = 4;
    if (x < y)
    {
      x = y;
    }
    
  4. The value of y after the following code executes is ________.
    int x = 42;
    boolean y = (x == 3);
    

3.2.4: Adding a Randomized Walk

  • Operands of a relational expression can be a method call
  • For example:
    Greenfoot.getRandomNumber(100) < 10
    
  • The method call to getRandomNumber() returns an integer between 0 and 99
  • The relational expression lets us test if the random number is less than 10
  • If so, the expression evaluates to true; otherwise the expression evaluates to false
  • We can use random numbers and relational operators to create a random walk for our actors
  • For instance, if we want our actor to turn a little off course 10% of the time, we would code an if-statement like:
    if (Greenfoot.getRandomNumber(100) < 10) {
        turn(5);
    }
    
  • If we want to turn a random amount, we can code something like:
    if (Greenfoot.getRandomNumber(100) < 10) {
        int degrees = Greenfoot.getRandomNumber(45);
        turn(degrees);
    }
    
  • To randomly turn either right or left, we can use:
    if (Greenfoot.getRandomNumber(100) < 10) {
        int degrees = Greenfoot.getRandomNumber(91) - 45;
        turn(degrees);
    }
    

Check Yourself

  1. True or false: one or both of the operands of a relational expression can be a method call.
  2. True or false: to randomly select when to turn we usually write an if-statement with a random number for a test condition.
  3. answer

Exercise 3.2: Natural Movement (5m)

In this exercise, we add more natural movement to our hero using random numbers.

Specifications

  1. If you do not already have the heroes scenario, download lesson3.gfar (or zip) to a convenient place like the Desktop and unzip the file.
  2. Open the scenario (see lesson 1.3.4).
  3. Open the source code editor of the Hero class (see lesson 1.3.8).

    If you have problems, ask a classmate or the instructor for help.

  4. Update the act() method to declare a variable and assign it a random number between 0 and 99 as follows:
    public void act()
    {
        int percent = Greenfoot.getRandomNumber(100);
        move(3);
        if (isAtEdge())
        {
            turn(17);
        }
    }
    

    For more information see section: 3.2.2: Applying Random Numbers.

  5. Add an if-statement to check if the random number from the variable percent is less than 10, so that the hero randomly turns 10% of the time.
    if (percent < 10)
    {
        // add random turn here
    }
    

    Make certain that the move() method is NOT inside the braces of the if-statement.

  6. Inside the new if-statement, add a randomized turn so the hero turns a random amount. For example:
    int degrees = Greenfoot.getRandomNumber(91) - 45;
    turn(degrees);
    

    For more information see section: 3.2.4: Adding a Randomized Walk.

  7. Save your scenario to upload to Canvas later as part of the next lab.

    We will be adding more code to these files in subsequent exercises, so it is not time to submit them to Canvas yet. However, it is a good idea to have a backup copy in case of problems later in development.

  8. When finished, check your code against the listing below and then help other students.

Listing of act() Method

public void act()
{
    int percent = Greenfoot.getRandomNumber(100);
    if (percent < 10)
    {
        int degrees = Greenfoot.getRandomNumber(91) - 45;
        turn(degrees);
    }
    move(2); // any number in range 2-5
    if (isAtEdge())
    {
        turn(17);
    }
}

3.2.5: Summary

  • Most actors in a game or simulation do not walk in straight lines
  • To more closely simulate the behavior of animate objects, we can add randomness to their movement
  • To add random behavior, we start with random numbers
  • We discussed Greenfoot's method for generating random numbers:
    public static int getRandomNumber()(int limit)
    
  • To call the method we write:
    Greenfoot.getRandomNumber(max);
    
  • Where max is one more than the maximum random number wanted
  • The method returns a random integer between 0 and up to, but not including, max
  • Method calls like this are known as dot notation, because there is a dot between the class name and the method name
  • We have to use dot notation whenever the method we want to use is not in the class or its superclasses
  • We can store information, like the call to getRandomNumber(), in a variable
  • To use a variable, you first have to declare it, like:
    int randNum;
    
  • The word int in the above is a data type meaning integer
  • Variables can be assigned values using an assignment operator, which is the equals sign:
    randNum = Greenfoot.getRandomNumber(35);
    
  • We can combine a declaration and assignment into one statement like:
    int randNum = Greenfoot.getRandomNumber(35);
    
  • We discussed various ways to use random numbers for randomizing turns, like:
    int randNum = Greenfoot.getRandomNumber(35);
    turn(randNum);
    
  • For creating a random walk for our actors, we used relational operators
  • The relational operators are tests for equality and inequality of two numbers
  • These tests return a Boolean value, either true or false
  • The relational operators of Java include:
    ==  !=  <   <=  >   >=
    
  • We can use a relational operator for a random walk using code like:
    if (Greenfoot.getRandomNumber(100) < 10) {
        turn(5);
    }
    

Check Yourself

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. How do you store information in a computer's main memory? (3.2.1)
  2. What is the code to declare an int variable named foo and assign it a value of 10? (3.2.1)
  3. True or false: most animals always walk in straight lines. (3.2.1)
  4. What is a random number? (3.2.1)
  5. What code do we write to get a random number? (3.2.1)
  6. True or false: you must specify a class name or object name when calling a method outside the class or its superclasses. (3.2.1)
  7. Which of the following causes an actor to make a random right-turn between 0 and 45 degrees? (3.2.2)
    1. turn(random(45));
    2. turn(getRandomNumber(45));
    3. turn(Greenfoot.getRandomNumber(-45));
    4. turn(Greenfoot.getRandomNumber(45));
  8. Which of the following is NOT one of Java's relational operators? (3.2.3)
    1. >
    2. !=
    3. <=
    4. =>
  9. True or false: a relational expression consist of two operands and a relational operator. (3.2.3)
  10. Which of the following is NOT a relational expression? (3.2.3)
    1. Greenfoot.getRandomNumber(100) < 10
    2. 10 >= Greenfoot.getRandomNumber(100)
    3. Greenfoot.getRandomNumber(100) != Greenfoot.getRandomNumber(100)
    4. <= Greenfoot.getRandomNumber(100) 10
  11. What turn does an actor make with the following statement? (3.2.4)
    turn(Greenfoot.getRandomNumber(91) - 45);
    
  12. How often does an actor turn with the following code? (3.2.4)
    if (Greenfoot.getRandomNumber(100) < 10) {
        turn(5);
    }
    

3.3: Simple Actor Interaction

Learner Outcomes

At the end of the lesson the student will be able to:

  • Add multiple actors to a scenario
  • Write code for actor interaction
  • Write code for class literals

3.3.1: Adding Other Actors

  • To make our games and simulations more interesting, we want to add more actors
  • All heroes like to eat food
  • We may add a Food class by subclassing Actor
  • We will assume that our hero's food does not move
  • Thus the Food class has very little code
  • We add several food objects, right-click on the world background, and then select Save the World

    select save the world

Adding Predators

  • To make our hero scenario more interesting, we add a Predator as well
  • We choose a predator that seems menacing
  • We want a predator to wander around the screen like our hero
  • To start with, we copy the complete act() method of the Hero class into the Predator class
  • We will change act() methods later as we add functionality

Check Yourself

  1. True or false: most games need more than one type of Actor.
  2. True or false: the Food class does not need to call the isAtEdge() method because it does not move.
  3. True or false: with multiple actors, we need to code ways for them to interact.

3.3.2: Interaction Methods

  • Notice that when a hero meets food, nothing happens
  • However, in our scenario, we want our heroes to eat the flowers
  • For our hero to eat flowers, we need two capabilities:
    1. A way for a hero to detect flowers within range
    2. A way to delete the eaten food from the scenario
  • Greenfoot has a method for detecting objects named: isTouching()
  • Also, Greenfoot has a method for removing objects named: removeTouching()
  • Both of these methods are in the Actor class and are shown below

Commonly Used Actor Methods for Interaction

Method Description
isTouching(Class cls) Returns true if this actor is touching another object of the given class; otherwise returns false.
removeTouching(Class cls) Removes one object of the given class that this actor is currently touching, if any exist.

Class Literals

  • To call the isTouching() method, we use code like:
    isTouching(Food.class)
    
  • Similarly, to call removeTouching() we use code like:
    removeTouching(Food.class)
    
  • Both method declarations require a Class description
  • To obtain a Class description, we add .class to the name of a class
  • Adding the ".class" evaluates to what is known as a class literal
  • A class literal is simply a description of a class consisting of the name of a class followed by a "." and the word class
  • An English description of the Food class would be, "Food class"
  • In the Java programming language, a description of the Food class is: Food.class
  • By using a class literal, the isTouching() and removeTouching() methods can look for a specific type of object, rather than all objects

Example Code Calling isTouching() and removeTouching()

if (isTouching(Food.class)) {
    removeTouching(Food.class);
}

Check Yourself

  1. The method isTouching() is defined in the class ________.
  2. True or false: the purpose of method isTouching() is to detect if our actor has touched another actor.
  3. A class literal is created by using the name of the class followed by a dot and the word ________.
  4. True or false: the advantage of using a Class parameter is that we can specify a single type of object.
  5. True or false: a class literal is how you can specify a particular class for a method parameter.

Exercise 3.3: Actor Interaction (10m)

In this exercise, we add methods for object interaction.

Specifications

  1. Start Greenfoot and open the Hero scenario from the last exercise.
  2. Right-click on Actor in the class diagram and select New Subclass...
  3. Type in a name of an actor that is a new food class for your scenario.
  4. Select an appropriate food image for your actor and scenario.
  5. Press the Ok button and verify the subclass was added to the class diagram.
  6. Again, right-click on Actor in the class diagram and select New Subclass...
  7. Type in a name of of an actor that is a new predator for your scenario.
  8. Select an appropriate predator image for your actor and scenario.
  9. Press the Ok button and verify the subclass was added to the class diagram.
  10. Copy the following act() method into your new predator:
    public void act()
    {
        move(3);
        if (isAtEdge())
        {
            turn(17);
        }
    }
    
  11. Open the editor for the Hero class and add the following code to the end of the act() method:
    if (isTouching(YourFoodName.class))
    {
        removeTouching(YourFoodName.class);
    }
    

    Where YourFoodName is the name of your food class.

  12. Press the Compile button and verify there are no errors.

    Resolve any errors you find, getting help from a classmate or the instructor as needed.

  13. Open the source code editor of your predator class and type the following code at the end of the act() method:
    if (isTouching(Hero.class))
    {
        removeTouching(Hero.class);
    }
    
  14. Compile all the classes and verify there are no errors. Resolve any errors you find, getting help from a classmate or the instructor as needed.
  15. Set up several food objects and one or more heroes and a Predator to see how the scenario works. Verify that the hero eats food and the predator eats the hero.
  16. Save a copy of your final scenario with all the changes so far to upload to Canvas as part of the next lab.

    We will be adding more code to these files in subsequent exercises, so it is not time to submit them to Canvas yet. However, it is a good idea to have a backup copy in case of problems later in development.

When finished please help those around you.

3.3.3: Summary

  • We add many actors to most scenarios
  • When we add actors, we usually want then to interact in some way
  • We examined two methods for actor interaction:
    • isTouching(): returns true is we can see an object in the same cell
    • removeTouching(): tries to "eat" (remove from the world) the specified object
  • To make use of the methods, you write code like:
    if (isTouching(Food.class)) {
        removeTouching(Food.class);
    }
    
  • Adding the .class to the name of a class is known as a class literal
  • A class literal is the description of a class
  • For instance, a description of the Food class would be, "class Food"
  • Using the class literal as a parameter allows us to specify a single type of actor rather than all actors

Check Yourself

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. What is a class literal? (3.3.2)
  2. True or false: in our scenario, when we call removeTouching() we always remove an object from the world. (3.3.2)

3.4: Creating New Methods

Learner Outcomes

At the end of the lesson the student will be able to:

  • Discuss the reason for writing methods
  • Define methods with and without parameters

3.4.1: Writing Methods Click for link

  • In the previous sections we added new behavior to the Hero class, like:
    • Turning at the edge of the world
    • Occasional random turns
    • Eating food
  • Notice that the act() method is getting longer and longer as we add code
  • If we continue adding code as we have, the act() method will become really long and hard to understand
  • The biggest problem in developing software is managing the complexity of programs
  • We can improve our code by organizing it into smaller pieces known as methods
  • Methods are a key tool in creating easy-to-understand programs that can be changed easily

What is a Method?

  • As game developers, we need to know how to write and call methods

    Method -- a named sequence of statements that can receive input, perform an action, and optionally return a value.

  • We have looked at methods before, such as the lookForWorm() method from the textbook (p.38):
    /**
     * Check whether we have stumbled upon a worm.
     * If we have, eat it. If not, do nothing.
     */
    public void lookForWorm()
    {
        if ( isTouching(Worm.class) )
        {
            removeTouching(Worm.class);
        }
    }
    
  • Methods are like little programs in our larger program
  • We give each little method something we want it to do
  • We call the method and cause it to be executed from anywhere within our class
  • When the method has finished running, program execution returns to the point just after the code that called the method

Check Yourself

  1. True or false: people write methods to organize code into small understandable pieces.
  2. Which of the following are features of a method?
    1. Must have a name
    2. Can receive input
    3. Performs an action
    4. Must return a value
  3. True or false: when a method finishes executing, the program flow returns to the point just after the code that called the method.

3.4.2: Defining Methods

  • In this section we look at method definition syntax and examine a simple example method
  • After we understand the syntax we can write more complicated methods

Method Syntax

  • The general syntax for defining a new method is:
    public returnType methodName(parameter1, ..., parametern) {
        statements
    }
    
  • Where:
    • returnType: the data type of the value returned
    • methodName: the name you make up for the method
    • parameterx: the input values, if any
    • statements: the statements to execute when calling the method
  • The word public is known as an access modifier
  • Methods have public access if we want to make them accessible to other classes
  • There are other access modifiers but we should use public for now
  • Can you identify each of these syntax items in the act() method we have always used?
    public void act()
    {
        // add commands here
    }
    

Example of Writing a New Method

  • As an example of writing a new method, let us make a method out of our code to look for a food
  • For example:
    /**
     * Checks whether we have stumbled upon a food.
     * If we have, then eat it. Otherwise, do nothing.
     */
    public void lookForFood()
    {
        if (isTouching(Food.class))
        {
            removeTouching(Food.class);
        }
    }
    
  • The overall code is known as a method definition
  • The above code defines a new method
  • Let us look at each part of the new method

Comments

  • The first four lines are a comment
    /**
     * Checks whether we have stumbled upon food.
     * If we have, then eat it. Otherwise, do nothing.
     */
    
  • Comments are ... comments -- notes to people reading the code
  • The computer ignores comments entirely
  • We write comments to explain our code to human readers
  • Every method should have a comment block like the example

Method declaration

  • The next line after the comment is the method declaration:
    public void lookForFood()
    
  • We technically can use words other than public, but for now always use public
  • The return type is the keyword: void
  • The word void is used when we want to return nothing from a method
  • Following the return type is the method name: lookForFood
  • Method names follow rules similar to variable names:
    • A sequence of letters, digits, underscores -- cannot contain spaces
    • Must start with a letter and not a number
    • Names are case sensitive
    • Cannot be a keyword
  • By convention, method names in Java always start with a lower case letter
  • If the name logically has multiple words, then use capital letters to mark the start of a new word
  • Following the method name is a set of parenthesis
  • Inside the parenthesis are the parameters, if any
  • How many parameters are there in this example?

Method Body

  • The last few lines -- the curly braces and anything between them -- is called the method body
  • The method body contains the list of statements executed when the method is invoked (called)

Check Yourself

  1. True or false: The compiler ignores method comments.
  2. True or false: method names are case sensitive.
  3. What is wrong with the following method name? (answer)
    public void 4food() { }
  4. What is wrong with the following method name? (answer)
    public void switch() { }
  5. For the following code, match the syntax item with the code
    public void lookForFood() {
        if (isTouching(Food.class)) {
            removeTouching(Food.class);
        }
    }
    
a. { }
b. lookForFood
c. ( )
d. if (isTouching(Food.class)) {...}
e. removeTouching(Food.class);
f. void

3.4.3: Calling Methods

  • When we define a method, the code does not immediately get executed
  • In fact, defining a method does not guarantee it is ever executed
  • To execute the code in a method, we must code a method call
  • We can call our example method from inside the act() method using the code:
    lookForFood();
    
  • Notice that the method call has an empty parameter list
  • The number and order of parameters must match the parameters defined in the method
  • In this case, there are no parameters defined and so the method call has an empty parameter list

Organizing with Methods

  • Our method and method call does not change the execution of our program
  • Instead, defining short methods like this makes programs easier to understand
  • As we add more code to a class, methods tend to become longer and longer
  • Longer methods are harder to understand
  • By separating our code into a number of short methods, we make the code easier to read
  • For example, if we were to organize all the code of Hero into short methods, we might end up with an act() method like:
    public void act()
    {
        turnAtEdge();
        randomMove(5);
        lookForFood();
    }
    
  • Understanding the act() method is easier when it is short
  • We can clearly see the logic and flow of our act() method

Current act() Method of Hero

public void act()
{
    int percent = Greenfoot.getRandomNumber(100);
    if (percent < 10)
    {
        int degrees = Greenfoot.getRandomNumber(91) - 45;
        turn(degrees);
    }
    move(2);
    if (isAtEdge())
    {
        turn(17);
    }
    if (isTouching(Food.class)) {
        removeTouching(Food.class);
    }
}

Check Yourself

  1. True or false: defining a method means it will be executed.
  2. True or false: method calls always have parenthesis, even when a method does not define any parameters.
  3. True or false: defining short methods makes it easier to understand the logic of a program.

3.4.4: Parameters

  • When defining a method, it is worth thinking about what helpful action it will perform
  • We can sometimes make a method more useful if we give it parameters
  • Recall from lesson 2.4.3 that every method has a parameter list

    Parts of a method

  • Even methods that accept no parameters have an empty parameter list
  • Thus, we always have parenthesis when we define a method

Adding Parameters

  • For some methods adding a parameter makes the method more useful
  • For example, we add a parameter to randomMove() like:
    public void randomMove(int speed)
    
  • Our randomMove() method now receives the number of cells to move in the speed parameter
  • We move the number of pixels in speed when the method is called as shown in the following example

Passing Arguments to a Method

Passing arguments in a method call

Arguments and Parameters

  • Depending on our background, we might use the term arguments or parameters for the values passed to methods
  • The terminology is not that important
  • However, the way I will use the terms:
    • A method definition has parameters
      public void randomMove(int speed) // speed is a parameter
          // ...
      }
      
    • A method call passes arguments
      randomMove(5); // 5 is an argument
      
  • Arguments are values our code passes into methods
  • When the argument drops into a method, it lands into a parameter
  • A parameter is just like other variables in the method
    • Except that a parameter gets initialized by an argument
  • The important part is:

    We must pass every method parameter an argument.

  • The arguments must be in the same order as the parameters
  • Also, the argument value must be compatible with the type of the parameter
  • For example, we cannot call randomMove() with: randomMove("Ed Parrish")
  • Instead we call randomMove() with: randomMove(5)

Check Yourself

  1. To received input, a method has __________.
  2. Parameters are set on the first line of a function inside a set of __________
    1. Curly braces -- { }
    2. Parenthesis -- ( )
    3. Square brackets -- [ ]
    4. Colons -- : :
  3. True or false: like any other variable, a method parameter has both a type and a name.
  4. If a method has three parameters, a method call must include ________ arguments.
  5. For the following method declaration, the parameter names are __________
    int add(int a, int b)
    
    1. a
    2. b
    3. both a and b
    4. cannot tell from the method declaration

Exercise 3.4: Writing Methods (10m)

In this exercise, we reorganize our Hero class by writing new methods and copying code from the act() method into these new methods.

Specifications

  1. Start Greenfoot and open the Hero scenario from the last exercise.

    If you are missing the scenario then download and open the file: lesson3b.gfar (or zip).

  2. Add the following method to the Hero class:
    /**
     * Checks whether we have stumbled upon food.
     * If we have, then eat it. Otherwise, do nothing.
     */
    public void lookForFood()
    {
        if (isTouching(Food.class))
        {
            removeTouching(Food.class);
        }
    }
    

    For more information see lesson: 3.4.2: Defining Methods.

  3. Change the act() method of Hero to remove the code copied to the method, and then add a method call in its place.
    public void act()
    {
        // ... other code here
        if (isTouching(Food.class)) {   // moved to lookForFood
            removeTouching(Food.class); // moved to lookForFood
        }                               // moved to lookForFood
        lookForFood();
    }
    

    For more information see lesson: 3.4.3: Calling Methods.

  4. Continue to replace code in the act() method by adding two new methods to the Hero class, moving the appropriate code from the act() method:
    • public void turnAtEdge()
    • public void randomMove(int speed)
  5. Change the act() method of Hero as follows:
        public void act()
        {
            turnAtEdge();
            randomMove(3);
            lookForFood();
        }
    

    When completed, compile the class and verify there are no errors. Resolve any errors you find, getting help from a class mate or the instructor as needed.

  6. Save a copy of your final scenario with all the changes made to upload to Canvas as part of the next lab.

When finished developing your code click here Click to show answer to compare your solution to mine. After you have completed your own solution, reviewing another is often helpful in learning how to improve your programming skills.

As time permits, read the following sections and be prepared to answer the Check Yourself questions in the section: 3.4.4: Summary.

3.4.5: Returning a Value

  • The word before the name of a method tells the compiler the type of data returned
    public void lookForFood()
  • The keyword void tells the compiler that the method returns nothing
  • If we want a method to return a value then we must change two things:
    1. Make the return type a data type like int
    2. Add a return statement to our method
  • As an example method, lets us add method getFoodEaten() to our scenario
    public int getFoodEaten()
    {
        return foodEaten;
    }
    
  • The return type int specifies the type of data the method returns

Return Statement

  • Functions that return a value must execute a return statement
    return foodEaten;
    
  • Our example method returns the value of a variable
  • The type of the returned value must be compatible with the method return type
  • The return statement executes as soon as the line is reached
  • Therefore the return statement must be placed after other statements that execute

Implementing the Method

  • For our method, we need to add an instance variable to the scenario with a type int
    private int foodEaten;
    
  • Then in the lookForFood() method we store the number of food eaten to the variable
    foodEaten = foodEaten + 1;
    
  • After running our scenario, we can pause, right-click on the actor and select the method

Example Method Return

Returning values from a method call

Check Yourself

  1. To return a value from a method use a __________ statement.
  2. True or false: a value returned from a method must be compatible with the method return type.
  3. The following method returns the value ________.
    public int get42()
    {
      return 42;
    }
    
  4. The following method returns the value ________.
    public int twice(int x)
    {
      return x * 2;
    }
    
    1. 2
    2. 42
    3. x
    4. twice the parameter

3.4.6: Summary

  • As we add more code to methods, they can become too long to easily understand
  • The solution is to break up the long sequences of code into shorter sections using methods

Defining Methods

  • Methods allow you to organize code within a class
  • To define a method, we use the following syntax:
    public returnType methodName(parameter1, ..., parametern) {
        statements
    }
    
  • Where:
    • returnType: the data type of the value returned
    • methodName: the name you make up for the method
    • parameterx: the input values, if any
    • statements: the statements to execute when the method is called
  • The word public is known as an access modifier
  • Methods have public access if we want to make them accessible to other classes
  • As an example, we wrote the method:
    public void randomMove(int speed) // speed is a parameter
    {
        int randNum = Greenfoot.getRandomNumber(100);
        if (Greenfoot.getRandomNumber(100) < 10)
        {
            turn(Greenfoot.getRandomNumber(100) - 45);
        }
        move(speed);
    }
    
  • If the method does not return a value, we use the return type: void
  • Otherwise, we specify the type of data we want to return like
    public int getFoodEaten()
    {
        return foodEaten;
    }
    
  • A method name follows the same rules as variable names
  • However, the method name is always followed by a set of parenthesis
  • Inside the parenthesis are the parameters, if any
  • We should always provide a comment block before a method
  • The comment helps explain the method to humans reading the code

Calling Methods

  • When we define a method, the code does not execute automatically
  • To execute the code, we must code a method call like:
    randomMove(5);
    
  • When we call a method, we specify its name and provide arguments for each parameter
  • The flow of the program execution stops and jumps to the called method
  • When the called method finishes executing it returns

Parameters and Arguments

  • When we define a method, we want it to be reusable
  • To make a method more reusable, we avoid hard-wiring important values
  • Instead, we pass the key values by defining parameters
  • A parameter is a variable that receives information during a method call
  • To identify their special ability, parameters are declared inside the parenthesis () of a method definition
    public void randomMove(int speed) { /* statements */ }
    
  • When we call a method, we supply an argument for each parameter
    randomMove(5)
    
  • Parameter variables hold the argument values when we call a method

    method parameter flow

Returning a Value

  • If we want a method to return a value then we must change two things:
    1. Make the return type a data type like int
    2. Add a return statement to our method
  • Here is an example method return a value:
    public int getFoodEaten()
    {
        return foodEaten;
    }
    
  • The return type int specifies the type of data the method returns
  • Functions that return a value must execute a return statement
    return foodEaten;
    
  • Our example method returns the value of a variable
  • The type of the returned value must be compatible with the method return type

Check Yourself

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. Why do programmers write methods? (3.4.1)
  2. What is a method? (3.4.1)
  3. How can you tell the difference between a method name and a variable name? (3.4.1)
  4. What are items always present in a method declaration? (3.4.1)
  5. What is the purpose of comments? (3.4.2)
  6. True or false: The compiler ignores comments. (3.4.2)
  7. What is wrong with the following method name? (3.4.2)
    public void 4food() { }
  8. What is wrong with the following method name? (3.4.2)
    public void switch() { }
  9. Which of the following is a method definition and which is a method call? (3.4.3)
    1. public void lookForFood() { }
    2. lookForFood();
  10. True or false: Within reason, shorter methods are easier to understand than longer methods. (3.4.3)
  11. How can you use methods to make your code easier to understand? (3.4.3)
  12. To return a value from a method use a __________ statement. (3.4.4)
  13. True or false: a value returned from a method must be compatible with the method return type. (3.4.4)
  14. The following method returns the value ________. (3.4.4)
    public int get42()
    {
      return 42;
    }
    

3.5: Bells and Whistles

Learner Outcomes

At the end of the lesson the student will be able to:

  • Write code for keyboard interaction
  • Describe the String data type
  • Write code to produce sound effects
  • Write code to end a scenario
  • Find class and method documentation in the Greenfoot API

3.5.1: Keyboard Interaction and Strings

  • So far the actors in our scenario move on their own
  • What we want to do with our hero is get the player involved
  • We want the player to control the actions of the hero using the keyboard
  • The Greenfoot framework has a method that lets us check whether a key on the keyboard has been pressed
  • The method is in the Greenfoot class and its signature is:
    static boolean isKeyDown(String keyName)
    
  • As we can see, the method is static and the return type is boolean
  • This means that the method returns true or false and we can use it in an if-statement
  • However, notice that the data type of the parameter is new: String
  • In order to use this method, we need to look at the String data type

Strings

  • A string is a sequence of characters (letters, digits, other symbols)
  • To indicate a string in a program we enclose the characters within double quotes
  • For example:
    "This is a string"
    "b"
    "$3.95"
    "My name is Ed"
    
  • We create variables for strings using the String data type
  • For example:
    String firstName;           // declaration
    firstName = "Edward";       // assignment
    String lastName = "Parrish" // declaration + assignment
    
  • When a method parameter expects a String, we must provide either characters in double quotes or a variable of type String

Check Yourself

  1. To check whether a key on the keyboard has been pressed, call the Greenfoot class method ________.
  2. A sequence of character values is known as a(n) ________.
  3. The name of the data type for storing strings in variables is ________.
    1. String
    2. string
    3. str
    4. Text

3.5.2: Using Strings to Specify Key Presses

  • To call the isKeyDown() method, we need a String argument
    static boolean isKeyDown(String keyName)
    
  • So what string do we provide for the method call?

Key Names

  • Every key on the keyboard has a name
  • For keys that produce a visible character, that character is their name
  • For example, the A-key is named "A" (or "a")
  • The number keys are: "0", "1", ..."9"
  • Other keys have names as well
  • The cursor keys are named: "up", "down", "left", "right"
  • Other control characters include: "enter", "space", "backspace"
  • The function keys are: "F1", "F2", .., "F12"
  • For more information, see the Class Greenfoot documentation

Using isKeyDown()

  • If we want to test for the right-cursor key, we write an if-statement like:
    if (Greenfoot.isKeyDown("right"))
    {
        // do something
    }
    
  • For example, to make an actor turn right by 10 degrees we would write:
    if (Greenfoot.isKeyDown("right"))
    {
        turn(10);
    }
    
  • We can add this code to a method and call the method from the act() method
  • For instance:
    /**
      * Check if a control key has been pressed and react.
      */
    public void checkKeyPress()
    {
        if (Greenfoot.isKeyDown("right"))
        {
            turn(10);
        }
    }
    
  • Then the act() method would look like:
    public void act()
    {
        checkKeyPress();
        // other methods omitted
    }
    

Check Yourself

  1. When calling isKeyDown() to check the B-key, use the argument ________.
  2. When calling isKeyDown() to check the left-cursor key, use the argument ________.
  3. answer

  4. The best place to put the above if-statement is in the ________ method.
    1. act()
    2. isAtEdge()
    3. checkKeyPress()
    4. move()

3.5.3: Adding Sound

  • Another "bell and whistle" we can add to our scenario is sound
  • As before, a method in the Greenfoot class can help us
  • By looking through the documentation, we find the playSound() method
  • The method expects a String parameter, which is the name of the sound file
  • The scenario from the book has some sound files and we will use one for our example: slurp.wav
  • We must add the sound file to the "sounds" folder in our scenario
  • To play the sound, we use the command:
    Greenfoot.playSound("slurp.wav");
  • As you can see, the file name is specified as a string
  • A convenient place to add the command in the Hero class is in lookForFood()
  • Our hero then makes a noise while eating

Getting Sounds

  • To play sampled sound, we need some sound files
  • We can get free sound effects files from the Internet like:
  • However, make sure to verify the licensing
  • Also we can create your own sounds using the microphone on your cell phone or other device
  • Then we can edit the sounds using a sound editing program
  • Free sound editing programs include:

Sound File Size

  • Sound files can become quite large
  • When developing a game, we need to find or develop sound files that convey the effect we want without becoming overly large
  • As a rule of thumb, we want no sound file larger than one megabyte
  • Also, the sum total of all sound files should be no larger than three megabytes
  • If we find our sound files are too large, we can use a sound editing program to reduce the size
  • For instance, using mono rather than stereo will cut the sound size in half
  • Another good idea is to use an MP3 format with medium, or higher, compression

Check Yourself

  1. To play sounds, first add the sound files to the ________ folder of your scenario.
  2. To play a sound file, call the Greenfoot class method ________.
  3. True or false: you can use any sound file you can find on the Internet.

3.5.4: Ending the Scenario

  • One last "bell and whistle" we add to our scenario is to stop when the hero is caught by a predator
  • Again, the Greenfoot class has a method to help us
  • We just need to find the method
  • To find out what methods are available, we look in the Greenfoot API

The Greenfoot API

  • The documentation for the Greenfoot classes is known as the Greenfoot API
  • API is an acronym for Application Programming Interface
  • We can find the Greenfoot API in Greenfoot by using the Help menu

    From the Help menu, select Greenfoot Class Documentation

  • This will show us the documentation for all the Greenfoot classes in a Web browser
  • Another way to find the documentation is online at https://www.greenfoot.org/files/javadoc/
  • The API shows all the available classes and we can follow the hyperlinks to find details about each class

Finding the Method

  • The method we are interested in is in the Greenfoot class
  • We click on a hyperlink for the Greenfoot class
  • When we get to the class, scroll down and look through the methods
  • Each method is listed and the one we are interested in has an explanation that says

    Pause the execution.

  • We can follow the hyperlink of the method name and often get more detailed information about the method

Check Yourself

  1. The acronym API stand for A________ P________ I________.
  2. True or false: the name of the documentation for Greenfoot classes is called the Greenfoot API.
  3. To end a scenario, call the Greenfoot class method ________.

Exercise 3.5: Keypresses and Sounds (10m)

In this exercise, we add keyboard controls and sounds to our scenario. In addition, we add a stopping condition.

Specifications

  1. Start Greenfoot and open the Hero scenario from the last exercise.
  2. Open the source code editor of the Hero class.
  3. In the Hero class, add a method to check if a control key has been pressed and react when pressed. Here is the start of the method:
    /**
     * Check if a control key has been pressed and react.
     */
    public void checkKeyPress()
    {
        if (Greenfoot.isKeyDown("right"))
        {
            turn(10);
        }
    }
    

    Be sure to call the method from the Hero act() method.

  4. Add to checkKeyPress() the code to turn left by pressing the left-cursor key.
    if (Greenfoot.isKeyDown("left"))
    {
        turn(-10);
    }
    

    For more information see lesson: 3.5.2: Using Strings to Specify Key Presses.

  5. Compile the class and verify there are no errors. Then test your scenario to verify the hero changes direction under keyboard control.
  6. Now that we can control the Hero with the keyboard, remove the randomMove() method and replace the call to randomMove() in the hero's act() method with a call to move(2).
  7. Save the following sound file in the scenario sounds folder: slurp.wav

    sounds folder

    For more information see lesson: 3.5.3: Adding Sound.

  8. In the source code of the Hero class and add the following code to the lookForFood() method after the removeTouching() method call:
    Greenfoot.playSound("slurp.wav");
    
  9. Compile the class and verify there are no errors. Then test your scenario to verify the hero eats food.
  10. Save the following sound file in the scenario sounds directory: au.wav
  11. Change the code in your predator class to play au.wav sound and the stop the scenario after eating the hero.
  12. Compile and run your scenario to verify all the changes work well:
    1. Hero eats flowers and makes eating noises
    2. Predator eats the hero and makes eating noises
    3. Game stops when the predator eats the her

    If you have problems, ask a classmate or the instructor for help as needed.

  13. Save a copy of your final scenario with all the changes made to upload to Canvas as part of the next lab (Lab 3).

As time permits, read the following sections and be prepared to answer the Check Yourself questions in the section: 3.5.5: Summary.

3.5.5: Summary

  • In this section we looked at several features that add interest and excitement to a game or simulation
  • First we looked at how to control actors using the keyboard
  • The important method was found in the Greenfoot class:
    static boolean isKeyDown(String keyName)
    
  • The method checks to see if a particular key is pressed
  • The particular key is specified using a String parameter
  • A string is a sequence of characters and you can specify the characters by placing them in double quotes
  • For instance:
    "This is a string"
    "A"
    "left"
    "right"
    
  • Another way to send the parameter information is to use a String variable like:
    String leftKey;
    leftKey = "left";
    String rightKey = "right";
    
  • When a method parameter expects a String, we must provide either characters in double quotes or a variable
  • Every key on the keyboard has a name
  • For keys that produce a visible character, that character is their name
  • For example, the A-key is named "A" (or "a")
  • The number keys are: "0", "1", ..."9"
  • The cursor keys are named: "up", "down", "left", "right"
  • Other control characters are: "enter", "space", "tab", "escape", "backspace"
  • The function keys are: "F1", "F2", .., "F12"
  • Since the isKeyDown() method returns a boolean type, we can use it in an if-statement like:
  • If we want to test for the right-cursor key, we write an if-statement like:
    if (Greenfoot.isKeyDown("right"))
    {
        // do something
    }
    
  • Another "bell and whistle" we can make to our scenario is the addition of sound
  • We must first place the sound file in the sounds folder of our scenario
  • Then to play the sound, we use the command:
    Greenfoot.playSound("filename.wav");
  • Finally we discussed how to look up classes and method in the Greenfoot API
  • You can find the class documentation from within Greenfoot using the help menu
  • Selecting the Greenfoot Class Documentation from the Help menu opens the documentation in a browser
  • Once you have opened the document ion, you follow the hyperlinks to find the information you want

Check Yourself

Answer these questions to check your understanding. You can find more information by following the links after the question.

  1. A sequence of character values is known as a(n) ________. (3.5.1)
  2. The string among the following is ________. (3.5.1)
    1. "42"
    2. 42
    3. 42.0
    4. '42'
  3. The name of the data type for storing strings in variables is ________.
    1. String
    2. string
    3. str
    4. Text
  4. To check whether a key on the keyboard has been pressed, call the Greenfoot class method ________. (3.5.1)
  5. When calling isKeyDown() to check the B-key, use the argument ________. (3.5.2)
  6. When calling isKeyDown() to check the left-cursor key, use the argument ________. (3.5.2)
  7. Where do you place sound files that you want to play in a scenario? (3.5.3)
  8. What is the name of the method that plays sounds? (3.5.3)
  9. True or false: the name of the documentation for Greenfoot classes is called the Greenfoot API. (3.5.4)
  10. To end a scenario, call the Greenfoot class method ________. (3.5.4)

Wrap Up

Due Next:
Q2: First Program (2/13/20)
B3: Random choices (Canvas) (2/18/20)
Lab 3: Finishing the Crab (2/18/20)
Q3: Methodical Improvement (2/20/20)
  • When class is over, please shut down your computer
  • You may complete unfinished lesson exercises at any time before the due date.
Last Updated: February 16 2020 @18:24:57