# 5: Side Scrollers

## Illuminations

#### Homework Questions?

• Lab 4: White Blood Cell (2/21/17)
Q4: Finishing Touches (2/23/17)
• Please do not put spaces in folder names of zip files turned in for homework
• The Java compiler has problems with spaces in folder or file names
• Did anyone attempt XC 2? (populate world from array using a loop)

## 5.1: Creating a Scrolling world

### Learner Outcomes

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

• Create a scrolling world scenario
• Automatically places tiles in a world
• Scroll tiles as the scenario runs

### 5.1.1: Scrolling Worlds

• The White Blood Cell (WBC) scenario is an example of a scrolling video game

Scenario file: WBC.gfar.

• The first scrolling video game was Kee Games Super Bug released in 1977
• "Super Bug" in this case refers to the Volkswagen Beetle, which was often referred to as a "bug"

#### WBC Character Movement

• WBC action is viewed from a side-angle view
• The main player character (PC) stays mostly stationary
• To create the illusion of motion, the background and other onscreen actors move
• Actors move by calling the `setLocation()` method in combination with `getX()` and `getY()` like:
```setLocation(getX() - speed, getY());
```
• The `getX()` and `getY()` commands return the current (x, y) coordinates
• Recall that Greenfoot Actors are located by a coordinate system that starts in the upper left-hand corner (see below)
• By adding or subtracting an amount of pixels to the current coordinates, the characters moves
• The movement is independent of the direction the character is pointing

#### Methods Controlling Movement

Method Description
getX() Return the x-coordinate of the actor's current location.
getY() Return the y-coordinate of the actor's current location.
move(distance) Move the actor the specified distance in the direction it is currently facing.
setLocation(x, y) Move the actor to the specified location.

#### Check Yourself

1. True or false: the coordinate system used by Greenfoot is the same as that used in algebra.
2. The origin of the (x, y) coordinate system is located at the ________.
1. upper left-hand corner of the window
2. upper right-hand corner of the window
3. lower right-hand corner of the window
4. lower left-hand corner of the window
3. True or false: in the coordinate system used by Greenfoot, locations shown in the window are always positive numbers.
4. To set the location of an actor we call the ________ method, passing arguments for the (x, y) coordinates

### 5.1.2: Creating a Scrolling World

• In this section we create our own scrolling world game named `scroller`
• The first step is to decide on your theme, like Space
• Once we have settled on a theme, we create a `World` subclass
• We open the editor for "MyWorld" and change it to something appropriate like "ScrollWorld"
• We leave the world with no background image ("No image")
• Some scrolling games do have a background image, like WBC
• However, we will supply the background image using scrolling tiles

#### Unbounded Worlds

• By default, Greenfoot does not allow actors to go outside the world
• In our scrolling world game, actors appear on the right and disappear on the left
• This behavior means we will see background actors suddenly appear and disappear at the edges
• WBC solved the problem by adding a border at the edge that hid the odd behavior
• Another option is to change the default behavior and allow actors to move outside the world
• Then we add and remove background actors off screen
• We allow actors to go outside the world by changing our call to `super()` in our `World` subclass
• For instance, in our `ScrollWorld` we can write
```super(600, 400, 1, false);
```
• The fourth variable, `false`, is added to let actors move outside the boundaries of the world

• We continue setting up our game by placing a `Player` character in the game as a reference
• Choose a player character image, any desired image, like `rocket.png`.
• We typically place the character on the left side of the game for a side scroller
• We will add player movement after we have set up the background
• Once we have the player positioned, we right-click on the world background and select the Save the World function
• This creates a `prepare()` method in our world and saves the location of our player

#### Scrolling Backgrounds

• For a scrolling background, we need actors that serve as the background of the game
• The background actors move across the screen to create the scrolling effect
• In the next sections, we will create a tile map for our scrolling background

#### Activity: Starting the Scenario (4m)

1. Choose a theme for a scrolling world game and create a new scenario named "scroller".

Please use the specified names if you want credit because it makes grading easier.

2. Open the editor for the world subclass and change the class name and constructor name to `ScrollWorld` like:
```public class ScrollWorld extends World
{

/**
* Constructor for objects of class ScrollWorld.
*
*/
public ScrollWorld()
// other code omitted
```
3. In addition, set the world to an unbounded state by changing the call to `super()` like:
```super(600, 400, 1, false);
```
4. Create a player character and position it in the world.
5. Right-click on the world background and select the Save the World option.
6. Save your scenario so you can update it in future exercises.

#### Check Yourself

1. True or false: by default, Greenfoot prevents actors from moving outside the world boundaries.
2. If you want an unbounded world, set the fourth parameter of the `World` constructor, which is called using `super()`, to ________.
3. True or false: "off screen" means an actor is outside what can be seen on the game screen.
4. The default background color of a world when no images are selected is ________.

### 5.1.3: Tiles and Tile Maps

• A common approach for developing game worlds is to use tile maps
• A tile map is a technique for generating large graphics from a number of smaller graphics
• Tile maps have been used for many years in games such as the early Legend of Zelda games
• The technique is still popular today because:
1. Tile maps save main computer memory
2. Tile maps increase real-time rendering performance

#### Laying Out Tile Maps

• A tile map breaks down a game world into a grid as shown in the diagram below
• Each cell in the grid contains either a small tile object or nothing

