Professional Documents
Culture Documents
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.
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.
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).
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.
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.
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?
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
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!
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.
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).
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.
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.
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.
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.
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.
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.
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:
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.
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.
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.
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
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!
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.
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.
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.
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
To help you explore I want you to find the following methods and copy the explanation of what they
do into the table below.
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.
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;
}
}
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.
move (5);
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.
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
/**
* 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.
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.
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.
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.
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.
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.
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
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.
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.
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();
}
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.
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.
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);
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
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)
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;
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.
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();
}
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.
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.
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.
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);
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.
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.
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.
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.
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.
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).
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.
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.
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.
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
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
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.
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.
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.
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.
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.
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!
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).
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.
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.
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