/** * File: Launcher.java * Author: Brian Borowski * Date created: August 1, 2011 * Date last modified: January 21, 2013 */ import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.util.Timer; import java.util.TimerTask; import javax.swing.JPanel; public class Launcher { public static final int LEFT = 0, RIGHT = 1; public static final int OK = 0, HIT = 1, RECOVERING = 2; private static final Image launcherColorImage, launcherBWImage, explosionImage; private static final int launcherWidth, launcherHeight, xDelta, yDelta; private final int speed, initX, y; private final JPanel parent; private final AudioPlayer audioPlayer; private final Timer timer; private float x; private int state; private boolean isRunning; private long lastLaunchTime; private Image launcherImage; private Object lock; static { // Launcher image courtesy of Ryan Stillings. launcherColorImage = Utility.getImage("images/launcher.png"); launcherBWImage = Utility.getImage("images/launcher_bw.png"); launcherWidth = launcherColorImage.getWidth(null); launcherHeight = launcherColorImage.getHeight(null); explosionImage = Utility.getImage("images/explosion.png"); xDelta = (launcherWidth - explosionImage.getWidth(null)) >> 1; yDelta = (launcherHeight - explosionImage.getHeight(null)) >> 1; } class RecoverTask extends TimerTask { public void run() { while (!isRunning) { synchronized (lock) { try { lock.wait(); } catch (Exception e) { } } } if (state == HIT) { state = RECOVERING; launcherImage = launcherBWImage; x = initX; timer.schedule(new RecoverTask(), 1 * 2000); } else { state = OK; launcherImage = launcherColorImage; } } } public Launcher( final JPanel parent, final int speed, final int x, final int y) { this.parent = parent; this.speed = speed; this.x = initX = x - (launcherWidth >> 1); this.y = y - launcherHeight - (launcherHeight >> 1); isRunning = true; launcherImage = launcherColorImage; audioPlayer = AudioPlayer.getInstance(); timer = new Timer(); lock = new Object(); } public void reset() { this.x = initX; } public void resume() { synchronized (lock) { try { isRunning = true; lock.notify(); } catch (Exception e) { } } } public void pause() { synchronized (lock) { try { isRunning = false; lock.notify(); } catch (Exception e) { } } } public void setHit() { if (state == OK) { state = HIT; launcherImage = explosionImage; audioPlayer.play(AudioPlayer.LAUNCHER_IMPACT); timer.schedule(new RecoverTask(), 1 * 1250); } } public void move(final int direction, final float elapsedSeconds) { if (state != HIT) { final float distance = speed * elapsedSeconds; if (direction == LEFT && x - distance >= -(launcherWidth >> 1)) { x -= distance; } else if (direction == RIGHT && x + distance <= parent.getWidth() - (launcherWidth >> 1)) { x += distance; } } } public Missile generateMissile() { final long launchTime = System.currentTimeMillis(); if (state == OK && launchTime - lastLaunchTime >= 350) { lastLaunchTime = launchTime; audioPlayer.play(AudioPlayer.LAUNCH_MISSILE); return new Missile(400, (int)x + (launcherWidth >> 1), y); } return null; } public Rectangle getBoundingRectangle() { // 7 pixels for the nozzle return new Rectangle((int)x, y + 7, launcherWidth, launcherHeight - 7); } public void paintComponent(final Graphics g) { if (launcherImage != explosionImage) { g.drawImage(launcherImage, (int)x, y, parent); } else { g.drawImage(launcherImage, (int)x + xDelta, y + yDelta, parent); } } }