• Tile-based maps are like creating a game world with building blocks
• We use only a few different blocks but we can use as many of each block as we want
• Each tile object in the map contains a reference to the image that belongs in a cell of the grid
• When Greenfoot draws the tile at a location, it takes the referenced image and draws it on the screen
• The program thus uses the same image at many places on the screen
• By reusing the image many times, the program needs to store fewer images
• Thus we only need a few small images to draw an entire scenario

#### Check Yourself

1. For the above image, and ignoring the grid lines, to draw the tile map you need ________ image(s).
2. In the above tile map, the number of time the same image is displayed is ________.
3. Of the following statements, the one that correctly describes how a tile maps saves memory space is ________.
1. tiles are arranged in a two-dimensional grid to create a larger image.
2. not all grids locations are filled with tile objects.
3. the program draws the same small image at multiple places in the world
4. each tile object is smaller than the entire world.

### 5.1.4: Tiles and Constant Variables

• In this section we create a tile background for our scrolling game
• The first step is to create a `Tile` actor and assign it an image
• For example, for our space game we choose the `space.jpg` background for the tile

#### Finding the Image Size

• Once we choose the tile background, we need to know the size of the image
• We will be using the image size to calculate where to place the images in our scenario
• We can usually discover the image size by looking in our scenario's image folder
• Another way to discover the size is to temporarily add the following code to the `act()` method of the `Tile` class
```GreenfootImage img = getImage();
System.out.println("Width: " + img.getWidth());
System.out.println("Height: " + img.getHeight());
```
• By adding a tile to the world and pressing the Act button once, the terminal window displays the image size like:
```Width: 64
Height: 64
```
• The size of the image should be small to conserve memory and increase performance

#### Constant Variables

• Once we know the size of the background image we need to save its size for use in some calculations
• One good way to save the size is to use a constant variable
• A constant variable (or constant) is a variable that cannot change after being assigned a value
• A constant variable seems oxymoronic, but is actually quite useful
• To declare a constant in Java, we use the keyword: `final`
```public static final int WIDTH = 64;
public static final int HEIGHT = 64;
```
• We must assign a value when the constant is declared
• If we tried to assign a value in a later statement, we get a compile-time error
• Notice that the name is all uppercase letters with an underscore separator
• This is a common coding convention that professional programmers follow and you should as well
• The advantage of saving the size in a variable is we can easily change the tile image
• When we make a change, all we will need to do is update the constant and our calculations still work

#### Keyword `static`

• We usually make a constant an instance variable and use the keyword `static`
```public static final int WIDTH = 600;
public static final int HEIGHT = 400;
```
• When used with a variable, the keyword `static` makes a single copy of the variable available to all objects of a class
• The `static` keyword is used because only one constant value is needed for all objects
• After creating the constant variable, we substitute it for all numbers like:
```super(WIDTH, HEIGHT, 1, false);
```
• Then if we ever decide to change the height we can adjust by changing a single number
• Another advantage of using constants is that you can easily tell what the number is for
• Using a constant variable instead of a literal number is a way of documenting what the number means
• Yet another advantage of a constant is that we can declare them `public` if necessary
• Since constants cannot change it is acceptable programming practice to declare them `public`
• When declaring `public` constants, other classes can know the value without causing problems
• Thus in the case of the world size, other classes can easily know the size of the world class using code like:
```int worldWidth = SrollingWorld.WIDTH;
```

1. Start Greenfoot and open the scrolling world scenario from the last Activity.
2. Open the `ScrollWorld` class and record the width and height of the world using two `public static` constant variables like:
```public static final int WIDTH = 600;
public static final int HEIGHT = 400;
```
3. Now update the world size command to use these constant variables in the world constructor like:
```super(WIDTH, HEIGHT, 1, false);
```
4. Next create a `Tile` subclass of `Actor` and assign it an image.
5. Find the width and height of the tile image you chose
6. Record the width and height in two `public static` constant variables in the `Tile` class like:
```public static final int WIDTH = 64;
public static final int HEIGHT = 64;
```

Your `WIDTH` and `HEIGHT` values will depend on the image you selected. We can use the same constant names since we are declaring the variables in different classes.

7. Compile your scenario to make sure the changes were made correctly.

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

8. Save your scenario so you can update it in future exercises.

#### Check Yourself

1. A better solution than adding the same number to several places in a class is to add a __________ variable.
2. The keyword Java uses to make a variable constant is __________.
3. True or false: you should use named constants rather than literal numbers in your code so you can easily tell what the number means.
4. True or false: constants should be written in lower case letters so you cannot easily tell the variable is constant.

### 5.1.5: Placing Tiles

• Now that we have a tile for the background we need to place the tiles
• We could manually place all the tiles and call the Save the World function
• However, manual placement is a tedious and error prone activity
• Also, what if we decide to change the tile image?
• A better approach than manual placement is to add code that automatically place tiles

#### Calculating Tile Position

