Light Racer 2.0 - Days 17-18 - Finished Power Lines

Sometimes finishing the detail work can be the hardest part of completing any project. Games are certainly no exception! My project plan called for me to move forward but instead I decided to take a day to improve sound and finish collisions for everything done to-date. This means that after day 18, there are new sounds in for the decimator, power lines and item pick-ups. I process the sounds myself using audacity but usually the base sounds come from free sound banks online.

Day 17 - What was done:

Added cycling states to power line
Added collision detection to power line
Reduced power line graphic size
Implemented horizontal power line
Found some sounds for power line

The PowerLine class is stateful, in that the powerline always has some state and is counting down to its next state change. At the time of state-switching, the PowerLine picks a random amount of time within a range to switch to the next state. Here's how the update() code that handles states:

@Override
public void update(LightRacerWorld world) {
if (world.gameState == STATE_RUNNING) {
nextActionTimeLeft -= world.tickDelta;
// System.out.println("Action = " + action + ", nextActionTimeLeft = " + nextActionTimeLeft);
if (action == ACTION_NONE) {
// switch to action idle
// determine time to charge
if (nextActionTimeLeft <= 0) {
nextActionTimeLeft = LightRacerWorld.RNG.nextInt(MAX_ZAP_INTERVAL - MIN_ZAP_INTERVAL)
+ MIN_ZAP_INTERVAL;
action = ACTION_IDLE;
}
}
if (action == ACTION_IDLE) {
// on no time left, switch to charge
if (nextActionTimeLeft <= 0) {
action = ACTION_CHARGING;
nextActionTimeLeft = CHARGE_TIME;
gameResources.soundManager.playSound(LightRacerConstants.SOUND_CHARGE_UP);
}
}
if (action == ACTION_CHARGING) {
// animate
// on no time left, switch to zap
if (nextActionTimeLeft <= 0) {
action = ACTION_ZAPPING;
nextActionTimeLeft = LightRacerWorld.RNG.nextInt(MAX_ZAP_TIME - MIN_ZAP_TIME) + MIN_ZAP_TIME;
zapSoundStreamId = gameResources.soundManager.playLoopingSound(LightRacerConstants.SOUND_ZAP, -1);
}
}
if (action == ACTION_ZAPPING) {
if (nextActionTimeLeft <= 0) {
lightningFrameAdvance = 0;
lightningFrame = -1;
action = ACTION_NONE;
gameResources.soundManager.stopLoopingSound(zapSoundStreamId);
zapSoundStreamId = -1;
} else {
// update animation
lightningFrameAdvance -= world.tickDelta;
if (lightningFrameAdvance <= 0) {
lightningFrame++;
if (lightningFrame > gameResources.lightningFrames.length - 1) {
lightningFrame = 0;
}
lightningFrameAdvance = LIGHTNING_ANIMATION_DELAY;
}
}
}
} else {
if (zapSoundStreamId != -1) {
gameResources.soundManager.stopLoopingSound(zapSoundStreamId);
zapSoundStreamId = -1;
}
}
}

What that results in is a slightly unpredictable but comfortable feeling map object that gives a little warning before it zaps. The collision detection code checks the state and uses one big rectangle if its zapping but two smaller rectangles when its not. Here's that code:

public boolean checkCollision(int lastX, int lastY, int curX, int curY) {
int halfSize = size / 2;
int x = this.x;
int y = this.y;
if (action == ACTION_ZAPPING) {
// do big rect
if (isVertical) {
return Collisions.checkRectCollision(curX, curY, x - (HALF_MIN_BOUNDS), y - (halfSize), x
+ (HALF_MIN_BOUNDS), y + (halfSize));
} else {
return Collisions.checkRectCollision(curX, curY, x - (halfSize), y - (HALF_MIN_BOUNDS), x + (halfSize),
y + (HALF_MIN_BOUNDS));
}
} else {
// do two small rects
if (isVertical) {
if (!Collisions.checkRectCollision(curX, curY, x - (HALF_MIN_BOUNDS), y - (halfSize), x
+ (HALF_MIN_BOUNDS), y - (halfSize) + MIN_BOUNDS)) {
return Collisions.checkRectCollision(curX, curY, x - (HALF_MIN_BOUNDS),
y + (halfSize) - MIN_BOUNDS, x + (HALF_MIN_BOUNDS), y + (halfSize));
} else {
return true;
}
} else {
if (!Collisions.checkRectCollision(curX, curY, x - (halfSize), y - (HALF_MIN_BOUNDS), x - (halfSize)
+ MIN_BOUNDS, y + (HALF_MIN_BOUNDS))) {
return Collisions.checkRectCollision(curX, curY, x + (halfSize) - MIN_BOUNDS,
y - (HALF_MIN_BOUNDS), x + (halfSize), y + (HALF_MIN_BOUNDS));
} else {
return true;
}
}
}
}

Day 18 - What was done:

Edited and added sounds
Added better sound management
Sounds -
NPC (ominous hovering sound, lowers in pitch when close to the ground but you can hardly hear it now.)
Power line - nice charge up and electricity sound. I used a garage door and arc welder sample for this.
Item pick-up - standard rising-up sound.

Here's how things looked in the middle of day 18.