4.4 Touching Another Actor
Detecting Collisions Between Greenfoot Actors
Unit 4: Loops and Collections of Actors · Lesson 4.4 · about 25 minutes · no coding experience needed
A game where nothing can hit anything else is a screensaver. Collision is one method call, and one piece of syntax that looks strange the first time you meet it.
What you will be able to do
- Detect a collision with isTouching
- Explain what .class means and why it is needed
- Choose between isTouching and getOneIntersectingObject
Words you will need
- .class
- In plain words The class itself, rather than one object of it.
- More precisely A class literal, used to tell a method which type to look for.
- null
- In plain words Nothing there.
- More precisely A reference that points at no object.
Build it step by step
Every step below leaves a scenario that compiles and runs. If you stop halfway you will have something that works, not something broken. Follow along in Greenfoot rather than reading straight through.
-
Step 1
On your screen A player actor overlapping a coin, with the collision detected.
if (isTouching(Coin.class)) { removeTouching(Coin.class); score = score + 1; }The whole coin-collecting mechanic, in four lines.
`isTouching(Coin.class)` hands back true or false, so it drops straight into an if, exactly like isKeyDown did.
`removeTouching(Coin.class)` takes the coin you are overlapping out of the world.
-
Step 2
On your screen The class diagram with Coin highlighted, next to a coin object in the world, illustrating the difference.
Coin.class // the CLASS, the plan new Coin() // an OBJECT, one actual coin`.class` is the strange-looking bit, and it is 1.3 coming back.
You are not asking "am I touching that specific coin". You are asking "am I touching ANY coin", so you have to name the CLASS rather than an object.
Forgetting `.class` and writing `isTouching(Coin)` is a compiler error, and the message will not tell you to add .class.
-
Step 3
On your screen getOneIntersectingObject returning an actor, stored in a variable.
Actor coin = getOneIntersectingObject(Coin.class); if (coin != null) { getWorld().removeObject(coin); }When you need the actual actor rather than just a yes or no, this hands it back.
And when there is nothing there it hands back `null`, which means "nothing". You have to check for that before using it, which is the `!= null` line.
Skip that check and you get the NullPointerException from E-07, because you asked nothing to do something.
Mistakes almost everyone makes here
These are the wrong ideas students actually build at this point. Read them even if you think you understand, because a wrong idea you have not noticed is the expensive kind.
Common wrong idea isTouching(Coin) works without .class.
What is actually true .class is required, and its absence is a compiler error.
Why it matters The error message talks about types and never suggests adding .class.
Common wrong idea getOneIntersectingObject always returns an actor.
What is actually true It returns null when there is nothing there.
Why it matters Using the result without checking is the most common NullPointerException in a game.
Common wrong idea removeTouching removes the actor calling it.
What is actually true It removes what you are touching. You survive.
Why it matters Getting this backwards makes the player vanish on the first coin.
Common wrong idea Collision only counts when the images overlap exactly.
What is actually true Greenfoot uses the image bounds, so a near miss can register as a touch.
Why it matters Explains "it collided when it clearly missed", which otherwise looks like a bug.
Check your understanding
Answer these before moving on. They are graded instantly and you can retry.
-
1. What does `isTouching(Coin.class)` hand back?
-
2. Why is `.class` needed?
-
3. getOneIntersectingObject finds nothing. What does it return?
-
4. Inside Player, what does `removeTouching(Coin.class)` remove?
Fill in the code
When the player touches a spike, remove the spike and lose a life. Fill in the collision checks.
if ((Spike))
{
removeTouching(Spike.class);
lives = lives - 1;
}
Stuck? Open a hint for each blank
- Blank 1: The method that reports whether you are overlapping something.
- Blank 2: The suffix that names the class rather than one object. Include the dot.
Lesson quiz
This one counts toward your progress. Take it when the section above makes sense.
-
1. Which is used when you only need to know whether a collision happened?
-
2. Why must you check for null after getOneIntersectingObject?
-
3. `isTouching(Coin)` without .class:
-
4. An actor seems to collide slightly before the images visually touch. Why?
The short version
- isTouching(Thing.class) answers yes or no and drops into an if.
- removeTouching(Thing.class) removes what you are touching, not you.
- .class names the class rather than one object, and is required.
- getOneIntersectingObject hands back the actor, or null. Always check for null.
If you get stuck
These pages cover the problems that come up most often in this lesson. Opening one is not cheating and it is not counted against you.
Get in Touch
Whether you're a student, parent, or teacher — I'd love to hear from you.
Just want free AP CS resources?
Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.
Message Sent!
Thanks for reaching out. I'll get back to you within 24 hours.
Prefer email? Reach me directly at [email protected]