• The first tile we want to place is in the upper-left-hand corner of the screen
• We carefully place the tile and check its (x, y) coordinates
• When checking, notice that the coordinates of the first tile are ½ the tile width and height
• This is because Greenfoot calculates the position of an actor from the center of its image
• Thus we can calculate the position of the first tile by adding the following code to the `prepare()` method:
```int leftX = Tile.WIDTH / 2; // leftmost x-coordinate for a tile
int topY = Tile.HEIGHT / 2; // highest y-coordinate for a tile
```
• Notice the use of the `new` operator: `new Tile()`
• As we discussed in lesson 4.2.3, we are constructing a new `Tile` object
• The keyword `new` tells Java to construct a new object from the class
• We use the `World` method `addObject()` to add the new tile object to the world
• To add more tiles, we would place them exactly one tile width to the side until the row is complete
• Then we would add the next row and repeat the placement process to position all the tiles in the world

#### Repeating Calculations with the `for`-Loop

• We need to repeat our calculation for tile locations and place additional tiles
• To repeat code we use `for`-loops and arithmetic to calculate locations
• We can visualize the `for`-loop as a series of steps to reach a goal
• In this case, the steps to reach our goal are the placement of tiles within the grid system of our world
• Recall from lesson 4.2.4 the syntax of the `for`-loop:
```           ❶    ⇛    ❷   ⇚   ❸
for (int i = start; i < end; i = i + 1) {
...
}
```
• Where:
• i: the name of a counter variable
• start: the initial starting value
• end: the final ending value
• As an example, we could place a row of tiles in the world by adding the following code to the start of the `prepare()` method:
```int leftX = Tile.WIDTH / 2;  // leftmost x-coordinate for a tile
int topY = Tile.HEIGHT / 2;  // highest y-coordinate for a tile
int tilesHorz = WIDTH / Tile.WIDTH + 2; // number of tiles across
for (int x = 0; x < tilesHorz; x++)
{
int tileY = topY;
int tileX = leftX + Tile.WIDTH * x;
}
```
• The first two lines calculate the position of the first tile
• The third line calculates the number of tiles needed across the screen
• We add an extra tile to allow tiles to be off screen when being added to or removed from the world
• The `for`-loop counts the number of tiles across one at a time
• Inside the `for`-loop we calculate the new tile's x-coordinate on the first line:
```int tileX = leftX + Tile.WIDTH * x;
```
• The last line of the `for`-loop adds a new tile at the calculated position
• Lets trace the calculation of the x-coordinate of the tile

#### Activity: Tracing the Loop (4m)

```int leftX = Tile.WIDTH / 2; // leftmost x-coordinate for a tile
int topY = Tile.HEIGHT / 2; // highest y-coordinate for a tile
int tilesHorz = WIDTH / Tile.WIDTH + 2; // number of tiles across
for (int x = 0; x < tilesHorz; x++)
{
int tileY = topY;
int tileX = leftX + Tile.WIDTH * x;
}
```

For the above code, trace the loop and enter the first three values of `tileX` and `tileY` into the following table. Assume that `Tile.WIDTH == 64` and `Tile.HEIGHT == 64`. Press the Submit button to record your answer.

Tracing the Loop
`x` `tileX` `tileY`
0
1
2

#### Testing Our Trace

• We should always test to verify our understanding
• In general, we should test our code every time we add a few lines
• To test our tile placement, we right-click a Tile object and select Inspect

#### Filling the Screen

• To finish filling the screen with background tiles we need to calculate the y-coordinate as well the x-coordinate
• First we need to calculate the number of tiles to place vertically:
```int tilesVert = HEIGHT / Tile.HEIGHT + 1; // +1 for top/bottom buffer
```
• We simply divide the world height by the tile height
• Unless the world height is an exact multiple of the tile height, we need to add one more tile
• Once we know the number of tiles, we add another loop around the existing loop as shown below

#### Example Code to Place Tiles in the World

```int leftX = Tile.WIDTH / 2; // leftmost x coordinate for a tile
int topY = Tile.HEIGHT / 2;    // highest y coordinate for a tile
int tilesVert = HEIGHT / Tile.HEIGHT + 1; // +1 for top/bottom buffer
int tilesHorz = WIDTH / Tile.WIDTH + 2;   // +2 for scrolling buffer
for (int y = 0; y < tilesVert; y++)
{
int tileY = topY + Tile.HEIGHT * y;
for (int x = 0; x < tilesHorz; x++)
{
// int tileY = topY;
int tileX = leftX + Tile.WIDTH * x;
}
}
```

#### Nested Loops

• Notice that the above code has a `for`-loop nested inside another `for`-loop
• By analogy, nested loops are like an odometer on a car
• The numbers to the right loop completely before the number to the left increments by one

• The inner loop is like the numbers to the right in the odometer
• An inner loop runs to completion every time the outer loop executes once

#### Analyzing a Nested Loop

• The best way to understand nested loops is to work from the inside out
• The inner loop in our example places all the tiles in a row
```for (int x = 0; x < tilesHorz; x++)
{
int tileX = leftX + Tile.WIDTH * x;
}```
• The outer loop moves the y-coordinate from one row to the next
```for (int y = 0; y < tilesVert; y++)
{
int tileY = topY + Tile.HEIGHT * y;
// inner loop here or call placeRow()
}
```
• Oftentimes people place inner loops inside a method to clarify the logic

#### Check Yourself

1. Instead of repeating statements we can often use a ________.
2. When you clap your hands 10 times:
1. You know when to stop because you ________
2. Every time you clap, the count ________.
3. For the example loop shown below, the loop repeats ________ times.
```for (int counter = 0; counter < 5; counter++)
{
System.out.println(counter);
}
```
4. True or false: the purpose of the variable `counter` in the above loop is to keep track of the number of repetitions.
5. True or false: a loop can be nested inside another loop.
6. By analogy to an odometer, an inner loop is like the digits to the ________.
7. Every time an outer loop iterates once, an inner loop runs ________.
1. completely
2. incrementally
3. partially
4. twice

