You are on page 1of 52

Session 1 Welcome to Greenfoot & Code Breaker

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
About Code Breaker
The Code Breaker competition is being held to celebrate the 100th birthday of Alan Turing a famous
British mathematician and computer scientist. To help others learn about him you are going to make
a small presentation about his life and work. Split into 4 groups and each group is to prepare a single
slide on one of the following aspects of his life and work. Remember what is on the slide should only
be a summary and you should have more information available to answer questions!

1. His early life and interests (where was he born, go to school, etc).
2. His work with codes and cyphers.
3. The Turing Test for artificial intelligence.
4. The Turing Machine

Once you have finished your slides make sure you put them together so that they can be presented
at the end of the session.

Starting with Greenfoot


As this is probably one of the first times you have used Greenfoot we are going to spend a little time
looking at how to use the program before we do much coding. To help you get started you have
been provided with a program (called a scenario in Greenfoot) to begin with. To start open
Greenfoot go to the Scenario menu, choose Open and find the ShipGame scenario. Once you have
done that you screen should look like this picture.

This class represents your world is


responsible for adding and removing
Actors. The main area of the screen shows
you what is happening in the world.

You will have to make an


Actor class for each type of
object (e.g. ship) that you
want to have in your world.
IMPORTANT: Press compile to
Use these buttons to run check your code and get it ready
your code once its compiled. to run. Your program will NOT
run unless you compile it first!

Adding Actors
At the moment if you press the Run button nothing happens because we havent added anything to
the world so lets get started on that.
1. To create a new Actor right-click on the Actor class and pick the New Subclass option.

2. Call your new class Ship and choose the ship image provided (as show above).
3. Press the OK button and you have created your actor.

4. You should notice that your new class appears at the right hand side of the screen but it
looks shaded out. This means that it needs to be compiled so press the compile button at
the bottom of the screen.
5. Right click on the Ship class again and choose the new Ship() option. This will let you up an
instance of your Ship class into the World as shown.
So far so good although if you press run you will probably notice that there is still nothing
happening. This is because you havent told it to do anything yet! However before we do that lets
make another class, called Crate, to represent the crates the ship has to collect. Follow the same
steps as before and you should end up with a scenario similar to the one shown below.

Controlling Actors
It is now time to consider what we want our actors to do. Our ultimate aim is to get the ship to
move in response to the arrow keys but for now lets just get the ship to move in a straight line.

1. Double click on the Ship class on the right side of the screen to open the code editor as
shown in the screenshot below.
This is where your class
These are comments
is named and you
that describe what your
declare it as a subclass
program does. They are
of Actor.
not compiled.

This is where you put


the code that controls
the behaviour of your
actor

2. The act method is what tells your actor how to behave. For now all the code you write for
the actor must go between the { and } brackets. If you put code outside these brackets it will
not compile properly. As an experiment change your code to the following and try running it
(remember you will need to compile it and add a new ship to the world before running it).

public void act()


{
// Add your action code here.
move(10);
}

NOTICE THE SEMICOLON AT THE END OF THE LINE YOU MUST INCLUDE IT

Your ship should now move in a straight line. The move method simply moves your ship 10
cells in a straight line. Change the 10 to a larger number to speed up the ship or a lower one
to slow it down. A value passed to a method like this is called a parameter as it tells the
method something about what you want it to do.

3. Lets try getting the ship to move in a circle next. To do this we only need to tell the ship to
turn and, convienently, there is a method called turn to do just that. Like the move method
it also needs a parameter although in this case it is the number of degrees that you want to
turn the actor. Try the following code.

public void act()


{
// Add your action code here.
move (10);
turn (10);
}
As before try changing the parameters to these methods to get the ship to move in different
ways!

Reading from the Keyboard


We now have the ship moving in nicely but we have no control one the program has started. What
we need to do is check when the arrow keys on the keyboard are pressed and then move the ship in
the correct way. While you can come up with many different ways for the ship to behave well start
with the one show in the table below.

Key Behaviour
Up Move 5 steps forward
Down Move 5 steps backwards
Left Turn 5 degrees to the left
Right Turn 5 degrees to the right

So the question is how do we know if one of the arrow keys is being pressed. Well fortunately
Greenfoot provides a method for you to check that. It is called isKeyDown and it takes one
parameter the name of the key you are checking. So to check if the up key is pressed you would
need to write the code below.

Greenfoot.isKeyDown(up);

You might be wondering why we need to write Greenfoot. in front of the method name. This is
because unlike the other methods we have used this one belongs to a different class so we need to
tell the computer where it can find the method.

On its own this code is still fairly useless because although it will check if the key is pressed it doesnt
do anything if it is. To do that we must use something called an if statement. An if statement will
check a condition, such as if the key is pressed, and if it is do something about it. So lets look at
what the code to check the up arrow should look like.

if ( something to check ) if ( Greenfoot.isKeyDown(up) )


{ {
do something move (10);
} }

As you can see the code for an if statement is fairly straight forward. It simply checks the condition
you put in the () brackets and if necessary does all the instructions you have put between the {}
brackets. Note you dont put a semicolon at the end of an if statement.

The final piece of the problem is to figure out how to move the ship backwards and right. The
answer is surprisingly simple - use negative numbers. If move(10); moves you 10 cells forward then
move(-10); will move you 10 cells back. It is very similar with the turn method.

From here you should be able to figure out how to get the ship moving by yourself. You will need
one if statement for each key you want to check and all the code will go into the act method dont
forget to remove the code you already have there. A solution is shown below but try it yourself
first!!

Once you have the code working be sure to adjust the parameters to the methods to make the ship
move in the way you want! If you want to see something really odd then add more ships to the
world and try it out. It looks like synchronised swimming to me! Do you know what is happening?

public void act()


{
// Add your action code here.
if (Greenfoot.isKeyDown("up"))
{
move (5);
}

if (Greenfoot.isKeyDown("down"))
{
move (-5);
}

if (Greenfoot.isKeyDown("left"))
{
turn(5);
}

if (Greenfoot.isKeyDown("right"))
{
turn(-5);
}
}

Finished before everyone else? Why not add a quick turn button? You know the feeling there you
are in a game you see the enemy coming and you cant quite turn around fast enough to get out of
the way! Well this is your game so why not add an extra piece of code to Ships act method that will
turn the ship 180 degrees when you press a key allowing you to make a quick escape!

Finishing Up
Show the presentation your group created at the start of the session. Remember the slide is only a
summary and you should be prepared for some questions.
Session 2 Collision Detection in Ship World

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Colossus Super Computer
During World War 2 both sides spent a lot of time trying to listen in on each other communications.
This was made more difficult because both sides used codes to make it difficult for anyone else to
read their messages. It was the job of the people who worked in Bletchley Park to break the German
codes and they developed some of the worlds earliest computers to help them do this. Of particular
importance was a series of computers called Colossus.

In pairs you are to find out as much information about the Colossus as you can. You will find a video
about Colossus on the Bletchley Park website. It is amazing to think how far computers have come!

Ship Game Part 2


