introduction to greenfoot part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf ·...

37
1 Introduction to Greenfoot Greenfoot is an IDE (Integrated Development Environment) that is built on Java. Greenfoot creates scenarios (projects) that allow us to create a variety of programs such as games and simulations Lets open a scenario called Wombats that comes as a default when you install greenfoot. Choose the Scenario, then Open and select Wombat. When you open this you see the following: This represents a world that we have named and created. To the right we see the class and underneath we see how it looks visually. You will have to make an Actor class for each type of object (e.g. leaf) that you want to have in your world. Compile allows you to turn you code into machine code that the computer understands. If any of your classes are grey, then they haven’t been compliled Use these buttons to run your code once it’s compiled.

Upload: others

Post on 03-Feb-2020

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

1

Introduction to Greenfoot

Greenfoot is an IDE (Integrated Development Environment) that is built on Java.

Greenfoot creates scenarios (projects) that allow us to create a variety of programs such as games and simulations

Lets open a scenario called Wombats that comes as a default when you install greenfoot.

Choose the Scenario, then Open and select Wombat.

When you open this you see the following:

This represents a world that we have named and created. To the right we see the class and underneath we see how it looks visually.

You will have to make an Actor class for each type of object (e.g. leaf) that you want to have in your world.

Compile allows you to turn you code into machine code that the computer understands. If any of your classes are grey, then they haven’t been compliled

Use these buttons to run your code once it’s compiled.

Page 2: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

2

Adding Objects to Your World

We will see later how we can automatically add objects to the world, but in the meantime we can add these manually when the scenario is running.

Click the run button in the Controls area.

Nothing will happen, so don’t be surprised as we haven’t actually told it to do anything!

Lets add our first actor to our world. There are two ways of doings this manually. We can click on the actor (wombat in this case), then hold down shift, or right click the actor and select new Wombat().

Add a wombat actor to your world.

What you have done here is to add an instance (object) of the class Wombat. This terminology wont make a lot of sense yet, but we will revisit it again.

If you have done this correctly you should see a wombat running around the edge.

Wombats like to eat leaves, so add a couple of leaf objects in their path and they should eat them.

Invoke a Method Directly

Objects (actors) have properties and methods.

Properties: These store values for each instance of an object. E.g. its height, speed, or its location

Methods: These are the actions that an object has. E.g. move forward, turn left, eat leaf

If we click pause in our scenario it stops. Do this, then right click on a wombat.

Page 3: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

3

Here we can see all the methods that a Wombat has. Can you think what each does?

The first part of a method tells you what type of data it returns. We see three different types being returned above. These are

Void – returns nothing

Boolean – returns true or false

Int – returns a whole number

We look at these types in more details later on.

There is also one that is called inherited from Actor. This means all the methods that an actor has that we also gain. This is an important aspect of OOP (Object Orientated Programming).

Page 4: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

4

So we can see we have a few more. Can you think what each of these may do?

Our first program

We are going to create a program where lobsters move around in the sand. The lobsters will try and eat seahorses. We will also later add an arch enemy of the lobster to try and eat it to make the game more challenging.

First create a new blank scenario called Lobsters.

Page 5: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

5

This is as basic as we can get in greenfoot. We cant directly interact with the base classes of World or Actor, so we have to create children of these.

We have to create a new world, so right click on the World class and select new subclass.

Page 6: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

6

Call this LobsterWorld and select the image sand.jpg which is under backgrounds. This image will be tiled if it does not take up the whole screen.

You should now notice you have created a child class of World called LobsterWorld

Notice that LobsterWorld is greyed out. This means that it hasn’t been compiled yet.

Compiling a Java program means taking the programmer-readable text in your program file (also called source code) and converting it to bytecodes, which are platform-independent instructions for the Java VM. In other words turning your code into code that your computer will understand.

Page 7: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

7

If you click the Compile button then then the greyed lines should be removed. These will not be removed if Java detects errors in the code. If you do receive errors then greenfoot will take you to where it sees a problem.

Lets look at the default code that’s been added. We can do this by either double clicking LobsterWorld, or by right clicking it and selecting open editor.