### 5.1.6: Moving the Tiles

• We can now automatically place the background tiles
• To create the illusion of motion, we move the background tiles
• The player character is more or less stationary
• The tiles move in the opposite direction we want the player character to seem to move

#### Moving the Tiles

• To move the tiles we call `setLocation()` from the `act()` method of `Tile`
```private static final int SPEED = 1; // some values leave gaps

public void act()
{
setLocation(getX() - SPEED, getY());
}
```
• With the above code, every call to the `act()` method moves the tile to the left

#### Wrapping the Tiles

• Within a short time, the tiles will all move left off the screen
• To keep the illusion going, we need to add tiles to the right of the screen
• We can delete old tiles and make new ones as needed, which is the approach used in WBC
• Another technique is to reuse the tiles

#### Reusing Tiles

• To reuse the tiles, we add an `if`-statement to test when the tiles goes off screen
• When the tile goes off screen, we reposition it off screen to the right
• As the `act()` method executes, the repositioned tile eventually moves on screen
• We can see the complete `act()` method in the following code example

#### Example Tile Code for Horizontal Scrolling

```public void act()
{
if (getX() <= -WIDTH / 2)
{
// Reposition tile to use again at the right edge off-screen
int newX = (ScrollWorld.WIDTH / WIDTH + 1) * WIDTH + WIDTH / 2;
setLocation(newX, getY());
}
setLocation(getX() - SPEED, getY());
}
```

### Exercise 5.1: Scrolling the Background (5m)

In this exercise, we do scroll the background of our scrolling world.

#### Specifications

1. Start Greenfoot and open the scroller scenario from the previous Activities:
2. Open the editor for the ScrollWorld class and add the following code to the beginning of the `prepare()` method:
```int leftX = Tile.WIDTH / 2; // leftmost x coordinate for a tile
int topY = Tile.HEIGHT / 2;    // highest y coordinate for a tile
int tilesVert = HEIGHT / Tile.HEIGHT + 1; // +1 for top/bottom buffer
int tilesHorz = WIDTH / Tile.WIDTH + 2;   // +2 for scrolling buffer
for (int y = 0; y < tilesVert; y++)
{
int tileY = topY + Tile.HEIGHT * y;
for (int x = 0; x < tilesHorz; x++)
{
int tileX = leftX + Tile.WIDTH * x;
}
}
```
3. Compile the scenario and verify there are no errors.

You should see the background of the world fill completely with tiles. Resolve any errors you find, getting help from a guild member or the instructor as needed.

4. Open the source code editor of the Tile class and add the following constant to the class:
```private static final int SPEED = 1; // some values leave gaps
```
5. Also in the Tile class, update the `act()` method as shown below:
```public void act()
{
if (getX() <= -WIDTH / 2)
{
// Reposition tile to use again at the right edge off-screen
int newX = (ScrollWorld.WIDTH / WIDTH + 1) * WIDTH + WIDTH / 2;
setLocation(newX, getY());
}
setLocation(getX() - SPEED, getY());
}```
6. Compile and run your scenario to verify all the changes work well.

You should see the background scroll to the left with the player character stationary. If you have problems, ask a classmate or the instructor for help as needed.

7. Save a copy of your final scenario with all the changes made 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.

## 5.2: Moving the Player

### Learner Outcomes

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

• Add animation to the player character
• Make use of logical operators
• Code `if`-statements with multiple conditions

### 5.2.1: Animating the Player

Scenario file: scroller1.gfar.

• We want to add animation to our player as we discussed in lesson 4.3
• For the example, the instructor will be using these two images:  rocket.png rocket2.png
• The flame of the second rocket is shorter than the flame of the first

• To add the animation we first declare instance variables for the images in the `Player` class
```private GreenfootImage img1, img2;
```
• Remember to ALWAYS declare instance variables as `private`
• Otherwise it becomes hard to change code as projects grow larger
• Second we add a constructor that initializes the image variables
```public Player()
{
img1 = new GreenfootImage("rocket.png");
img2 = new GreenfootImage("rocket2.png");
}
```
• Recall that the constructor is called automatically whenever an object is constructed
• Thus when the `ScrollWorld` constructs a new `Player`, the constructor method is called
```Player player = new Player(); // calls Player constructor
```

#### Coding the Animation

• An animation requires us to alternate images
• To alternate the images we use an `if-else` statement
• The `if-else` statement allows us to choose between two actions
• If a condition is true
• then do this
• Otherwise it is false
• so do something else
• Recall the syntax of the `if-else` statement:
```if (test) {
statements1
} else {
statements2
}
```
• Where:
• test: the test condition to evaluate
• statementsX: the statements to execute depending on the test
• Our example animation alternates two images so we code:
```if (getImage() == img1) {
setImage(img2);
}
else
{
setImage(img1);
}
```
• We package the animation in a method and call the method from `act()`

#### Example Animation Method

```public void updateImage()
{
if (getImage() == img1) {
setImage(img2);
}
else
{
setImage(img1);
}
}
```

#### Check Yourself

