Chapter 3: Collision Detection

Needed Scenarios:

So far we really have not done anything game like. We now add functionality to detect when little red has made it to an apple and remove that apple. With this simple functionality plus a timer, one could create a game to pick some number of apples in the smallest amount of time.

First go ahead and open scenario RedHood3.1. Put one little red in the world and a few apples. Click run and move little red over to get an apple. When you make it to an apple the apple disappears, the message "You won" is printed using System.out.println, and the game stops. Later we will make it so you need to pick some number, say 5, of apples to win.
First, look at the code for the Apple class. (double click on Apple to open the code editing window). As you can see there is no functionality in there, the Apple class exists only to allow apples to be created and put on the screen.
Now look at the code for LittleRed. In the act() method there are two method calls: tryEatApple() and tryMove(). The method tryMove() is not new, it just moves little red around using the keyboard. The method tryEatApple() is new to us.
public void tryEatApple()
{
Actor apple1 = getOneIntersectingObject(Apple.class) ;
if(apple1 != null)
{
getWorld().removeObject(apple1);
Greenfoot.stopSimulation();
System.out.println("YOU WON!");
}
}
The actor method getOneIntersectingObject() returns an object that intersects this object. Here, "this" object is littleRed because the code is inside of the LittleRed class. If you give a parameter of Apple.class to the method call, as above, then the method returns an object of type Apple that intersect. If there is no object that intersects then the method returns null. The value of null means empty, or nothing. So, the next part of the code looks to see if the method returned and apple or not. The following line of code:
if(apple1 != null)
{
}

Checks to see if an apple was returned. If no apple was returned the variable apple1 will be null, and the code in the curly braces after the if statement will not be executed. On the other hand, if an apple did intersect, and hence was returned, the code in the braces is executed so then the apple is removed from the world, the greenfoot game is stopped, and a message of "You won" is printed out using System.out.println().

----------- Begin Exercise 1 ------------------------
Create your own game using the stock Greenfoot actors where you have one class whose movement is controlled by the keyboard and another class whose movement is randomly bouncing around (like littleRedRandom from scenario Redhood2). Make it so that when an object of the first class intersects an object of the second class the game ends. Run your game by creating one object of the first class (keyboard controlled) and many moving objects.
----------- End Exercise 1 ------------------------

If you were making a game to race to the first apple, then having the player place the apples and little red before pushing "run" does not make much sense, as they can always place an apple one spot away from little red. We can create the objects using code instead of having the user create and place them using the greenfoot interface. Open scenario RedHood3.2. The apples and litte red are created for you! If you hit reset, the apples appear in the same spot but little red is in a new spot. In fact, little red appears in a new random spot every time you click reset.
The code for the object creation and placement is found in the RedHood class. Double click on RedHood, found under World, to open up the code editor. First look at the following code:
public RedHood()
{    
// Create a world with 48x48 cells with cell size of 10x10 pixels.
super(48, 48, 10);
setBackground("background.png");
populate();    
}
This code is called a constructor. The method has the same name as the class which is how it is identified as a constructor. A constructor specifies what do do when an object is created. In this case, when a new RedHood world object is created, it sets the grid size to 48x48 cells where each cell is 10x10 pixels. Next, it sets the background to an image named "background.png". You will find this image in the images folder. Finally, the constructor calls the method populate().

The method populate() create objects and places them in the world. Up until now you have created the objects using the Greenfoot toold by right-clicking and placing them in the world with the mouse.
Consider the code:
Apple a1; // declare a variable, name a1, that can hold apples
a1 = new Apple(); // create a new apple and put it in a1
addObject(a1,10,10) ;

The first line declares a varaible named a1 and specifies it is of type Apple. A variable can be thought of as a storage box that can hold only one thing at a time. Further, once specifies what types of objects can be stored . In this case, only objects of type Apple can be stored in variable a1.

The second line of code creates a new apple object and places it into variable a1. The command new is used to create a new object. This is like pressing a cookie cutter down into dough and creating a new cookie.

After the first two lines there is an apple object in variable a1, but it does not show up on the screen in our game because we have not added it to the world. The addObject method, a method of the World class, adds on object to the world. The third line of code above adds the object in variable a1 to the world at cell location 10,10. The next 6 lines of code in RedHood3.2 create three more apple objects and add them at locations (14,14), (18,18), and (22,22).

Now check out the following code:

int tempX ;
int tempY ;

tempX = 26 ;
tempY = 10 ;
a1 = new Apple() ;
addObject(a1, tempX, tempY) ;

The first two lines of this code decare variable tempX and tempY. These variables can only hold integers (whole numbers like 1, 2, 3, -5, -8, etc). The next two lines of code assign 26 and 10 to variables tempX and tempY respectively. Note that the = sign does NOT MEAN EQUALS , instead it means "assign to". The way this works is the value on the right hand side of the equals sign is assigned to the variable on the left hand side. The next line creates a new apple and assigns it to variable a1. Finally, the addObject command place the new apple at the location specified by the contents of variables tempX and tempY, i.e. at location (26,10).

Finally, lets look at the last four lines of code that specify where littleRed is placed:

LittleRed tempLittleRed = new LittleRed();
int randX = Greenfoot.getRandomNumber(50) ;
int randY = Greenfoot.getRandomNumber(50) ;
addObject(tempLittleRed,randX,randY) ;