# 5: Side Scrollers

## Illuminations

#### Questions from last class or the Reading?

• Reminder: Midterm 1 next week

#### Homework Questions?

• B4: Challenge (Canvas) (2/26/19)
Lab 4: White Blood Cell (2/26/19)
Q4: Finishing Touches (2/28/19)
• 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

#### Character Location #### 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

#### Adding a Player Character

• 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

#### Exercise: 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, outside a constructor, 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 constants `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;
```

#### Exercise: Adding Constants (4m)

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
addObject(new Tile(), leftX, topY);
```
• 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
• Recall from lesson 4.2.4 that 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
• Reviewing 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
• The four parts above are:
1. Initialization (first value) of the counting variable
2. Test condition: if true enter the loop body; otherwise exit the loop
3. Loop body contining statements to repeat
4. Update statement at the end of the loop body
• As an example, we 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;
addObject(new Tile(), tileX, tileY);
}
```
• 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;
addObject(new Tile(), tileX, tileY);
}
```

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 UpDown = 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 UpDown = HEIGHT / Tile.HEIGHT + 1; // +1 for top/bottom buffer
int tilesHorz = WIDTH / Tile.WIDTH + 2;   // +2 for scrolling buffer
for (int y = 0; y < UpDown; y++)
{
int tileY = topY + Tile.HEIGHT * y;
for (int x = 0; x < tilesHorz; x++)
{
// int tileY = topY;
int tileX = leftX + Tile.WIDTH * x;
addObject(new Tile(), tileX, tileY);
}
}
```

#### 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 < tilesAcross; x++)
{
int tileX = leftX + Tile.WIDTH * x;
addObject(new Tile(), tileX, tileY);
}```
• The outer loop moves the y-coordinate from one row to the next
```for (int y = 0; y < UpDown; 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

#### Method `placeRow()` with Inner Loop

```public void placeRow()
{
for (int x = 0; x < tilesAcross; x++)
{
int tileX = leftX + Tile.WIDTH * x;
addObject(new Tile(), tileX, tileY);
}
}
```

#### 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 UpDown = HEIGHT / Tile.HEIGHT + 1; // +1 for top/bottom buffer
int tilesAcross = WIDTH / Tile.WIDTH + 2;   // +2 for scrolling buffer
for (int y = 0; y < UpDown; y++)
{
int tileY = topY + Tile.HEIGHT * y;
for (int x = 0; x < tilesAcross; x++)
{
int tileX = leftX + Tile.WIDTH * x;
addObject(new Tile(), tileX, tileY);
}
}
```
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

#### Adding the Animation Images

• 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

#### Check Your Understanding

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()
{
// add other code here
}
```
3. Add a call to the `checkKeyPress()` in the `act()` method.
4. Complete the `checkKeyPress()` method, adding appropriate movement for your player character.

For more information see lesson 5.2.3: Implementing Player Movement.

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

### 5.4.1: About the Boss Exam

#### Important Boss (Midterm Exam) Information

Date: 03/07/19
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

• Put your name on your card
• 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: Boss Exam Topics

Here is a list of exam topics:

1. Objects, instances and class diagrams (1.3.4, 2.1.3)
2. Calling methods and returning values (1.3.6, 3.4.3)
3. Calling methods with parameters (1.3.7, 3.4.4)
4. Creating `World` and `Actor` subclasses (2.1.3, 2.1.4, 2.1.5, 2.2.3)
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)

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

Take three minutes to review and choose one of the above topics for Lab 5: Test Questions. Post the questions in the Discussions area of Canvas titled "Lab 5: Basic Arcane 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.

### 5.4.3: Boss Preparation Resources

Here is a list of resources available to help you in preparing for the exam.

1. Lecture notes
• Notes: text explaining the concepts
• Check Yourself questions: questions and answers at end of most sections
• Lesson note summaries: summary after major sections
• Site Search: type in keywords to help find topics
• In-class exercises: practice problems during class
• Your notes: written down during or after class
2. Textbook
• Text: use the index to find topics or search in e-text versions
• Margin notes: key concepts of texts
• Exercises: step-by-step how to solve some problems
• Chapter summaries: review section at the end of each chapter
3. Quest and labs
• Programming projects
• CodeLab
4. Practice exam questions
5. Instructor: ask me questions
• Office hours
• Email
6. Tutoring: see tutors to ask questions
7. 3x5 Reference card

#### Practice Exam

• The practice exam is for you to practice with on your own and will not be graded
• The questions are intended to help you get a "feel" for taking an exam in Canvas
• The questions are NOT intended to tell you what 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
• Things to Know Before Taking a Quiz/Exam in Canvas

#### 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? ### 5.4.4: Pre-Boss Planning

• No one can ace the test without understanding the material and the key to understanding is to study
• To get the best grade 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
• Your choice helps determine if you are a victim or a creator
• Victims are people who let their lives control them, like a pawn on a chessboard
• Creators are people who control 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 well

#### Making the Plan (15m worth 4 XP)

1. Open the survey in this link
2. Download the document by following the menu File > Download as > Plain Text (.txt), and save the file as `examplan.txt`
3. Fill out the survey without deleting any of the existing text.
4. Show your plan to the instructor and discuss as needed.
5. Submit the `examplan.txt` file as part of Q5: Basic Arcane Studies.

#### Discussions Questions

• What are some of the best study techniques that work for you?
• How much time do you dedicate to test preparation?
• Do you like to work with others or study on your own?

## Wrap Up

Due Next:
Q4: Finishing Touches (2/28/19)
Lab 5: Boss Basic Questions (3/5/19)
Q5: Basic Arcane Studies (3/7/19)
• When class is over, please shut down your computer
• You may complete unfinished lesson exercises at any time before the due date.
Last Updated: March 01 2019 @22:13:27