1. True or false: an if-else statement allows the programmer to select between two alternatives.
2. What is wrong with the following if-else statement? (answer)
```if (7 == guess) {
msg = "*** Correct! ***";
} else (7 != guess) {
msg = "Sorry, that is not correct.";
}
```
3. If the current image displayed is `image1`, the image displayed after the following code fragment runs is ________.
```if (getImage() == image1)
{
setImage(image2);
}
else
{
setImage(image1);
}
```
4. What is the value of `x` after the following code segment? (answer)
```int x = 5;
if (x > 3) {
x = x - 2;
} else {
x = x + 2;
}
```

### 5.2.2: Logical Operators

• Our player character can move four different directions in the scenario
• right
• left
• forwards
• backwards
• By using multiple `if` statements we can select between multiple alternatives
• However, our movement could go outside the world
• If we are close to the edge, we no longer want to allow movement
• Thus we will need to check for two conditions with each if statement:
• if the correct key is pressed
• if we are far enough away from the edge to move
• To make multiple decisions with each if-statement, we will use logical operators

#### Logical Operators

• Recall that we test is a key is currently being pressed using Greenfoot.isKeyDown()
• Sometimes we want to test if a keyboard key is pressed but only if another condition is true as well
• A logical operator, or Boolean operator, is an operator that connects two Boolean test conditions
• We use logical operators to combine multiple Boolean expressions into one Boolean result
• For example, we want to test if the "up" key is pressed and our `y`-coordinate is greater than 25
• We write this in Java code like:
```if (Greenfoot.isKeyDown("up") && getY() > 25)
```
• The `&&` is how we spell "and" in Java
• Java has several logical operators, but we only need to use three to create any possible test condition
• These three operators are:
• `&&` (and)
• `||` (or)
• `!` (not)
• We discuss all three operators below

#### Truth Tables

• When we discuss logic we often use truth tables
• A truth table is a list of input values and the resulting output
• We can see truth tables below starting with the truth table for logical "and"

#### Truth Table for `&&` (and) Operator

If cond1 is... And cond2 is... Then cond1 && cond2 is... Example Result
`false` `false` `false` `5 > 10 && 5 < 2` `false`
`false` `true` `false` `5 > 10 && 5 > 2` `false`
`true` `false` `false` `5 < 10 && 5 < 2` `false`
`true` `true` `true` `5 < 10 && 5 > 2` `true`
• The `&&` operator returns `true` if both operands are true and returns `false` otherwise
• Activity: construct a truth table for the following test conditions
```if (Greenfoot.isKeyDown("up") && getY() > 25)
```

#### Truth Table for `||` (or) Operator

If cond1 is... || cond2 is... Then cond1 || cond2 is... Example Result
`false` `false` `false` `5 > 10 || 5 < 2` `false`
`false` `true` `true` `5 > 10 || 5 > 2` `true`
`true` `false` `true` `5 < 10 || 5 < 2` `true`
`true` `true` `true` `5 < 10 || 5 > 2` `true`
• The `||` operator is true when either or both operands are true
• Only when both operands are false is the entire `||` statement false
• Activity: construct a truth table for the following test conditions
```if (Greenfoot.isKeyDown("up") || getY() > 25)
```

#### Truth Table for `!` (not) Operator

If cond is... Then `!` cond is... Example Result
`false` `true` `!(5 < 2)` `true`
`true` `false` `!true` `false`
• The `!` operator negates the meaning of a logical expression

#### Another Look at Truth Tables

• Note that most computers store `true` as `1` and `false` as `0`
• If we substitute `1` for `true` and `0` for `false`, we have these truth tables:

• With this substitution we see that the AND operation is the minimum of the operands
• Conversely, the OR operation is the maximum of the operands
• The NOT operator simply reverses its operand

1. Of the following groups ________ is larger.
1. Students wearing denim
2. Students wearing denim AND corrective lenses
2. Of the following groups ________ is larger.
1. Students wearing denim
2. Students wearing denim OR corrective lenses
3. Of the following groups ________ is larger.
1. Students wearing denim
2. Students wearing denim AND NOT corrective lenses
4. Of the following logical expressions, the one that tests to see if `x` is between 1 and 10 (including 1 and 10) is ________ .
1. `(x >= 1 && x <= 10)`
2. `(1 <= x and x <= 10)`
3. `(x >= 1 || x <= 10)`
4. `(1 <= x or x <= 10)`

### 5.2.3: Implementing Player Movement

• Now that we can test two conditions with each `if`-statement we can implement player movement
• Remember we will need to check for two conditions with each `if`-statement:
1. if the correct key is pressed
2. if we are far enough away from the edge to move
• When the "up" key is pressed we also make sure our y-coordinate is greater than half the height of our image
• We write this in Java code like:
```if (Greenfoot.isKeyDown("up") && getY() > 25)
```
• When both these conditions are `true`, we move our player character upwards like:
```setLocation(getX(), getY() - 4);
```

#### Activity: Logical Operators (4m)

Remember that Greenfoot.isKeyDown() checks if a key is currently being pressed and that our `ScrollWorld` has two `public` constants `WIDTH` and `HEIGHT`. Assuming our image is 100 pixels wide by 50 high, what test conditions do we write for the following:

Logical Tests
Keypress Logical Operator Edge Check
`Greenfoot.isKeyDown("up")`
`Greenfoot.isKeyDown("down")`
`Greenfoot.isKeyDown("left")`
`Greenfoot.isKeyDown("right")`