In the last session we created two actors (Ship and Crate) and we got the ship moving in response to
the keyboard. The next step is to make it so a ship can pick up crates and to do this we will need to
check if the ship is touching a crate.

Collision Detection
Fortunately Greenfoot provides a number of methods that an actor can use to check this. The one
we are going to use is called getOneIntersectingObject and it takes a single parameter which tells it
what type of actor you want it to check for. In our case we are looking for Crate actors so we would
write.

getOneIntersectingObject (Crate.class);

If this method finds that there is a crate intersecting (touching) the ship it tells us which one it is so
we need to store that answer somewhere. To do this we make a variable - which is just a small piece
of memory in the computer we give a name to. The code below tells the computers to set aside
enough memory to hold an Actor and to call that piece of memory crate. It then takes the answer
from the getOneIntersectionObject method and stores it in that piece of memory.

Actor crate = getOneIntersectingObject (Crate.class);

Now that we can store the answer in the computers memory the next thing we need to do is check
if the answer is empty. In Java if nothing is found the variable has a special value stored in it which is
called null. So using an if statement we must check that the answer we got is not null (in an if
statement != means is not equal to).

Actor crate = getOneIntersectingObject (Crate.class);


if (crate != null)
{
// we have hit a crate what do we do?
}

The final step is to decide what we want to do to the crate when we hit it. The easiest thing to do is
to just remove the crate from the world so that it is no longer on the screen. The world class has a
method called removeObject to do this. However to call that method we must first have access to
the world our game is running in and to do this we call the getWorld method. The final code is as
follows so add it to the bottom of the act method for the ship (underneath where you check for key
presses). Add some crates to the world and check that the ship can collect them.

Actor crate = getOneIntersectingObject (Crate.class);


if (crate != null)
{
// we have hit a crate so we get access to the
// world using the getWorld() method and then
// use the removeObject method to remove the
// crate from the game.
World shipWorld = getWorld();
shipWorld.removeObject(crate);
}

For a bit of extra flair it would be nice to make a sound every time you collect a crate. A sound file
called cash-register.mp3 has been provided for this. To use it put the following line of code
immediately after where you remove the crate from the world (it should still be in the brackets of
the if statement). Once you have done this test it again to make sure it works.

Greenfoot.playSound(cash-register.mp3);

Adding Enemies
A game like this wouldnt be any fun if you werent avoiding enemies so lets make some.

1. Create a new class called Submarine using the image provided. Do this in the same way that
you have created the Ship and Crate class previously.
2. Open up the code for the new Submarine class and get it running in circles like we did
previously for the Ship. An example of the instructions you could use in the act method are
shown below.

move (5);
turn (5);
3. If our ship is hit by one of the submarines we need the ship (not the submarine) to explode.
While we could put the code for this into either the Submarine or the Ship class I
recommend that we put it in the Ship class for now to keep all our collision detection code
together. The code is the exact same as before except for the two changes noted below.

You need to change


Actor sub = getOneIntersectingObject (Submarine.class);
this to the type of
if (sub != null) actor you are
{ looking for now.
// we have hit a sub so we get access to the
// world using the getWorld() method and then
// use the removeObject method to remove This time we are not
removing the thing we
// the ship from the game.
hit from the game but
World shipWorld = getWorld();
we are removing this
shipWorld.removeObject(this);
ship.
}

4. To finish off this piece of code another sound file has been provided called kaboom.wav. You
must add the line of code necessary to play the sound every time the ship hits a submarine.
5. Test the games and make sure your code works.

Bonus Code: If you want everything to stop once your ship has exploded then use the
Greenfoot.stop() method to do so.

Automatically Resetting the Game


While we still need to make the submarines move more realistically the last thing for today is to set
the game up automatically rather than having to put the pieces on every time we reset. As this code
will be setting up the world for the start of the game it needs to go in the ShipGameWorld class.

1. Open the ShipGameWorld class by double clicking on it.

You will see a method with the same name as the class. This is called a constructor and it is called to
setup the ShipGameWorld every time a new world is created. This is where we are going to put our
code underneath the line that starts with the word super.
2. To add an actor to the world we call the addObject method. You need to provide 3
parameters for the method to work. The first is the new actor you want to add, the second is
the how far across the screen you want to put it (x coordinate) and the third how far down
the screen (y coordinate). You can see from the constructor that the world is 600 by 400
cells this means that the x coordinate can be between 0 and 600 and the y coordinate can be
between 0 and 400. So for example if we wanted the ship to start at the centre of the world
we could write the following code.

addObject (new Ship(), 300, 200);

3. In the same way we can add submarines and crates wherever we want. An example of
adding both is given below but you will want to add more. Once you are done test the game
again and see what happens.

addObject (new Submarine(), 100, 50);


addObject(new Crate(), 400, 350);

Finished before everyone else again? Well why not make your game that little bit harder! One way
you could get the submarines to grab the crates if they get to them first. All you need to do is to add
some collision detection code to the Submarine class to find when it hits a crate. You should know
how to do that by now because you have already done it in the Ship class! If you want you could
even get a new sound to play when they happens. You can use mp3 or wav files and you will have to
save it in the sound folder of your scenario to use it.

Comparing Values
When you use an if statement in Java it looks at a condition and decides whether or not it is true. For
example if you wrote the following the condition would be true because the numbers arent equal.

if (5 != 8)
{
// Your code here
}

When programming it is important to know how you can check values against each other. The most
commonly used operators are shown below. It is your job to write a description of what each of
them mean I have included the one we used earlier in this session to help you get started.

Operator Example Description


== value1 == value2
!= value1 != value2 True is value1 and value2 are different.
< value1 < value2
> value1 > value2
>= value1 >= value2
<= value1 <= value2
Session 3 Finishing the Ship Game

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Comparing Values
Lets see what you can remember about comparing values from the last session. For each of the
following statement you must figure out whether the statement is true or false. For the purposes of
this exercise x = 6 and y = 10. Remember * means multiply and / means divide. Now lets get going

Statement True or False?


x == y
x != y
(x+4) != y
y<x
(x*2) > y
(y 4) <= x
x<y
(x+7) >= (y+3)
When you are finished compare your answers with a friend and make sure you agree before you
present your answers to the rest of the class!

Ship Game Part 3


So far our submarines only turn in a circle which really isnt very exciting. It would be much better if
they went in a straight line until they hit the edge and then they turned around. So that is the first
thing we care going to try and get working today.

Making the Submarines Move Randomly


To get the submarines to turn we need to be able to tell when they reach the edge of the screen and
we can only do this by looking at their X and Y coordinates. Remember we have already seen that
our world is defined as being 600 cells wide by 400 cells high.

At this corner X is at its


At this corner both X and Y biggest (599 in our world
are equal to zero (0,0) because it starts at 0) (599,0)

X increases as you go to the right.


Y increases as you go down

At this corner Y is at its At this corner both X and Y


biggest (399 in our world are at their biggest (599,
because it starts at 0) (0,399) 399).
So what we want to do is tell the computer to turn the ship 180 degrees if the X coordinate is 0
(which means it is on the left hand side) or 599 (which means it is on the right hand side). To do this
we must use an if statement and the code should look like this.

Gets the current X


