Ghost.java
/*
* Copyright © 2012 Nokia Corporation. All rights reserved.
* Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
* Oracle and Java are trademarks or registered trademarks of Oracle and/or its
* affiliates. Other product and company names mentioned herein may be trademarks
* or trade names of their respective owners.
* See LICENSE.TXT for license information.
*/
package com.nokia.example.ghosts;
import java.io.IOException;
import java.util.Random;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
/**
* This class implements ghost behavior.
*
* The ghost sets its position on the screen and waits for some time
* to allow the player to aim and shoot. During the waiting period the ghost moves a little.
* When the ghost is shot and hit, it changes its appearance for a little while before
* it is repositioned. After a successful hit the waiting period is reduced to
* increase difficulty.
*/
public class Ghost
{
private Size parentSize;
private Image ghostImage;
private Image ghostShotImage;
private Point ghostPosition = new Point();
private Size ghostSize = new Size();
private final long initialGhostRelocationPeriod = 10000; //ms
private long ghostRelocationPeriod = 0; //ms
private long lastGhostRelocationTime = 0;
private final int ghostJitterLimit = 10;
private int ghostJitterPosition = 0;
private int ghostJitterDirection = 1;
private boolean shot = false;
private Random rand;
public Ghost(Size parentSize) throws IOException
{
this.parentSize = parentSize;
this.ghostImage = Image.createImage("/images/Ghost.png");
this.ghostShotImage = Image.createImage("/images/GhostShot.png");
this.rand = new Random(System.currentTimeMillis());
this.ghostRelocationPeriod = this.initialGhostRelocationPeriod;
this.ghostSize.width = this.ghostImage.getWidth();
this.ghostSize.height = this.ghostImage.getHeight();
}
public void paint(Graphics graphics)
{
// Draw the ghost
if (!this.shot)
{
graphics.drawImage(
this.ghostImage,
this.ghostPosition.x + ghostJitterPosition,
this.ghostPosition.y,
Graphics.TOP | Graphics.LEFT
);
}
else
{
graphics.drawImage(
this.ghostShotImage,
this.ghostPosition.x,
this.ghostPosition.y,
Graphics.TOP | Graphics.LEFT
);
}
}
/**
* Sets ghost's shot status.
* When a ghost is shot, its appearance changes. The image of the shot ghost stays
* on the screen for a short time before it is repositioned.
*/
public void setShot(boolean shot)
{
this.shot = shot;
// Plan ghost relocation to one second from now
this.lastGhostRelocationTime = (System.currentTimeMillis() - this.ghostRelocationPeriod) + 1000;
// Reduce relocation period to increase difficulty
if (this.ghostRelocationPeriod > 1500)
{
this.ghostRelocationPeriod -= 500;
}
}
/**
* Returns the percentage of the waiting period used already.
*/
public int getPercentOfTimeUsed()
{
return (int)(100 *
(double)(System.currentTimeMillis() - this.lastGhostRelocationTime) / (double)this.ghostRelocationPeriod
);
}
/**
* This method should be called periodically from the game's world-clock handler.
*/
public boolean handleClockTick()
{
boolean relocated = false;
if ((System.currentTimeMillis() - this.lastGhostRelocationTime) > this.ghostRelocationPeriod)
{
// Waiting time has elapsed. Relocate the ghost.
if (!this.shot)
{
// Ghost was not hit - reset waiting time to initial value.
this.ghostRelocationPeriod = this.initialGhostRelocationPeriod;
}
this.shot = false;
this.relocateGhost();
this.lastGhostRelocationTime = System.currentTimeMillis();
relocated = true;
}
// Update the ghost's jittering position to let it move in
// small range from left to right.
if (this.ghostJitterPosition > this.ghostJitterLimit)
{
this.ghostJitterDirection = -1;
}
else if (this.ghostJitterPosition < -1 * this.ghostJitterLimit)
{
this.ghostJitterDirection = 1;
}
this.ghostJitterPosition += this.ghostJitterDirection;
return relocated;
}
/**
* Checks whether the given point is inside of the ghost's rectangle.
*/
public boolean hitTest(int x, int y)
{
return (x > this.ghostPosition.x)
&& (x < this.ghostPosition.x + this.ghostSize.width)
&& (y > this.ghostPosition.y)
&& (y < this.ghostPosition.y + this.ghostSize.height);
}
private void relocateGhost()
{
int newPosX = this.ghostSize.width
+ this.rand.nextInt(this.parentSize.width - 3 * this.ghostSize.width);
int newPosY = this.ghostSize.height / 5
+ this.rand.nextInt(this.parentSize.height - 6 * this.ghostSize.height / 5);
this.ghostPosition.x = newPosX;
this.ghostPosition.y = newPosY;
}
}