#### Writing the Code

• Once we have the test conditions for our if statements, we can complete the code
• The following example shows how to control player movement
• The code is in its own method: `checkKeyPress()`
• We must call the `checkKeyPress()` method from the `act()` method

### Exercise 5.2: Adding Player Movement 5m)

In this exercise, we do implement movement for our player character.

#### Specifications

1. Start Greenfoot and open the scroller scenario from the last exercise.
2. Open the editor for the player character and add the following `checkKeyPress()` method:
```private void checkKeyPress()
{
}
```
3. Add a call to the `checkKeyPress()` in the `act()` method.
4. Complete the `checkKeyPress()` method, adding appropriate movement for your player character.

5. Compile and run your scenario to verify all the changes work well.

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

6. Optionally, add animation to your `Player` class as discussed in 5.2.1: Animating the Player
7. Save a copy of your scenario with all the changes made 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.

### 5.2.4: Review

• In this section we continued developing our side scroller
• First we animated our player by alternating two images, which we have done before
• Our example animation alternated two images though we could add more images:
```if (getImage() == img1) {
setImage(img2);
}
else
{
setImage(img1);
}
```
• Next we looked at how to code more complex conditions by using logical operators
• A logical operator, or Boolean operator, is an operator that connects two Boolean test conditions
• Java has several logical operators, but we only need to use three to create any possible test condition
• These three operators are:
• `&&` (and)
• `||` (or)
• `!` (not)
• The logical operators AND, OR and NOT are shown in the following table

• We looked at Java code examples with complex conditions to control player movement like:
```if (Greenfoot.isKeyDown("up") && getY() > 25)
```

## 5.3: Non-Player Characters

### Learner Outcomes

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

• Discuss what is meant by an NPC
• Reference the current world
• React to collisions
• Use the World `act()` method to create new objects

Scenario file: scroller2.gfar.

• Our player characters is all alone in the scenario
• To make the scenario more interesting, we add non-player characters (NPCs)
• A non-player character is any character not controlled by a human player
• In a video game, the NPC is usually controlled by the computer
• We will want two types of NPCs in our scenario:
1. One to collect
2. One to avoid
• We will develop these NPCs in the following sections

#### NPCs to Collect

• We often have objects to collect in a game
• For example we may collect score for finding certain items such as we do in WBC
• Other collectibles may include power-ups
• A power-up is a game object that provides some benefit or extra ability

#### NPCs to Avoid

• Many games are filled with NPCs to avoid
• NPCs may cause damage or reduce the player score
• For example, touching the Virus in WBC subtracts 100 from the score and may end the game

#### Check Yourself

1. Of the following, ________ is an NPC.
1. a player character
2. a sprite controlled by the game player
3. a sprite controlled by the computer
4. a background image like a sign
2. True or false: all NPCs should be avoided in a game.

### 5.3.2: Referencing the World

• The World class has many useful methods like
• `addObject()`
• `removeObject()`
• `showText()`
• We often run into situations where an actor wants to call one of these methods
• However, an actor cannot just call these methods because they are world methods and not actor methods
• We can only directly call methods of our own class

#### Calling `getWorld()`

• Fortunately, the `Actor` class has a method to get a reference to the world

getWorld(): returns a reference to the world the actor lives in.

• We can save the world reference in a variable like:
```World w = getWorld(); // called from an actor
```
• We discussed reference variables in lesson 4.3.5: Constructors and Reference Variables
• A reference has access to all the methods of an object
• Thus when we get a reference to the world we can call its methods like:
```w.showText("Game Over", 300, 200);
```
• The last two arguments are the (x, y) coordinates

#### Chaining Method Calls

• The `getWorld()` method returns a reference to the world the actor lives in
• Rather than saving the world reference in a variable, we can access the reference directly like:
```getWorld().showText("Game Over", 300, 200);
```
• This is known as chaining method calls
• We first call `getWorld()` which returns a reference
• Then we call a method of the reference like `showText()`
• Both of these methods calls occur in one statement with dots between them

#### Check Yourself

1. True or false: sometimes an actor needs to call methods of the world class.
2. True or false: `getWorld()` returns the current world that the actor lives in.
3. Calling multiple methods in one statement with dots between them is known as ________

### 5.3.3: Objects to Collect and Avoid

• We now add a collectible object to our scenario
• For our example, we will add an `Astronaut` class
• For the backstory, a space habitat has sprung a leak and we are collecting baby astronauts
• The baby astronauts are temporarily surrounded by an emergency bubble but time is running out!

#### Moving and Turning

• In the `Astronaut` class, we add moving and turning in the `act()` method
```setLocation(getX() - 2, getY());
turn(1);
```
• We use `setLocation()` so the astronaut moves to the left no matter the rotation

#### Disappearing an Astronaut

• We need to remove any astronauts that slip past our player character so we do not overload our scenario
• To make an astronaut disappear we add the following code to the `act()` method:
```if (getX() == 0)
{
getWorld().removeObject(this);
}
```
• When the x-coordinate reaches the left side of the screen, we call the `removeObject()` method of `World`
• As an argument we use the special Java keyword `this`
• The `this` keyword refers to the current object that is executing at this moment
• In essence, the keyword `this` means "this current object"
• Thus by using `this` as an argument, we are telling the astronaut to remove itself from the world

