Chapter 4: Images and sound
After Chapter 1 you have a player that moves. This chapter is how you give it a picture and a sound without stalling the game loop.
Where files go
ActiverseImage and ActiverseSound both go through ResourcePaths:
an existing file on disk first, then a classpath resource (so a packaged jar still works). Use a relative
path and keep the same folder layout in your IDE and in the jar.
your-project/
Main.java
MyWorld.java
Player.java
assets/
images/
player.png
world.png
coin.png
sounds/
pickup.wav
Load with paths like "assets/images/player.png". Putting files next to your .java
sources also works if that is the working directory; a dedicated assets folder is easier to keep
straight.
A bad image path usually prints ACEHS 2A.IN (Chapter 3).
The debug overlay marks missing images as MIA (Chapter 2).
Images
Supported types include png, jpg, gif, and bmp. Size the file to the actor (a 32×32 character should use a 32×32 image). Set it once in the constructor, not every tick:
public Player() {
setImage(new ActiverseImage("assets/images/player.png"));
}
Worlds use setBackgroundImage("assets/images/world.png"). Backgrounds are optional; without one
you get the panel’s default fill.
Do not call setImage every act() unless you are actually changing frames. Reloading
the same file sixty times a second will hitch.
Sound
ActiverseSound loads WAV files. Construct the clip once, register it on the
world with addSound (so debug and shutdown can see it), then play from a condition — never from
the top of act() with no guard.
import ActiverseEngine.*;
public class Player extends Actor {
private ActiverseSound pickup;
public Player() {
setImage(new ActiverseImage("assets/images/player.png"));
}
public void setPickupSound(ActiverseSound sound) {
pickup = sound;
}
public void playPickup() {
if (pickup != null && !pickup.isPlaying()) {
pickup.play();
}
}
@Override
public void act() {
if (KeyboardInfo.isLetterDown('w')) {
move(5);
}
}
}
public class MyWorld extends World {
public MyWorld() {
super(400, 400, 1);
setBackgroundImage("assets/images/world.png");
Player player = new Player();
addObject(player, 100, 100);
ActiverseSound pickup = new ActiverseSound("assets/sounds/pickup.wav");
addSound(pickup);
player.setPickupSound(pickup);
}
}
Useful methods: play(), stop(), loop(), loop(int count),
pause() / resume(), setVolume(float) (0 to 1),
isPlaying(). Check isPlaying() (or a key edge with
KeyboardInfo.justPressed) so a held key does not restart the clip every tick.
Optional: mouse
Keyboard movement from Chapter 1 is enough for a first game. If you want clicks, call
ActiverseMouseInfo.createInstance(this) in the world constructor (the world is a panel), then
poll isLeftClick() / isRightClick() and
getMouseLocationOnComponent() from act().
Next: Chapter 5 — other actors and collision.