public void act ()
coordinate of the actor
{
this must be called AFTER
move (5); you move the submarine.
Declares a variable to hold a
whole number (called an
integer in maths which is
int xCoord = getX();
shortened to int).
if (xCoord <= 0 || xCoord >= 599) Checks if the submarine has
{ gone off the edge this is
turn (180); explained more below.
}
}

There are a few new things in this code. First we are making a variable (a piece of memory) called
xCoord and we are saying it is going to hold an integer (a whole number). It is very common to make
integer variable so to save time they shortened it to int. The other thing I need to explain is the
condition on the if statement it is as follows:

xCoord <= 0 || xCoord >= 599

XCoord is less than or OR xCoord is greater than or


equal to 0 equal to 599

Hopefully you will already be familiar with the < (less than) and > (greater than signs) but the really
new thing is using || to say OR and this is really handy when you want to check a number of things
at once. You can also use && to say AND although we dont need to do that here because the
submarine cant be at both sides at the same time!

Put this code into the Submarine class and test it. If it works then your ships will be bouncing back
and forth across the world. While this is an improvement it isnt good enough because they are too
easy to dodge. What we need is for the ships to turn unpredictably when they hit the edge. To do
that we need to use random numbers and, again, Greenfoot makes this super easy for us by
providing a method called Greenfoot.getRandomNumber. So for example to get a random number
between 0 and 9 we would write Greenfoot.getRandomNumber(10);

So how do we use this to turn our submarines? Well instead of always turning the submarines 180
degrees why dont we turn them 160 degrees plus a random number between 0 and 40? This will
mean that every time a ship hits the edge it will turn a random number of degrees between 160 and
200 degrees. To do this change the code where it says turn(180); to the following.

int random = Greenfoot.getRandomNumber (41);


turn (160 + random);
Once you have changed the code test it and see what happens. Dont know if you have noticed but
there is still one problem what happens when your ships reach the top or bottom of the screen or,
more accurately, what doesnt happen? The ships dont turn around!

This isnt surprising really because we never checked the Y coordinates anywhere. The code to do
this will be almost the exact same as that we have just created to check the X coordinates. So, on
your own this time, create the code to check if the Y coordinate is less than 0 or greater than 399
and turn the ship if it is. This code should go in the submarine act method just below the code that
checks the X coordinate.

Once you have done that you should have a fully working game so check it out! You might find the
game is too easy or too hard. If that is the case then change the parameters of the game. Things you
could try changing are the speed of your ship/the submarines or changing the number of the
submarines that you start with.

Run Out of Crates?


After playing the game for a while I quickly ran out of crates to collect. It would be better to move
crates to somewhere else instead of removing them from the game completely. To do this we must
look at the code in the Ship class that removes the crates and change it. Currently the code should
look like what is shown below and we need to remove the line where we use the removeObject
method.

Actor crate = getOneIntersectingObject (Crate.class);


if (crate != null)
{
World shipWorld = getWorld();
shipWorld.removeObject(crate);
Greenfoot.playSound (cash-register.mp3);
}

Instead of removing the crate we are going to use its setLocation method to give it a new position in
the game. Fortunately we have just learnt how to get random number so we can use this technique
to make sure that the crate appears somewhere different each time it is created. To do this we use
the getRandomNumber method to generate a random x and y coordinate. The final code should look
like this.

Actor crate = getOneIntersectingObject (Crate.class);


if (crate != null)
{
int xCoord = Greenfoot.getRandomNumber(600);
int yCoord = Greenfoot.getRandomNumber(400);
crate.setLocation(xCoord, yCoord);
Greenfoot.playSound (cash-register.mp3);
}

Random Startup
At the moment your ship, submarines and crates always start in the same places (the ones you set in
the ShipGameWorld constructor). However now that you know how to use random numbers you
should be able to go back and change the constructor so that the ships start at different places each
time you start the game. Try it on your own and see how you get on!

Still looking for a challenge? Well this is a hard one so be warned! One thing you could add to make
the game more interesting is to have the submarines change direction when they hit each other. To
do this you will have to add some collision detection code to find when the submarines hit each
other and then turn the submarines around. Good luck!

Variable Types
Java lets you store a variety of different types of information. Below is a table of the most common
types that you might find yourself using. Use the internet or any resources you have try and find out
what type of information you can store in each one. I have already filled in the row for the int data
type but you wont need to be that detailed for all of them!

Type Description
byte
short
int A whole number (no decimal places) that can be either positive or negative. It uses
4 bytes of memory and can have a value from -2,147,483,648 to 2,147,483,647.
long
float
double
boolean
char
String

Once you have collected this information discuss why you think there are so many different ways of
storing numbers. The float and double data types need to be treated carefully because they do not
store precise values what do you think this means and why could it be a problem?
Session 4 Starting the Air Raid Game

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Naming Conventions
When writing code it is important to make it easy to understand and maintain. On most software
projects there will be more than one person writing code so having a consistent way to name class,
methods and variables makes it easier for them to work together. The Java Naming Conventions
provide guidelines on how different names should be formatted and it is your task to find out what
the rules are and provide an example for each of the following types of name. You can easily find
this information on the web but in case you get stuck try the link provided. I have filled out the first
of these as an example.

Name Type Rule Example


Class or Interface Should be in CamelCase. This is where AirRaidWorld
the first letter of each new word is a
capital and all spaces are removed.
Method
Variable
Constants
Name Conventions: http://www.oracle.com/technetwork/java/codeconventions-135099.html#367

Air Raid Game


Today we are going to start a new game. In this game airplanes will fly across the top of the screen
dropping supplies to enemy troops. You are in charge of a rocket launcher and it is your
responsibility to destroy the crates before they hit the ground. To get started open the Air Raid
scenario that you have been provided with. As you can see we already have two classes created for
us. You should already be familiar with the purpose of the AirRaidWorld class from what we did
before and we will use the StatusBoard class to display the players score but that is a little while off
yet so we can ignore it for now.

The two classes that have


been created for us.

The first step is to create classes for each type of object that we are going to have in the game. We
will need at least the 4 classes listed below. It is important to realise that we only need a class for
each TYPE of object. This means that we only need to have one class for rockets even though we will
be firing an awful lot of them.

Object Description
Plane Represents the plan that flies across the top of the screen
dropping the crates.
Launcher Represents the rocket launcher that you control and the
bottom of the screen.
Rocket Represents the rockets you launch to try and shoot the
crates and/or planes.
Crate Represents the crates that are dropped by the plane.

So to get us started right click on the Actor class (on the right hand side) pick the New Subclass
option and create a new subclass for each of these objects. You should notice that images have
already been provided for each of them. Once you are finished your scenario should look something
like that shown below although it wont do anything yet!

Moving the Launcher


The first job is to get the rocket launcher moving in response to the keys. This should be easier than
the ship game because in this game we only want the launcher to move left and right along the
bottom of the screen. To do this we must add the code to the act method of the Launcher class (to
open the code double click on the class).

1. Write an if statement to check if the right arrow on the keyboard is being pressed exactly
like the example below.
if ( Greenfoot.isKeyDown(right) )
{
// Add your code to do something
// if the right arrow is pressed here.
}