#### Example Code for an `act()` Method

```public void act()
{
setLocation(getX() - 2, getY());
turn(1);

if (getX() == 0)
{
getWorld().removeObject(this);
}
}
```

#### Objects to Avoid

• In addition to a collectible object, we add an object to avoid
• For our example, we will add an `Asteroid` class using the image:

• We add similar code to move, turn and disappear the asteroid as we did the astronaut
• The difference is in what we do when we collide with the object

#### Check Yourself

1. for an actor to move in one direction no matter the orientation, call the method ________.
2. To make an object disappear, we call the `World` method ________.
3. In the following code, `this` as an argument means ________.
```getWorld().removeObject(this);
```

### 5.3.4: Reacting to Collisions

• Let us look at how to react when we collide with an object
• The player character will do the reacting, so we add the code in the `Player` class
• We call the method `checkCollision()` and call it from the `act()` method
• Inside the `checkCollision()` method we use the commonly used collision methods shown below
• When we collide with as astronaut, we rescue them and play a happy sound

hooray.wav

• When we collide with an asteroid it is disastrous and we play a crash sound

crash.wav

#### 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.

#### Example Method `checkCollision()`

```private void checkCollision()
{
if (isTouching(Astronaut.class))
{
removeTouching(Astronaut.class);
Greenfoot.playSound("hooray.wav");
}
if (isTouching(Asteroid.class))
{
Greenfoot.playSound("crash.wav");
Greenfoot.stop();
}
}
```

#### Check Yourself

1. True or false: collision detection is generally performed in the class that responds to the collisions.
2. The methods `isTouching()` and `removeTouching()` are defined in the class ________.
3. True or false: the purpose of method `isTouching()` is to detect if our actor has touched another actor.

### 5.3.5: Creating New Objects Automatically

• A world subclass may have an `act()` method just like an actor
• One use of an `act()` method in the world is to add new objects to our scenario
• An example `act()` method for the world class is shown below

#### Example `act()` Method for `ScrollWorld`

```/**
* Create new floating objects at random intervals.
*/
public void act()
{
if (Greenfoot.getRandomNumber(100) < 3)
{
int x = WIDTH - 1;
int y = Greenfoot.getRandomNumber(HEIGHT - 50) + 25;
}
if (Greenfoot.getRandomNumber(100) < 1)
{
int x = WIDTH - 1;
int y = Greenfoot.getRandomNumber(HEIGHT - 50) + 25;
}
}
```

#### Assigning the Coordinates

• The right-hand side of the screen is always at the `WIDTH - 1`
• The reason for the -1 is that we count pixels starting at 0 instead of 1
• The y-coordinate is a random number like we discussed in lesson 3
• However, with an unbounded world we must use care when launching an actor off-screen

#### Check Yourself

1. True or false: the world may have an `act()` method just like an actor can.
2. To appear at the right side of the screen with a world size of 600 x 400 pixels, we set the y-coordinate to ________.
3. True or false: with an unbounded world we must be careful to not launch objects off screen.

### Exercise 5.3: Adding NPCs (5m)

In this exercise, we do add NPCs to our scrolling world scenario.

#### Specifications

1. Start Greenfoot and open the scroller scenario from the last exercise.
2. Add two new classes to the scroller scenario, one to collect and one to avoid.

3. Add code like the following to both of the new classes, such that the actors move from one side of the screen to the other.
```public void act()
{
setLocation(getX() - 2, getY());
turn(1);

if (getX() == 0)
{
getWorld().removeObject(this);
}
}
```
4. In the player character class, add a `checkCollision()` method like the following example. Call the method from the `act()` method of your player character.
```private void checkCollision()
{
if (isTouching(Astronaut.class))
{
removeTouching(Astronaut.class);
Greenfoot.playSound("hooray.wav");
}
if (isTouching(Asteroid.class))
{
Greenfoot.playSound("crash.wav");
Greenfoot.stop();
}
}
```
5. Add an `act()` method to the `ScrollWorld` class like the following such that both new objects are added to the world at random intervals.
```public void act()
{
if (Greenfoot.getRandomNumber(100) < 3)
{
int x = WIDTH - 1;
int y = Greenfoot.getRandomNumber(HEIGHT - 50) + 25;
}
if (Greenfoot.getRandomNumber(100) < 1)
{
int x = WIDTH - 1;
int y = Greenfoot.getRandomNumber(HEIGHT - 50) + 25;
}
}
```
6. Compile and run your scenario to verify all the changes work well.

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

7. Save a copy of your completed lesson scenario to upload to Canvas as part of Lab 5. Also, we will add to the scenario next week so bring it to class.

## 5.4: Midterm Preparation

### Learner Outcomes

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

• Describe the ground rules for the midterm exam
• Start preparing for the midterm exam

#### Important Midterm Exam Information

Date: 3/2/17
Location: Regular classroom
Start time: During the regular class time

• The exam covers material from the first four lessons
• Exam question types include multiple choice and short programming problems
• You will have about 45 minutes to complete the exam

#### Ground Rules