You should see something similar to the following:

Anything that is between /* */ are just comments. These are ignored by java and are really just for programmers to help other programmers explain what parts of the code do. We can also add a single line comment using //

The line –

import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class LobsterWorld here. * * @author (your name) * @version (a version number or a date) */ public class LobsterWorld extends World { /** * Constructor for objects of class LobsterWorld. * */ public LobsterWorld() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super(600, 400, 1); } }

Page 8: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

8

was created when you right clicked the world object and selected new subclass. So we can see LobsterWorld is a type of World. public LobsterWorld() This is what is known as a constructor. All we need to know about a constructor is that when we create an instance of this object this code is called automatically.

Notice the curly brackets. The curly brackets signify sections of code. So everything between the {} above belongs to LobsterWorld(). So any code that sits between the curly brackets only runs when LobsterWorld() is called. You will forget to open and close these curly brackets a lot, especially at the start. Its good practice to use indenting to show which open curly brackets matches close ones. You can also use a feature of Greenfoot to help you here.

Under Edit there is a command called Auto-layout. This will improve you code layout and will show which curly brackets have no opening and closing pair.

In our example

public class LobsterWorld extends World

public LobsterWorld() { }

Page 9: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

9

It has one comment and one line of code.

Super(600,400,1) - this creates a new world of width 600, height 400 with cell size 1.

Try changing the height to 500 in the code, then press compile. What do you notice?

Adding a Lobster

We wish to add a lobster actor to our scenario. Right click on Actor and select new Subclass.

We could import a picture of our own, but we will see this later, so in the meantime select animals-> lobster.

Press run and add an instance of a Lobster to your scenario. Does it do anything?

The answer should be no as we have yet to add any code that would tell it to do anything.

Open up the code editor for lobster (double click on lobster, or right click and select editor).

We can see the class Lobster, which is descended from an Actor. There is an important method called act(). This tells your actor how it should behave. This method is different from other methods you will create as it is

public LobsterWorld() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super(600, 400, 1); }