2. If the right arrow is being pressed we want to move the launcher 5 cells note that unless
you turn an actor first the move method will move the actor towards the right of the screen.
3. Write an if statement to check if the left arrow on the keyboard is being pressed.
4. If the left arrow is being pressed we want to move the launcher 5 cells backwards
(remember this should be a negative number).
5. Test that the code works and that you can move the launcher.

Moving the Rocket


Now we have got the launcher working we need to make sure that the Rocket class works. When we
launch a rocket we want it to go straight up until it hits the top of the screen. Getting the rocket to
move in a straight line should be simple for you by now. In the Rocket class act method write a
single line of code telling it to move e.g. move(10);.

When you test this code you will notice the problem. The rocket goes straight to the right edge of
the screen rather than to the top. We should have known this because unless you turn an actor first
it will always head towards the right hand side. So what we want to do is change the direction the
rocket is pointing every time we make a new one. If you can remember we used a method like this
to add actors to the ship game it was called a constructor. The constructor sets up things when we
construct a new object of a class. To create a constructor for the Rocket class add the following code
before the act method.

public Rocket ()
{
setRotation (270);
}

Our constructor simply does one thing which is turn the rocket 270 degrees clockwise which leaves it
pointing at the top of the screen. If you test this code it should now fire the rocket at the top of the
screen.

Removing Rockets
If, like me, you have fired a number of different rockets at the top of the screen you will have
noticed that they get stuck there and dont disappear. That isnt really what we want to happen so
lets think about how we can fix it.

We already know we can get the world by calling getWorld() and then use the removeObject
method to remove something from the game. So far so good - but the question is how do we know
when it has reached the top of the screen? Again we have done this before when we got the
submarines to bounce off the sides of the screen can you remember what we checked to see if it
was at the top of the screen?
In case you cant the answer is we checked if the y coordinate was less than or equal to zero. So we
are going to do the same for the rocket and if it is we will remove it from the game! Remember the
parameter for the removeObject method will be this because we want to remove the rocket we are
controlling at the time. This code should go into the act method.

int yCoord = getY();


if (yCoord <= 0)
{
World airWorld = getWorld();
airWorld.removeObject(this);
}

Whenever you are writing a program it is really important to ensure that you always remove things
that you no longer need. If you dont the computer will slow down as it runs out of memory and
eventually crash! Anyway lets test this again and make sure it works.

Firing from the Launcher


Phew! We seem to have looked at a lot today but to finish off lets get the launcher firing the
rockets. What we want to happen is that every time we press space a new rocket should be added to
the game where the launcher is at that time. So lets give it a go

1. Write an if statement that checks if the space key is being pressed.


2. If the space key is pressed create a new variable called airWorld and store the result of using
the getWorld() method into it.

airWorld.addObject(new Rocket(), getX(), getY());

3. Use the addObject method as shown above to add the rocket to the game. This should look
familiar from when we added the ships and submarines to the ship game. Notice how we
use getX and getY to find the current position of the launcher and use that as the starting
position for the rocket.
4. A sound called RocketTakeoff.mp3 has been provided. If you want to use it add the code to
play it after the addObject method.
5. Test it it will work but not perfectly.

As I have already said the last piece of code that you have created will not work perfectly. Can you
explain what is going wrong and how you might try and fix it? Present your ideas to others in the
class and see if you agree!
Session 5 Making the Planes Work

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Understanding the Greenfoot API
Throughout these sessions we have been using class and methods provided by Greenfoot. It is
important for you to be able to find these methods on your own. Java classes are usually
documented as a series of linked webpages and the Greenfoot class are no different. To see the
documentation for the World class double click on it at the right hand side of the screen. Here you
can see a list of all the methods in the World class with a brief explanation of what they do. To see
all the classes that Greenfoot provides click the Package link in the top left corner of the browser
window that opens.

To help you explore I want you to find the following methods and copy the explanation of what they
do into the table below.

Class Method Description


Actor getObjectsInRange
Greenfoot getObjects
GreenfootImage mirrorHorizontally
Greenfoot mouseClicked

Air Raid Game Part 2


So did you figure out what was causing the problem with firing the rockets? What is happening is
that the act method is called so quickly that it is almost impossible to press and let go of the space
key without more than one rocket being fired! The simplest solution to this is to introduce a time
delay between firing rockets so thats what we are going to try.

However before we think about the code lets say what we want to do in plain English. When we
press space to fire a rocket we want to set a delay so that for the next 25 times the act method runs
we dont fire again. So lets get on with it

1. Add a class property to hold the delay counter. A class property is just a variable that you
make for the entire class to use. You declare it as shown below just after the start of your
class. In our case it will be an integer because we just want it to hold numbers between 0
and 25. We say it is private because we dont want any other classes using this information.
Finally we give it a starting value of 0.

public class Launcher extends Actor