• You must attend the exam or you will receive a score of zero (0)
• Except by prior arrangement with the instructor
• I am using Canvas to administer the test
• The exam is closed books and closed notes
• However, you may have one 3" x 5" card of handwritten notes for the exam
• You may use a computer from the classroom, but only to take the exam in Canvas
• You may have blank scratch paper
• You may NOT use the computer to compile or run programs
• You may NOT use the computer to view documents on the Internet
• You may NOT use a cell phone, calculator or other electronic device
• Thus, you may NOT use your own computer to take the exam
• If you have a cell phone visible or in use during the exam, you will automatically fail
• You may NOT communicate with anyone but the instructor during the exam

#### 3"x5" Card Requirements

• Maximum card or paper size is 3 inches by 5 inches
• You may use both sides of the card
• Notes must be handwritten and NOT photocopied
• No more than three statements in a sequence on the card — only snippets
• Any 3" x 5" cards violating these rules will be confiscated before the test
• You must turn in your 3" x 5" card after the exam in any case

### 5.4.2: Test Preparation Self Assessment

#### Discussions Questions

• How are these practices beneficial?
• What are your successful strategies for exam preparation?
• How much time do you dedicate to test preparation?

### 5.4.3: How to Study for the Exam

• No one can ace a test without studying and understanding the material
• To get an "A" you need to thoroughly prepare for the test well in advance
• With the midterm approaching, you have a choice:
• Study and do well, or
• Not study and do less than your best
• Victims are people who let their lives control them, like a pawn on a chessboard
• Creators are people who controls their own life, like a person playing chess
• You can take responsibility for studying and do well on a test
• Or you can make excuses and do less than you are capable of on a test

Here are some steps you can take to improve your test results:

1. Compile a list of topics you might be tested on.

Look over your quests, labs, and lecture notes to determine what we covered. Write a list of topics from these sources.

2. Make sure you understand all the topics on your list.

Correct any mistakes you may have made in your quests, labs or boss events.

3. Identify the most probable exam topics for thorough study.

To do well, you need deep understanding of the test topics. Gaining a deep understanding takes time. Often you can tell what is on a test simply by which topics the instructor spends the most time talking about.

4. Create a list of possible test questions.

Turn headings from the textbook and lecture notes into questions. Look at the section summaries in the lectures and read the Check Yourself questions.

5. Study your questions over and over until you know them perfectly.

Make flash cards (or use an app) with questions on one side and answers on the other. Carry the cards with you and review them when you have a few minutes available. Have other people ask you questions from your flash cards. Do practice problems to gain a an even deeper understanding of coding techniques.

6. Prepare your 3"x5" card of test notes.

Since the instructor allows a 3"x5" card, make use of it. For the topics you had the most trouble with, write down a short note or summary. If the pressure of the test causes you to forget something, you can refer to your card.

### Exercise 5.4: Preparing Exam Questions (3m)

Take three minutes to review and choose one of the following topics for Lab 5. Post the questions in the Discussions area of Canvas titled "Midterm 1 Study Questions" for XP.

There cannot be more than two posts per topic and all the questions for a post must be unique. Thus if two people select the same topic, the second person who posts on the topic must have different questions than the first person.

#### Exam Topics

1. Objects, instances and class diagrams (1.3.4, 2.1.3)
2. Calling methods and returning values (1.3.5, 3.4.3)
3. Calling methods with parameters (1.3.6, 3.4.4)
4. Creating `World` and `Actor` subclasses (2.1.3, 2.1.4, 2.1.5)
5. Actor movement, rotation and API methods (2.2.5, 2.2.6, 2.4.2)
6. Coding `if`-statements (2.3.2, 3.2.3, 4.3.6, 4.3.7, 4.4.2)
7. Errors and debugging (2.3.3, 2.3.4)
8. Variable declaration, assignment and order (2.4.1, 3.1)
9. Defining new methods (2.4.2, 2.4.3, 3.4)
10. Random numbers and applications (3.2.1, 3.2.2, 3.2.4, 3.2.5)
11. Relational operators (3.2.3, 3.2.5)
12. Simple actor interaction (3.3)
13. Strings (3.5.1, 3.5.2)
14. Responding to keyboard input (3.5.2)
15. Playing sounds and stopping (3.5.3, 3.5.4)
16. Coding constructors (4.2.1, 4.3.5)
17. Creating and adding objects to the world (4.2.3, 4.2.2)
18. Coding `for`-loops (4.2.4)
19. Animation (4.3)
20. Instance variables versus local variables (4.3.4)
21. Reference variables (4.3.5)
22. Counting, numbers and arithmetic (4.4)

### 5.4.4: More Test Preparation

• To help you study, you can use this review game: Greenfoot Jeopardy
• Start the game with the "basics.txt" file

#### Practice Exam

• To help your understanding of how the midterm will operate, I am providing a practice exam in Canvas
• The questions are intended to help you get a "feel" for taking an exam in Canvas
• The questions are NOT intended to tell you everything that is on the exam
• Suggestion: prepare first and then try the practice exam
• This will give you a better understanding of how much more preparation you need

#### Exam Taking Tips

• If you get stuck on a question, make your best guess and return later
• If you are equally uncertain between two choices, go with your first impression
• When writing code, do NOT add more than the problem asks for
• You do not need to comment code for tests and exams
• Unless specifically instructed to in the exam question
• Use the full time available
• Check your work if you finish early
• Any questions?

## Wrap Up

Due Next:
Q4: Finishing Touches (2/23/17)
Lab 5: Test Questions (2/28/17)
Q5: Basic Arcane Studies (3/2/17)