Chapter 5: Other actors and collision
A game needs more than one object. Add a second Actor, place it with addObject,
then ask the player whether it is touching something.
A collectible
Coins, walls, and enemies are all subclasses of Actor. If the object never needs per-tick
logic, override isTickInert() so the world skips act() (cheaper when you have
many tiles). Decorative scenery can also use setStatic(true) so it stays off the debug list.
import ActiverseEngine.*;
public class Coin extends Actor {
public Coin() {
setImage(new ActiverseImage("assets/images/coin.png"));
}
@Override
public void act() {
// no per-tick behavior
}
@Override
public boolean isTickInert() {
return true;
}
}
public class MyWorld extends World {
public MyWorld() {
super(400, 400, 1);
addObject(new Player(), 100, 100);
addObject(new Coin(), 200, 180);
addObject(new Coin(), 280, 90);
}
}
Detecting a hit
Two methods beginners actually use:
intersects(other)— bounding-box overlap with one actor you already have a reference togetOneIntersectingObject()— first other actor whose pixels overlap this one (viaCollisionManager). Returnsnullif nothing hits
Pixel-perfect checks need loaded images. If an image is still missing, collision falls back to boxes.
move() already refuses to walk off the world edge; you do not need extra bounds code for that.
@Override
public void act() {
movementViaKey();
Actor hit = getOneIntersectingObject();
if (hit instanceof Coin) {
playPickup();
getWorld().removeObject(hit);
}
}
removeObject takes the actor out of the world. After that, do not keep using the removed
reference. getWorld() is null-safe to call from act() only while the actor is
still in a world — call it before you remove yourself.
instanceof is the filter
getOneIntersectingObject() returns any overlapping actor, including other players or walls.
Check the type (or a field you add) before you treat it as a coin. For several overlapping objects in one
tick, the method returns the first match; if you need all of them, loop getWorld().getActors()
and test intersects yourself.
for (Actor other : getWorld().getActors()) {
if (other != this && other instanceof Coin && intersects(other)) {
getWorld().removeObject(other);
break;
}
}
Showing a score
World.showText(x, y, "Score: 3") draws a string each frame. Keep a counter on the world or
the player and update the text when a coin disappears.
private int score = 0;
public void addScore(int amount) {
score += amount;
showText(10, 20, "Score: " + score);
}
Call ((MyWorld) getWorld()).addScore(1) from the player when a coin is collected, or keep the
counter on the player and have the world read it. Either is fine for a first game.