{
private int delay = 0;

rest of your class

2. In the act method check if the delay counter is greater than zero and if it is reduce the value
of the counter by one.
if (delay > 0)
{
delay = delay 1;
}

3. We now need to make sure that we dont fire a rocket if delay is not zero. The easiest way to
do this is to change the if statement above to include an else clause. This means that if delay
is greater than zero the delay is reduced otherwise it does what is in the else part of the if
statement.

if (delay > 0)
{
delay = delay 1;
}
else
{
// What do you want to do if
// delay is zero check if space
// is pressed.
}

4. The final step is to set the delay to 25 once you fire a rocket. By changing this number you
will change the delay between rockets. The final code is shown below including the code for
firing a rocket that you already made (this should replace that code otherwise you will be
firing twice).

if (delay > 0)
{
delay = delay - 1;
}
else
{
if (Greenfoot.isKeyDown("space"))
{
World airWorld = getWorld();
airWorld.addObject(new Rocket(), getX(), getY());
Greenfoot.playSound("RocketTakeoff.mp3");

delay = 25;
}
}

5. Test it and make sure the code works.

Falling Crates
Having got the launcher and rockets working we now need to change the Crate class so that crates
fall to the bottom of the screen and disappear when they hit the bottom. The code will be almost
exactly the same as the Rocket class so Im not going to go through it in detail. The main differences
are that you want to set the rotation to 90 degrees and you will want to remove the crate when the
Y coordinate is greater than or equal to 399 (as opposed to less than or equal to zero for the rocket).

Using the Rocket class as a guide try and edit this code yourself and test that it works.

Moving the Plane and Dropping Crates


The last class we have to edit is the Plane class. As a starting point we simply want the plane to go
back and forth across the top of the screen. We have already written the code for this when we
initially got the submarines moving so if you are unsure have a look back at that. The final code in
the planes act method should look like this.

move (5);

int xCoord = getX();


if (xCoord <= 0 || xCoord >= 599)
{
turn (180);
}

We now need to decide how often we want the plane to drop a crate. We could use a delay and just
drop one every few seconds but a better solution would be to drop them randomly. We can do this
by generating random numbers and only dropping a crate if the number is a 1. So if we generated a
random number between 0 and 100 then there is a 1% chance that we will drop a crate each time
the act method is called. The if statement for this would be as follows.

int rand = Greenfoot.getRandomNumber(100);

if (rand == 1)
{
// Get the world and add a new crate
// the same way you added a new
// rocket for the launcher.
}

Using the code for creating rockets in the Launcher class as a guide you should be able to add the
code to make a new crate to this if statement and add the completed code to the act method of the
plane. Once you have test it works.

Finished early and looking for something to improve? Why dont you consider changing some of the
graphics used in the game? In particular the background could be improved. To change the
background you must first get an image of the right size (remember the world is 600 by 400). You
must then right click on the AirRaidWorld class and choose the setImage option.

Java API
Having looked at the Greenfoot API at the start of the lesson why dont you have a look at the Java
API to finish up. It is a LOT bigger and more complicated but the layout is the same and you should
be able to find your way around. The Java1.7 API is at http://docs.oracle.com/javase/7/docs/api/.
One class it might be worth looking up is the java.awt.Color class as you may need to use it to
change the colour of text and backgrounds in the future. See if you can find it!
Session 6 Collision Detection and Keeping Score

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Commenting our Methods
In the last session we looked at the API for classes written by other people but we need to provide
this type of information for our classes as well. To do this we must write comments into our code to
explain the purpose of each method. By default Greenfoot provides the following comment for the
act method of each class.

/**
* Act - do whatever the Actor wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()

Change this comment to say what your act method does in each of the classes you have made. You
can then view what the documentation looks like by choosing documentation from the drop down
list in the top right hand corner of the screen.

Continuing with the Air Raid Game


Collision Detection
We have already done simple collision detection so checking if the rocket is hitting a crate or plane
should be something you are familiar with. However because we now have more than one condition
that can cause a rocket to be removed from the game we have to make sure we dont try and
remove it twice as this will cause our game to crash! In general the code to check if the rocket has hit
another object and remove them both from the game will look like this (for this example I have used
the Crate class). To make sure we dont remove the rocket twice the rest of the code will be put in
an else block so it is only executed if you havent hit a crate.

Actor actor = getOneIntersectingObject (Crate.class);


if (actor != null)
{
World airWorld = getWorld();
airWorld.removeObject (actor); // remove the crate
airWorld.removeObject (this); // remove the rocket
// play sounds or anything else
}
else
{
// Code to check if you have hit the plane or the top of
// the screen goes here.
}

If you dont get this right it is likely that you game will crash and you will get a nasty looking error
message. While you should see if you can construct this code on your own the final version of the act
method in my version of the Rocket class is shown below. You will notice that Im playing a sound
called explosion.mp3 every time I blow something up so you can add this too if you want.
Deal with hitting a crate.

Else deal with hitting a plane.

Else deal with hitting the top


of the screen.

Automatic Setup
So far we have been putting the plane and launcher into the world manually which is a bit of a pain.
To make things easier we are going to edit the constructor of the AirRaidWorld class so that it puts
both of these things on automatically (if you havent done it already). Double click on the
AirRaidWorld class and add the following two lines of code to the constructor.

addObject (new Launcher(), 300, 375);


addObject (new Plane (), 100, 30);

Keeping Score
One thing we havent looked at yet is how to keep score something that you need to do in almost
every game! Probably the best place to store this information is in the AirRaidWorld class as the
score is a piece of information that applies to the entire game. To do scores properly we will need to
provide a variable to store the score in, a way to increase the score and a way to check what the
current score is. So lets get started

1. In the AirRaidWorld class add a new private property called score. It is private because we
want other classes to have to ask us to change the score rather than then changing it
themselves.

public class AirRaidWorld extends World


{
private int score = 0;

rest of your class


2. We are now going to write a method that can be used to increase the score. Note that this
method must be public because it is to be used by other classes.

public void increaseScore ()


{
score = score + 1; // could just write score++; which does the same thing.
}

3. The final thing we need to do is provide other classes with a way of seeing what the current
score is. To do this we are going to add another public method. Notice that instead of saying
void like last time we say int to show that the method is going to return an integer. We use
the return statement to say we want to give this value to the class using the method.

public int getScore ()


{
return score;
}

After you have finished making these changes the final code for your AirRaidWorldClass
should look like this.

Now that we have a way of keeping score we need to increase it when we hit a crate or plane. To do
this we must go back into the Rocket class and change our collision detection code a little. At the
moment our collision detection code looks like the example below.
Actor act = getOneIntersectingObject (Crate.class);
if (actor != null)
{
World airWorld = getWorld();
airWorld.removeObject (actor); // remove the crate
airWorld.removeObject (this); // remove the rocket
// play sounds or anything else
}

What we need to do is call the increaseScore method that we have just made when we are removing
the objects from the game. Unfortunately it is not quite as simple as writing the following line of
code although it is very close.

airWorld.increaseScore();

The problem is that we have said that airWorld is made from the World class and the increaseScore
method is only in the AirRaidWorld class. So what we need to do is tell the computer that the world
we are in is actually made from the AirRaidWorld class. We do that by putting (AirRaidWorld) in
front of the getWorld method. An example of the complete code is shown in the box below. You will
need to change this is two places in the Rocket class once for when you are checking for crates and
once for when you are checking for planes.

Actor act = getOneIntersectingObject (Crate.class);


if (actor != null)
{
AirRaidWorld airWorld = (AirRaidWorld)getWorld();
airWorld.removeObject (actor); // remove the crate
airWorld.removeObject (this); // remove the rocket
airWorld.increaseScore();
// play sounds or anything else
}

As we havent hooked up our score board yet the easiest way to check the score is working is to play
the game for a while and then pause it. You can then right click on the background and choose
getScore, as shown in the screenshot below, to see what your current score is. Try it!
Further Documenting Your Code
Having written comments explaining what each of your act methods do you should now add
comments for each of your other methods. Once finished swap with a partner and see if their
comments make sense do they give enough or too much detail? Are the comments helpful?
Session 7 Counting Lives and Displaying the Score

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Commenting the Code
Having used comments to explain all your methods in the last session you probably think that is all
the comments you could need but youd be wrong. Some methods can do very complicated things
that may need to be explained further. Throughout these sessions you might have noticed I have put
in comments using starting with two slashes i.e. //. When Java comes across these it will ignore what
you have written on the rest of the line so you can write text to explain the code.

Working in pairs you should go back over the code you have written so far and see if there is
anything that might be hard for someone to understand. If there is put in a comment to help them
understand WHY you need that code. Do you think it is possible to have too many comments?

Tracking Lives
Tracking lives is very like keeping score although instead of counting up you are counting down! As
with the score the number of lives you have left should probably be stored in the World and we will
need methods to both decrease the number of lives and find out how many you have left. The code
is almost exactly the same as for the score and the final code added to my game is as follows.

private int lives = 5; // number of lives to start with.

public void loseLife ()


{
lives = lives 1; //could write lives --;
}

public int getLives()


{
return lives;
}

The next decision we need to make is when we lose a life. It seems sensible to lose a life each time a
crate makes it to the bottom of the screen. This makes things easy for us because we already have
code that checks for when that happens. Remember writing code in the crate class to remove it
when it hit the bottom of the screen?

So open the Crate class and find where you check if it has hit the bottom of the screen. We need to
change this code in a similar way to the way we had to change the collision detection to keep the
score. We must first tell the computer that we want an AirRaidWorld and then add a line calling the
loseLife method. The altered code should look like this.

if (yCoord >= 399)


{
AirRaidWorld World airWorld = (AirRaidWorld)getWorld();
airWorld.removeObject (this);
airWorld.loseLife();
}
Once you have changed the code test it in the same way you tested the score previously. If you have
tested it properly you have probably seen the number of lives you have go into negative figures. This
is because we have never told the game to stop when we reach zero!

The easiest (but maybe not the best) place for us to do this is in the loseLife method. All we need to
add is a simple if statement that checks if the number of lives left is zero and calls the
Greenfoot.stop method if it is. The following lines of code are all you need to add. If you test this
code the game should stop after 5 crates have hit the bottom of the screen.

if (lives == 0)
{
Greenfoot.stop();
}

Using the Scoreboard


Now that we are keeping track of the score and how many lives are left it would be nice to display
that information on the screen. If you remember way back at the start of this game I told you that
the StatusBoard class had been provided to show this information on the screen and it is now time
that we use it! This class has one method that we are interested in called updateStatus which simply
takes the score and number of lives to display on the screen. We will need to call this method every
time we change the score or the number of lives we have left.

Happily this will be really easy because the only place the score is changed is in the increaseScore
method and the only place the number of lives is changed is in the loseLife method. However to get
started we need to create the score board from the class and put it into the world.

1. Create a new private property for the AirRaidWorld class to hold the score board in memory.

private StatusBoard scoreBoard;

2. In the constructor make the new score board and put in into the world by calling the
addObject method. The code required to do this is show below.

scoreBoard = new StatusBoard ();


addObject (scoreBoard, 0, 370);
scoreBoard.updateStatus (score, lives);

3. Add calls to the updateStatus method into both the increaseScore and loseLife methods. The
line you need to add to both methods is shown below.

scoreBoard.updateStatus(score, lives);

4. Test it and make sure that it works.


Introduction Sound
To make our game a bit more appealing lets add a startup sound. We can do this by creating a
method called started in the AirRaidWorld class. This method will automatically be called each time
the game starts so I added the following code.

public void started ()


{
Greenfoot.playSound(Siren-AirRaid.mp3);
Greenfoot.delay (500);
}

Playability
Now that you have made most of the game play it and see what you think. Identify any problems
that still exist and see if you can fix them yourself. Things you may want to consider changing include
the speed of the rocket launcher, how frequently crates are dropped, the speed of the plane, etc. Its
you game so its up to you!
Session 8 Finishing Touches to the Air Raid Game

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Growth in Computing Power
If you think about how fast computers have evolved over the last few decades it is truly amazing. To
demonstrate how much computers have changed I have a challenge for you. Most people have a
smart phone of some sort today so I want you to find out the processor speed and memory available
either in your phone or a phone you would like to have!

Done that? Well compare that to the Apollo 11 (the spacecraft that landed on the moon) computers
which ran at 2.048 MHz (not GHz) and about 2KB (not MB or GB) of memory. There is a table below
to help you compare these values. All I can say is wow it does make me wonder if you could do all
that with such simple machines why do people always complain about their computers running too
slow? Do you have any ideas?

Unit Conversion
1 KiloByte 1024 Bytes
1 MegaByte 1024 KiloBytes (1,048,576 Bytes)
1 GigaByte 1045 MegaBytes (1,073,741,824 Bytes)

Replacing the Plane and Making it Harder


One of the biggest issues with the game at the moment is that if you shoot the plane it isnt replaced
and so there is nothing left for you to do. At the same time the game never really gets harder and it
would seem to be a good idea if we add more and more planes the higher the score gets. As both
these problems relate to adding planes to the world we are going to try and deal with both of them
at the same time.

To start with we are going to add two more methods to our AirRaidWorld class. The first method will
be called addPlane and will be used to add a new plane to the world. The second will be called
getNumberOfPlanes and will tell you how many planes are currently in the world.

You should already know how to write the method to add a new plane to the world as you have
already done it in the constructor. So write the method and copy the code into the new method. It
should look like the code below once you are finished. Note that once you have written this method
you could replace the line where you add the plane in the constructor with addPlane;

public void addPlane ()


{
addObject(new Plane(), 100, 30);
}

The second method is a little more tricky but we know that we want to return the number of planes
in the game so the method definition is going to look something like this.

public int getNumberOfPlanes ()


{
// Code to count the number of planes goes here.
return 0;
}
We can get a list of all the planes in the game by calling the getObjects method and passing it the
Plane class as a parameter. Luckily for us the List returned by this has a size method which will tell us
how many planes are in the list. This means that the final code will be as shown.

public int getNumberOfPlanes ()


{
List planeList = getObjects(Plane.class);
return planeList.size();
}

There is one final complication that means that this code wont compile at the moment. The
problem is that unless you tell it Java wont know where to find the List class we are using in this
code. To sort this out we need to go to the top of the file and import the List class. At the very top of
the file you will see a line importing the Greenfoot classes and right underneath it simply write the
following to import the list class.

import java.util.List;

Now that we have both a way of checking how many planes are left and creating a new one we need
to go back to our Rocket class and find the code where we remove a plane that is hit by the a rocket.
After the code that removes the plane we need to check if there are any planes that are left (using
an if statement) and if there isnt add a new one. Once you have added these new lines of code test
your program and make sure it works.

if (airWorld.getNumberOfPlanes() == 0)
{
airWorld.addPane();
}

The final thing to do is consider when we need to add more planes to the game to make it harder.
For example we could add a new plane to the game every time a player scores 5 points but where
would we put that code?

You may have guessed that the increaseScore method might be a good place to do this and that is
what we are going to do. We are going to check if the score is evenly divisible by 5 and if it is then we
will add a new plane. The easiest way to find if a number is evenly divisible by 5 is to use the modulo
operator (written as %). This will give you the remainder of a division so, for example, 11 % 5 would
give you 1 as an answer because when you divide 11 by 5 you get a remainder of 1.

The code you need to add to the increaseScore method is shown below. Make sure you add it AFTER
you increase the score otherwise it wont work properly! Once you have added the code try the
game unless you are a lot better at playing it then I am you might want to change it so that more
than 5 points are required before a new plane is added! You could also set a maximum number of
planes that can be in the game at once there is something for you to figure out on your own!
if (score % 5 == 0)
{
addPlane();
}

Game Over Screen


The easiest way to make a game over screen is to open up a graphics program (paint/fireworks/etc)
and draw one! I would suggest that you make your image 300 by 200 pixels to ensure it fits properly
on the screen.

Once you have made you image create a new subclass of Actor called GameOver and choose your
picture for it to use. Add the following code to the lostLife method just before it stops the program
to display your game over actor in the middle of the screen.

addObject (new GameOver(), 300, 200);

Other Refinements
At this stage it is over to you! You need to decide what if any improvements that can be made. One
thing that you might want to consider is changing the graphics used in the game. You can change the
picture used by any of the objects simply by right clicking on the class and choosing the Set Image
option. Get someone else in the group to play your game and give you feedback on what they think.

Its your game so customise it!

Publishing Your Game


Want to get others feedback on the game? Then why not publish it to the Greenfoot site. You can do
this by clicking the Share button on the right hand side of the window. Publishing a game like this
can be a great way to get feedback and you can always use the Greenfoot forums to ask for more
help if you need it!
Session 9 Cannon Game and Displaying Text on Screen

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Numbers That Represent Colours
In this session we are going to have to tell the computer what colours we want things to be.
Although there are certain constants that we can use most colours need to be specified as RGB
values. That means we need to give the computer three numbers for each colour the amount of
Red, the amount of Green and the amount of Blue. Each of these values must be a number between
0 and 255. By doing some research on the Internet (or by using a paint program on your machine)
see if you can find the RGB values for the following colours.

Colour Red Green Blue


Black
White
Red
Green
Blue
Yellow
Orange
Violet

If you found a useful tool to help you identify colours be sure to share it with everyone else!

Cannon Game
The last thing we are going to make is a simple game where you have to aim a cannon to hit a target
on the other side of a wall. This means we are going to have to add gravity to our game something
which we havent had to consider before. However before we worry about that we need to the
actors we need in the game. The list of actors to create is shown below pick an appropriate image
for each apart from the StatusBoard class which we are going to draw manually anyway.

Object Description
Turret Represents the turret that we aim to fire the cannon balls
from. Use the Turret image for this class.
Target Represents the target that you will need to hit with the
cannon ball. Use the Target image.
Wall Represents the wall you have to shoot over to hit the
target. Use the BrickWall image.
CannonBall Represents the cannon ball that you are going to shoot
over the wall. Use the CannonBall image.
StatusBoard Represents the status board where you will show how
the cannon is currently aimed. Do not pick an image for
this class.

Once you have created all the classes you should be able to add them to the world to make sure that
they display correctly. The only class that wont display anything at the moment is the StatusBoard
class so lets start by fixing that.
Creating a Status Board
We are going to make the status board so that it tells us the angle and the power the cannon is
currently set for. The first step is to do this is to create the background of the status board. To do
this we must first create a property to store the background in by adding the following line at the
start of the class.

protected GreenfootImage background = null;

After creating the property we must write a constructor that draws a rectangle on the in the new
image and sets that image to be used by the actor. The code for this is shown below.

public StatusBoard()
{
// Creates an image 100 by 180 pixels in size
background = new GreenfootImage (100, 180);

// Sets the current colour to 255,255,255 (White) and the


// transparency value to 200 (the higher the more see through)
background.setColor(new java.awt.Color(255, 255, 255, 200));

// Draws the rectangle for the background.


background.fillRect (0, 0, 150, 60);

// Sets this image to be used by the actor.


setImage(background);
}

Now when you add the StatusBoard to the screen it displays a semi-transparent white background
but there is no writing. To add writing we are going to put another method in the class called
setValues. This method will take two integers as parameters one for the angle and one for the
power. Using the background image as a starting point it adds two strings and sets the new image to
be used by the actor. The code for this is shown below.

public void setValues (int angle, int power)


{
// Create a new image based on the background.
GreenfootImage img = new GreenfootImage (background);
img.setColor (java.awt.Color.BLACK);

// Add the text at the x,y coordinates given.


img.drawString("Angle: " + angle, 10, 20);
img.drawString("Power: " + power, 10, 35);

// Change the image of the actor to be the one we


// just made with the writing on it.
setImage(img);
}
Once you have finished the StatusBoard class add it to the world again, right click on it and call the
setValues method to check that it does actually work.

Aiming the Turret


The Turret class will have to keep track of the angle it is aimed at and the power at which it is going
to fire the cannon ball so the first thing we need to do is create properties to hold this information.
Both of these values will be integers so the properties will look like this.

protected int angle = 0;


protected int power = 100;

In the act method you must write methods that increase or decrease these values depending on
what key is being pressed. In my example the angle is changed by pressing left and right while the
power is changed by pressing up and down. An example of the code needed here is as follows.

if (Greenfoot.isKeyDown(left))
{
angle = angle+1;
}

You should be able to write the 4 if statements yourself so give it a go! Unfortunately even if you get
the code right it wont do anything at the moment. The first thing we need to do is rotate the
cannon when the angle is changed. The easiest way to do this is by using the setRotation method
although because we are aiming from the left to the right we need to pass it a negative number as
shown.

setRotation(-angle);

If you test the code now you should be able to see the turret rotating. However with the code as it is
the turret can be aimed in any direction. In our game we only really want the angle to be between 0
and 90 and the power between 0 and 100. To do this you will need to change the if statements you
have just made like the one shown below. Try the others yourself.

if (Greenfoot.isKeyDown(left) && (angle < 90))


{
angle = angle+1;
}

Laying Out the Game


Now that we have the turret moving it is time to add all the pieces to the world at once. Most of this
will be very similar to what you have done before you must make a constructor for the
CannonWorld class and then use the addObject method to add the actors to the world. To start with
we are going to add the status board to the top left corner, the turret at the bottom somewhere on
the left hand side and the target at the bottom somewhere on the right hand side. The code to do
this is shown below.
// Create the StatusBoard, give it an intial set of values
// and then add it to the world.
StatusBoard status = new StatusBoard ();
status.setValues (0, 100);
addObject(status, 50, 90);

// Add a new Turret to the bottom left hand side


Turret turret = new Turret();
addObject(turret, 20 + Greenfoot.getRandomNumber(200), 380);

// Add a new Target to the bottom right hand side


addObject(new Target(), 340 + Greenfoot.getRandomNumber(230), 375);

The interesting bit is how we add the wall to the game. If we just wanted the wall to be one block
high then we could just write the following line of code.

addObject (new Wall(), 285, 380)

However I think it would be more interesting to have the wall a different height each time we play
the game. To do this we will use a random number to pick a wall height between one and five.

int height = Greenfoot.getRandomNumber(5) + 1;

We now want to add that number of blocks to the game. As we dont know how many that will be in
advance we need to use a loop to get the computer to add the correct number of blocks. The best
loop for us to use is a for loop and it would be written as follows.

for (int index = 0; index < height; index++)


{
// code to repeat goes in here
}

What this does is set the variable index to zero, run the code in the brackets and then increase the
value of index. It will keep doing this until index is no longer less than height. Into this loop we put
the code to add the blocks of the wall while being sure to put each block on top of the last (each
block needs to be 50 pixels higher than the last one).

for (int index = 0; index < height; index++)


{
addObject (new Wall(), 285, 380-(50*index));
}

Once you have added all this code test your game and make sure that everything is in the right
place. Press Reset a few times to ensure that the turret and target are placed randomly and that the
wall changes height.
Connecting the Status Board to the Turret
The last job for today is to make the Turret class to use the StatusBoard. To do this we are going to
create a new constructor for the Turret class which takes the status board to use as a parameter and
then stores it in a property. The code to be added to the Turret calls should be as follows.

protected StatusBoard statusBoard;

public Turret (StatusBoard board)


{
statusBoard = board;
}

Then to update the board we need to call the setValues method of the StatusBoard class from the
act method of the Turret class. Simply add the following code to the end of the act method of the
Turret class.

statusBoard.setValues (angle, power);

If you try and compile the code now it wont work! This is because we have changed the Turret
constructor so that you need use a StatusBoard object as a parameter. To fix the error go to the
cannon world class and find the code where you create the new Turret. You then need to change it
as follows. Remember status is what you called the StatusBoard object that you created earlier in
the worlds constructor.

Turret turret = new Turret (status);

If you test the code now the staus board should update as you aim the cannon.

Sound Effects
If you have finished all the coding and still have time to spare why dont you try and find sound
effects that you can use with your game. You can use mp3 or wav format files and there are many
sites where you can download these off the Internet. If you cant find something that suits what you
want to do then why not edit a sound (using Audacity or other programs) to make it fit!
Session 10 Adding Gravity to Games

Authored by Brian Cullen (bcullen@rossettschool.co.uk)

(c) Copyright 2011 Computing At School.


This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
See http://creativecommons.org/licenses/by-nc-sa/3.0/ for details.
Substitution Cypher
Although this competition is called the code breaker competition we havent talked about codes
very much. As this the last session I want to introduce one of the simplest types of codes called a
substitution cypher. In this type of cypher you simply replace each letter with another or a number.
A simple example would be to replace each A with a 1, B with a 2, C with a 3 and so on.

In pairs develop a substitution cypher and write a message using it (with at least 10 words). Make
sure that you can decode the message properly and then swap with another group. Can you decode
each others messages? What do you think the weaknesses of this type of cypher are?

Cannon Game
Today the focus is going to be on getting the cannon ball moving and collision detection. The game
will not be complete at that stage and it will be up to you to finish it but Ill mention that again at the
end. For now lets get started

Making the Cannon Ball Move


Getting the cannon ball to move with gravity isnt too complicated but it does require a little bit of
trigonometry. In particular you must be understand how you can calculate length of all the sides of a
right angles triangle when you only have one angle and the length of the hypotenuse. The diagram
below shows the formulae you need to use to do these calculations.

cosine (Angle)
Hypotenuse *

Angle
Hypotenuse * cosine (Angle)

So why do we need to use this formula? To figure out how to move our cannon ball we must be able
to calculate how far it moves in terms of X and Y coordinates. Therefore it is necessary for us to get
the power and the angle the cannon ball is shot at and use this to calculate how fast it is move in the
horizontally (X) and vertically (Y). This should be done in the constructor of the CannonBall class and
we then need to store the results into properties of the class. The code to do so is shown below.

protected int xSpeed = 0;


protected int ySpeed = 0;

public CannonBall (int angle, int power)


{
power = (power * 10) / 25;
xSpeed = (int)(power*Math.cos(Math.toRadians(angle)));
ySpeed = (int)(power*Math.sin(Math.toRadians(angle)));
}

The only thing you might not have expected in the constructor is where the value of power is
changed. This is done because I felt that having the power at 100 was far too high but you can
change it to anything you think works well. Having figured out the cannon balls initial speed we now
need to edit the act method to move it. To move it without worrying about gravity we can simply
write the following in the act method.

setLocation (getX() + xSpeed, getY() ySpeed);

If you test this code the cannon ball should shoot off the screen in a straight line not very useful
but a start. To start with we need to define the number we are going to use for gravity and rather
than just write it into our formulae we are going to make a constant so we can use it again if
necessary. To make a gravity constant add the following property to your CannonBall class.

public static final int GRAVITY = 2;

As this property is declared as final it means it cannot be changed by the program. Also notice that
because this is a constant I have put it in all capitals. So now to take gravity into account in our act
method simple add the following line to the end of the act method. This will slowly change the
vertical speed of the cannon ball until it plummets off the bottom of the screen.

ySpeed = ySpeed GRAVITY;

To finish this class we need to think about when the cannon ball should be removed from the world.
We will deal with what happen when it hits a wall or the target later but what if it doesnt hit either?
The easiest condition to check for is if the cannon ball goes off the bottom of the screen (which
gravity will eventually force it to do) then we should remove it. You should be able to write the code
to do that by yourself by now but if you are stuck it is shown below and should be added to the act
method in the CannonBall class.

World cannonWorld = getWorld();


if (getY() > cannonWorld.getHeight())
{
cannonWorld.removeObject(this);
}

Notice how we use the cannonWorld.getHeight method rather than assuming the world is always
going to be 400 pixels high. This means we could change the size of the world without having to
change this code a definite advantage!

Firing the Cannon Ball


Having setup the cannon ball the last step is to fire it. This should be done from the Turret class just
like how we fired rockets in the last game we made.
if (Greenfoot.isKeyDown(space))
{
World cannonWorld = getWorld();
CannonBall ball = new CannonBall (angle, power);
cannonWorld.addObject(ball, getX(), getY());
}

One problem I noticed when testing this is that it is almost impossible to fire a single cannon ball at a
time and there are two obvious ways of solving this problem. The first is to use a delay similar to the
one we used in the rocket game. The other option is to check if there are any other cannon balls in
the world and if there are dont shoot again. This method does this by asking the world to give it a
list of all the CannonBalls currently in it. It then returns a value of true if the list is empty (meaning
that there are no cannon balls currently present).

public Boolean noCannonBalls ()


{
World cannonWorld = getWorld();
java.util.List balls = cannonWorld.getObjects(CannonBall.class);
return balls.isEmpty();
}

We can now change the if statement from before so that we only fire a cannon ball if the space key
is pressed AND there are no cannon balls.

if (Greenfoot.isKeyDown(space) && noCannonBalls())


{
// Code to fire the cannon ball is as before
}

Collision Detection
As with the other games we can put the collision detection in more than one place and it doesnt
really matter. To check if the cannon ball hits the wall we are going to put the collision detection into
the act method of the Wall class. In this method we simply want to check if a cannon ball is touching
one of the wall blocks and if it is remove it from the world.

Actor cannonBall = getOneIntersectingObject(CannonBall.class);


if (cannonBall != null )
{
World cannonWorld = getWorld();
cannonWorld.removeObject(cannonBall);
}

To check if the cannon ball has hit the target we will add some code to the act method of the Target
class. If they have collided then we simply remove both the target and the cannon ball from the
world to show that it has been hit.
Actor cannonBall = getOneIntersectingObject(CannonBall.class);
if (cannonBall != null )
{
World cannonWorld = getWorld();
cannonWorld.removeObject(cannonBall);
cannonWorld.removeObject(this);
}

Test the code make sure that it works. If you want you can code to these blocks to use sound or
other effects to show that it has been hit.

Over to You
This game is not complete and there are lots of things you could add. Two examples could be a
count of the number of misses it takes for you to hit the target or resetting the world for a second
round once you hit the first target. However from here on it is up to you. In general my advice is
say/write what you want to do in English first and then worry about how to code it otherwise you
may lose sight of what you are trying to do and REMEMBER TO COMMENT YOUR WORK!

Happy Coding

You might also like