import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class Lobster here. * * @author (your name) * @version (a version number or a date) */ public class Lobster extends Actor { /** * Act - do whatever the Lobster wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { // Add your action code here. } }

Page 10: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

10

continually called. Ie if you add code here it will run it, then run it again, and again and again… Remember to keep all code here between the { }. A quick review of all the parts

So if we want our lobster to actually do anything then we will have to add code here. If you right click on an instance of your lobster you can see all the methods that are currently available.

These are comments that describe what your program does. They are not compiled.

This is where your class is named and you declare it as a subclass of Actor.

This is where you put the code that controls the behaviour of your actor. Notice we have a single line comment here.

Page 11: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

11

If you look at the list we can see a command called void move(int). If we wish to have more information on how this command works then we can look at the documentation. This is easily available by double clicking on the top level Actor class. If you scroll down you should see the method move described : void move(int distance)

Move this actor the specified distance in the direction it is currently facing.

int means integer which is a whole number. The higher the number the more the actor moves. Return to our code within crab and add the following:

Note: notice the ; this tell java it’s the end of a command. If you omit this you will get an error when compiling. This is another error you will do a lot of at the start of learning to program.

You need to precisely match what is written here. It's the word move, followed by round brackets containing the number 4, followed by a semi-colon. Common mistakes include captialising the m (case matter in java!) missing the semi-colon, using the wrong brackets (or thinking that empty round brackets are a zero), or accidentally deleting the curly brackets. If you get an error during this tutorial, look for one of these errors that you might have made when copying the code.

Once you've written this, hit the Compile button in the main Greenfoot interface (or at the top of the editor window) then place a lobster in the world again and click Run. Now the lobster should glide sideways across the screen. Then it should hit the edge of the world and abruptly stop. If you like, you can pause the scenario, drag the lobster over to the left, hit Run and watch it again. Why not place a few more lobsters in the world and watch them all do that? The lobsters aren't actually stopping as such; they are still trying to move, but Greenfoot doesn't let them move out of the world (if they did, how would you drag them back in again?). You can vary the speed of the Lobster by changing the number 4 in the code to a different number. Higher

public void act() { move(4); }

Page 12: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

12

will be faster, lower will be slower -- see if you can guess what happens with a negative number.

The fun soon wears off if you can only have lobsters going in a straight line.

Let's make the lobster do a bit more than simply going forward. Go back to the code, and after the move line, add another line (but still inside the curly brackets for the act method) that says turn(3), like this:

You'll see that the lobster runs in a circle. Experiment with the turning amount to get the circle tighter or larger.

The good thing about the lobster turning all the time is that even if it does hit the edge of the world, eventually it will turn enough that it moves back off the edge of the world and into the middle again. What would be even better is if we can control the lobster's turning -- let's get some interaction in our scenario! We can make the lobster turn when we press the left or right cursor (arrow) keys.

The If statement

The if statement is an example of a conditional expression. This means that you can have certain section of your code only run when something is true.

e.g.

public void act() { move(4); turn(3); }

if ( true condition ) {

do something }

Page 13: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

13

In our lobster application there is a predefined class called Greenfoot which has a number of methods that we can use.

One such method is Greenfoot.isKeyDown(“Selected Key”). This return true if the selected key has been pressed.

So to make our crap turn we would have to add the following logic

If left Key then

Turn left

If right key then

Turn right

In java and Greenfoot the above is written as follows:

So in the above code it says

Move forward 4

If left key pressed turn left 3

If right key pressed turn right 3

We use the Greenfoot built-in methods for checking if a key is down. Between the quotes is the name of the key, "left" is the left cursor key, "right" is right. If you want something like "a" and "d", just use those instead! Our code is saying: if those keys

If (user > 65) {

ProcessPension();

}

public void act() { move(4); if (Greenfoot.isKeyDown("left")) { turn(-3); } if (Greenfoot.isKeyDown("right")) { turn(3); } }

Page 14: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

14

are down, turn a certain number of degrees. Enter that code, compile it, and try it out for yourself. You can alter how fast the lobster turns by increasing those numbers.

If you put multiple lobster in the world, you'll find that pressing the keys controls all of them at once in glorious synchronisation, making you into some sort of lobster overlord: all of the lobsters are executing the same code, so if you press the left key, all of them will see that the left key is down, and they will all turn accordingly.

Add Actors in Code

So far we have manually added actors to our world while it is running, but this is rather repetitive and long winded. We can add new actors at the start of the program automatically by using the addObject command. The help file says the following:

void addObject(Actor object, int x, int y)

Add an Actor to the world.

So we require the name of an actor, and its position where to start. Position is from the top left of your screen.

To automatically add a lobster we would do the following

The new Lobster() creates an instance of the Lobster class.

Can you think where we would add this code?

The above code can be re-written by the following

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

Lobster lobster1 = new Lobster();

addObject(lobster1,300,200);

Page 15: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

15

Both do the same, but the second option allows us to effect a particular lobster instance in code from the world. This is a technique that we will go into more details on later.

We would add this to the LobsterWorld constructor, so that this runs the first time the world is created.

Compile your scenario and you should now see a lobster appear in the middle of your screen.

Adding other actors

Lets create another child object of Actor called Seahorse.

As the new class name, enter: Seahorse -- note that we are using a capital S. It's the convention in Java that we begin class names with a capital letter. If you accidentally use a small s now, you'll get an error later on when copying our code that uses a capital S. From the left-hand list of images, select "Seahorse.png" as the image and press okay.

Add code to the scenario to automatically create 3 sea horses.

Add the following code to a seahorses act method:

Our Seahorse class will have no real code in it to begin with -- just like our lobster class was when we started. We're going to leave it that way; our Seahorses are dumb and just sit in one place ready to be eaten. Easy prey! We're going to modify our lobster class so that when our lobsters pass over a seahorse, they eat the

public LobsterWorld() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super(600, 400, 1); addObject(new Crab(),300,200); }

turn(3);

Page 16: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

16

seahorse. To do this, we go back to our lobster's source code, which currently looks like this:

At the end of the act() method, we're going to insert some code to check whether the lobster is currently touching a seahorse. We'll use the method getOneIntersectingObject. This method takes one parameter. The parameter allows us to indicate which class we're interested in; that's the Seahorse class:

Note that we're not only calling the method, we're doing something on the left-hand side, too. This method returns something (the object underneath us, if there is one), so we need to store this return value ready to use it again. To do this we declare a variable (something for holding values) which we've called myseahorse, on the line before. Then we use the assignment operator (an equals sign) to indicate that the value of myseahorse should be set equal to the return value of the method.

Now we have the return value of the method in the variable myseahorse. If there was no Seahorse touching us, this variable will contain the special value null. We can only remove the seahorse when there is a seahorse, so we need a check that the seahorse is not the special null value before removing:

Actor myseahorse; myseahorse = getOneObjectAtOffset(0,0,Seahorse.class); if (myseahorse != null) { World world; world = getWorld();

public void act() { move(4); if (Greenfoot.isKeyDown("left")) { turn(-3); } if (Greenfoot.isKeyDown("right")) { turn(3); } }

move(4); if (Greenfoot.isKeyDown("left")) { turn(-3); } if (Greenfoot.isKeyDown("right")) { turn(3); } Actor myseahorse; myseahorse = getOneIntersectingObject(Seahorse.class);

Page 17: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

17

world.removeObject(myseahorse); }

The != is the "does not equal" operator in Java. This means we will only execute the code when myseahorse is not null. The code in question is to get a reference to the world in the variable imaginatively named world and tell it to remove the worm using the removeObject method.

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 aren’t equal.

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

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 let’s 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)

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

Page 18: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

18

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!

So, let's give it a test. Compile it, create some seahorses and place them in to your world, then add a crab, hit run and use your left and right keys to guide the crab to the seahorses, which should then get eaten. Tasty!

Create another actor that the crab can eat and have the scenario create 2 occurrences of these.

Refactoring

Before we move on, we are going to make a change to the code. This is something known as refactoring: changing the code without changing its behaviour. Currently the run() method for the Lobster has two distinct behaviours in it: the top half deals with moving around, and the bottom half deals with eating seahorses. It would be clearer to name these and split them up, to avoid confusing ourselves later on. We can do this by creating methods for each behaviour. We've actually already seen how methods are written: act() is a method, after all.

Both of our new methods require no parameters and return no value, so they can be declared just the same as act(); the adjusted code is below:

If you compare this code to the previous version, you'll notice that we haven't actually changed or removed any of the existing code. We moved the top half into a new method called moveAndTurn, and we moved the bottom half into a new method called eat. We then replaced the contents of the act() method with calls to these new methods. So why do it? This again is good practice in programming, to break down code into smaller more manageable chunks. So above is we know we have a problem with movement, then it easy to see the problem probably lies within the moveAndTurn() method. You might still think that you can have seen that without refactoring, but what if you act had 1000 lines of code, and someone else had written it!

public void act() { moveAndTurn(); eat(); } public void moveAndTurn () { move(4); if (Greenfoot.isKeyDown("left")) { turn(-3); } if (Greenfoot.isKeyDown("right")) { turn(3); } } public void eat() { Actor seahorse; seahorse = getOneObjectAtOffset(0,0,Seahorse.class); if (seahorse != null) { World world; world = getWorld(); world.removeObject(seahorse);

Page 19: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

19

Random Movement Lets add another actor, that will attempt to eat our lobster! The well-known enemy of a lobster is the alligator. Create another child class of actor called Alligator and chose an appropriate image. In the actor of Alligator lets create our own method because we know refactoring is fun. In side act add:

then outside of the method add :

Greenfoot.getRandomNumber(int) gets a random number between 0 and int, but not including int. So above we will get a number between 0 and 89. That code means we will turn a random amount each frame, between 0 degrees (inclusive) and 90 degrees (exclusive). Try it out, and see how it works. You'll see that it doesn't create a very threatening enemy: the alligator seems to mostly spin on the spot (turning too often, in effect), and it always turns to the right. Let's fix those problems one by one, starting with the spinning on the spot. At the moment, our alligator turns every frame, which makes it spin rather than wander around. There's a couple of different ways that we could make it turn less often. One would be to have a counter variable that keeps track of how long it was since we last turned, and turns, say, every 10 frames. Another way is to use the

moveAround();

public void moveAround() { move(4); turn(Greenfoot.getRandomNumber(90)); }

Page 20: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

20

random number generator to turn randomly, with a certain average (e.g. every 10 frames). We'll go with another use of the random generator, as it makes for a less predictable alligator. Let's say that an alligator has a 10% chance of turning each frame. We can code this by comparing Greenfoot.getRandomNumber(100) to a given percentage:

That will make our alligator turn (on average) every 10 frames. Compile and run it, and see what happens. The alligator should mostly wander along in a straight line, occasionally turning right by a varying amount. That's great, and it brings us back to our other problem: the alligator always turns right. We know from our lobster that the way to turn left is to use a negative number for the angle. If we could change from turning our lobster in the range 0 to +90 to turning in the range -45 to +45, that would fix our problem. There's a few different ways to achieve this, but here's the simplest: notice that if we subtract 45 from our number, we end up with a number in the right range. So let's adjust our code accordingly:

Compile and run that, and we should have a somewhat effective predator that can turn towards you at any moment. Put a lobster, several alligators and lots of seahorses into the world (then save the world!), and try to eat all the seahorses before the alligators catch you. You might notice however that there is one remaining flaw: the alligators can get stuck for a time at the edges of the world. This is because once they hit the edge of the world, they'll only move away from it once they've done a few random turns. We can speed up the process of getting the alligators off the walls again by making them turn 180 degrees as soon as they reach the edge of the world. We can check for being at the edge of the world by seeing if their X coordinate is close to zero, or close to the width of the world -- and a similar logic for the Y coordinate (and the height of the world).

public void moveAround() { move(4);

if (Greenfoot.getRandmonNumber(100) < 10) { turn(Greenfoot.getRandomNumber(90)); }

}

public void moveAround() { move(4);

if (Greenfoot.getRandmonNumber(100) < 10) { turn(Greenfoot.getRandomNumber(90)-45); }

}

Page 21: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

21

We are going to use new methods of an actor – getX() and get(Y). These simply return the current world co-ordinates of the current actor. The code is below:

Remember that getWorld() get the current world information. So getWorld().getWidth() gets the current world width.

public void moveAround() { move(4);

if (Greenfoot.getRandmonNumber(100) < 10) { turn(Greenfoot.getRandomNumber(90)-45); } If (getX() <= 5 || getX() >= getWorld().getWidth() – 5) { turn(180); } If (getY() <= 5 || getY() >= getWorld().getHeight() – 5) { turn(180); }

}

At this corner both X and Y are equal to zero – (0,0)

X increases as you go to the right.

Y increases as you go dow

n

At this corner X is at it’s biggest (599 in our world because it starts at 0) – (599,0)

At this corner Y is at it’s biggest (399 in our world because it starts at 0) – (0,399)

At this corner both X and Y are at their biggest – (599, 399).

Page 22: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

22

We also have || in our code. Here we are using something called Boolean algebra. The word algebra tends to put fear into people, but in this case it is quite a simple. || = or && = and Item1 Item2 || (or) && (and) False False False False False True True False True False True False True True True True Sometimes it can be easier constructing some simple real life examples to help explain the above.

You can get a bank account if you have a uk address and a passport.

Notice the and. In the above sentence when can you get a passport?

Your thinking should be the same as the table above.

Now lets have a bank where it is easier to get an account.

You can get a bank account if you have a uk address or a passport.

How does this change when you can get a passport?

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 won’t 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

Page 23: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

23

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?

We have now learned nearly every command that we require! Quite some feat for an introduction! But we can still learns lots of different techniques using these commands to build games and puzzles that become more complex.

Bee Exercise

As an exercise try and create fly game, where you are a bee and have to eat flies.

The first version should create 5 flies and you should try to eat them.

Good luck.

Lets change the program so that every time you eat a fly then another one appears.

Lets make it harder. Every time a fly dies, 2 more are created!

Playing and Recording Sounds

We can add some sound to our scenario.

Sounds are picked up within your scenario directory in a folder called sounds. Copy the file eating.wav from moodle to this folder

We can make that sound play every time the crab eats a seahorse by adding a single line to our crab class that calls Greenfoot.playSound after we remove a seahorse from the world:

Page 24: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

24

Give that a try. Don't forget to turn your speakers on (or plug in your headphones). One last thing -- if you have a microphone for your computer, you can record your own sounds. In the Controls menu there is an option to show the sound recorder:

Press the record button and speak (or scrunch an empty food packet, or whatever!), then press stop. You should see a green wave, and when you press play you should hear your noise played back to you. If not, there is a problem with your microphone -- try googling to get help with that. Assuming it does have some sound, you'll almost invariably have a bit of silence at the beginning and end of the sound -- you can see this in the green display, as it will have a flat horizontal line at the beginning and end before the shape:

Silence at the end isn't much of a problem, but silence at the beginning is irritating -- it means that when you tell the sound to play when a worm is eaten, there will appear to be a short delay before the sound starts playing, as if your game is lagging. You can clean up the silence by selecting the bit in the middle (the bit you want to keep) by clicking at the beginning (after the initial silence) and dragging to the end (before the final silence) -- the selection should be shown in grey. Then press "Trim to selection". The silence should be removed.

Save the sound by entering something in the filename box (e.g. "myeating") then pressing Save. Close the sound recorder and go back to your code. Find the line with "eating.wav" and change it to "myeating.wav" (or whatever name you used, plus

if (seahorse != null) { World world; world = getWorld(); world.removeObject(seahorse); Greenfoot.playSound("eating.wav"); }

Page 25: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

25

the .wav extension). Then when you play your game, you should hear your own sound playing.

Dodge Game

We are going to create a scenario where we move Eric around, who is a small person trying to find the way out of a crazy world.

Eric cannot touch anything in the world as it means certain death, so he must navigate all obstacles in front of him to reach his goal.

Create a new World called DodgeWorld with a background of rivets.

Create a new actor called eric and chose a picture for him.

Add Code to DodgeWorld that creates an instance of Eric at the top left.

Add another actor called Block, and chose Background brick.

Add the following code to DodgeWorld

Page 26: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

26

This will create a number of bricks to dodge.

We have seen movement before using the move and turn commands. This time we are going to control it ourselves.

In the act of Eric we can move eric left by using the following commands.

Complete this so that eric moves in all 4 directions.

We are now going to create a block that will rotate and try to stop eric from making it through the gap in the wall.

In Greenfoot you can add your own images and sounds. We are going to create green block and add it to our world.

Open Microsoft paint and create a new image 200 x 20 pixels in size. Then paint it green. You may have to resize a current image. Save this anywhere except in your scenario images folder.

Now create a new Actor called GreenBlock and import the image you just saved.

Add this object automatically at the location 302,162.

We are now going to make it rotate. Can you think how you might do this?

Previously we have looked at collision detection, by checking if we have collided with a particular object. There are a number of collision methods available.

We have seen getOneIntersectingObjectt(Object.class);

addObject(new Block(),50,150); addObject(new Block(),150,150); addObject(new Block(),450,150); addObject(new Block(),550,150);

if (Greenfoot.isKeyDown("left")) { setLocation(getX()-5,getY()); }

Page 27: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

27

Which allows us to detect a collision where we can change where the collision can happen by changing the x and y. Keeping the x and y at zero is just the same as

getOneIntersectingObject(object.class);

We have seen this as follows:

This allowed us to detect if we had collided with a particular class.

In java there is something called a null, which means nothing.

We can actually use that here to detect a collision with any class where we use null.

So we can write:

Would return a value anytime we collide into something in our world.

Add the logic above so that every time Eric bumps into something he goes back to the start.

We now require to add a place where Eric has to reach to escape.

Create another actor called Home and chose a building which will be the way out.

Add this object to 546,364.

Add code so that we win when eric reaches this home.

Within this code we are going to add eric to a new world.

Actor myseahorse; myseahorse = getOneIntersectingObject(Seahorse.class); if (myseahorse != null) {

//do something here if a seahorse is found }

myCollidedObject = getOneIntersectingObject(null);

Page 28: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

28

Create another world so that we have 2 worlds in our scenario and call it DodgeWorld2.

The code to make this active is as follows:

Now automatically create eric in this world and add some more obstacles. This may be multiple turners, other actors that move or more walls to miss.

Dodge Game Part 2

What if we wanted to have more than one turning block? This would be quite easy as we just add another instance of the Block actor. But what if we wanted this block to turn at a different speed? Would we have to create a different actor?

With our current knowledge the answer is yes, but we can expand our classes with additional properties.

So we could add a property called turnSpeed. This would store the current speed of the block.

The above code adds a public property called turnSpeed. It is declared as an int type (whole number) and has a default value of 2. So if we don’t set a turn speed it will turn at a speed of 2.

If we run our program we can pause it and inspect the GreenBlock actor.

Greenfoot.setWorld(new DodgeWorld2());

public class GreenBlock extends Actor { public int turnSpeed = 2; public void act() { turn(turnSpeed); } }

Page 29: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

29

First we can see our new method called setSpeed.

Click Inspect

We can see our property called turnSpeed and its current value.

We have seen a constructor method used within the world class. This is a special method that is called when an object is created.

So in world we see something like:

This means when the World DodgeWorld is created this code is automatically called. We can add this feature to any of our classes. So lets expand our GreenBlock class.

public class DodgeWorld extends World { /** * Constructor for objects of class DodgeWorld. * */ public DodgeWorld() {

super(600, 400, 1); addObject(new Eric(),20,20); }

Page 30: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

30

Here we have added a constructor(notice it has the same name as the class). This constructor also expects an integer value to be added. So where we normally added something like :

We would now have

This would pass a value of 3 into the constructor via the parameter called speed.

Note: a parameter is a kind of variable that passes data in or out of a method.

Update your program to have more than one block moving at a different speed and/or direction.

We could add another method to this class, so that we can change the speed without having to create a new instance. This is very similar to what we did in the code refactoring section.

public class GreenBlock extends Actor { public int turnSpeed = 2; public GreenBlock(int speed) { turnSpeed = speed; } public void act() { turn(turnSpeed); } } addObject(new GreenBlock(),302,162);

addObject(new GreenBlock(3),302,162);

Page 31: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

31

The new part is

This means we can refer to the object.setSpeed(2) to change the speed at any time we wish. So as the player takes longer we could increase or decrease the speed of the spin.

Adding the Score

We have created a class called Score. In the Score class we can create a constructor that displays the score and a method that does the same. Very similar to the idea of the GreenBlock above.

Notice the line

public class GreenBlock extends Actor { public int turnSpeed = 2; public GreenBlock(int speed) { turnSpeed = speed; } public void setSpeed(int speed) { turnSpeed = speed; } /** * Act - do whatever the GreenBlock wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { turn(turnSpeed); } }

public void setSpeed(int speed) { turnSpeed = speed; }

import greenfoot.*; import java.awt.Color; public class Score extends Actor { public Score(String text, int val) {

// create the button image setImage(new GreenfootImage(" " + text + " "+val, 36, Color.black, Color.yellow)); } public void act() { // Add your action code here. } public void setScore(String text, int val) { setImage(new GreenfootImage(" " + text + " "+val, 36, Color.black, Color.yellow)); } }

Page 32: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

32

Here we bring in other Java classes that will give us access to the color class.

So we have a constructor called Score and a method called setScore. Both do the same. They take in 2 parameters or type string (characters) and type int (whole numbers) and then display a message. This message is displayed by creating a GreenfootImage with the message displayed on it.

Our basic scoring system is going to be worked out by increasing the score the longer Eric lives.

Lets create a property of Eric that will store his current score.

In the act method we could write

This increases ericscore by one each time it is called. In programming we normally write this as

import java.awt.Color;

public class Eric extends Actor { public int ericscore = 0;

ericscore = ericscore + 1;

Page 33: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

33

So we now have ericscore increasing. You can pause the program at any point and inspect eric.

Here we can see that the ericscore property has been increasing and is sitting at a value of 219.

So its not that difficult to create a property of eric that updates the score. The harder part is how do we use the Score actor to display this?

First we have to modify DodgeWorld.

Normally when we want to add a new actor with a world we add the following

The problem with the above is once its created we cant reference it again from any other object. We have to create a reference to it so that we can access it again.

To do this we have to modify DodgeWorld.

ericscore++;

addObject(new Score(),70,380);

Page 34: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

34

First we create a property that will allow us to keep a reference to our Score actor.

This is the same as how we kept the score and turnspeed above.

We still cant do

As this doesn’t allow us to reference the Score object we created, but we can modify it slightly.

First we will create a new Score object and store a reference to it in our property thescore.

Then we will add this object by passing this variable.

We can access this property directly but its better practice to create a method to return it

public class DodgeWorld extends World { public Score thescore;

addObject(new Score(),70,380);

thescore = new Score("Score",0); addObject(thescore,70,380);

Page 35: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

35

Previously we have only seen public void methodname, but a method can return any type. Here we have a method returning a Score object.

This then allows us to access the score from any other actor.

You might be tempted to try the following

Try it and see what message you get.

You should see a message like “cannot find symbol – method getScore()”

This is because getScore() is not a method of World, but is a method of a child world called DodgeWorld. We are going to introduce a technique called casting.

Casting : Casting is used when you, as the developer, have a reference to an object of type ClassA, but you know that the object type is actually of type ClassB, where ClassB extends ClassA.

Sounds difficult, but basically it allows you to convince the java compiler that your object is of another type.

So we want to tell have the getWorld() act like it return a DodgeWorld rather than a World.

public Score getScore() { return thescore; }

World mycurrentworld = getWorld(); Score myscore = mycurrentworld.getScore(); score.setScore("Score",ericscore);

DodgeWorld mycurrentworld = (DodgeWorld)getWorld(); Score myscore = mycurrentworld.getScore(); // get a reference to the counter myscore.setScore("Score",ericscore);

Page 36: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

36

So getWorld() normally returns something of type World, but in our case we are overwriting this and saying it actually returns a DodgeWorld type.

If you have added the above we can now see an increasing score. There is a problem if we try and access new worlds, as the new world will not be of type DodgeWorld. I will add the code for this but not go into much details on it.

Basically this tests the current world and sees if it is a particular world or not.

We have one other problem. The score is lost when we create DodgeWorld2. We could modify the constructor of this to accept the current score score.

So DodgeWorld2 would look like the following:

And modify the code within eric to

So instead of

if (DodgeWorld.class.isInstance(getWorld())) { DodgeWorld mycurrentworld = (DodgeWorld)getWorld(); Score score = mycurrentworld.getScore(); // get a reference to the

counter score.setScore("Score",ericscore);

} if (DodgeWorld2.class.isInstance(getWorld())) {

DodgeWorld2 mycurrentworld = (DodgeWorld2)getWorld(); Score score = mycurrentworld.getScore(); // get a reference to the

counter score.setScore("Score",ericscore);

}

public class DodgeWorld2 extends World { public Score thescore; public Score getScore() { return thescore; } public DodgeWorld2(int currentscore) { super(600, 400, 1); thescore = new Score("Score",currentscore); addObject(thescore,70,380); addObject(new Eric(),20,20); addObject(new GreenBlock(3),302,162); addObject(new GreenBlock(-2),402,162); addObject(new Home(),546,364);

Actor home; home = getOneIntersectingObject(Home.class); if (home != null) { // we win! Greenfoot.setWorld(new DodgeWorld2(ericscore)); }

Page 37: Introduction to Greenfoot Part1fionawcs.weebly.com/.../introduction_to_greenfoot_part1.pdf · 2018-09-10 · Press run and add an instance of a Lobster to your scenario. Does it do

37

We have

Greenfoot.setWorld(new DodgeWorld2());