Intro.java
See also
HotSpot.java,
HotSpot_readme
package tiongson.expo;
// Intro.java
import java.applet.Applet;
import java.awt.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.*;
/** Intro.class
* I grant anyone a royalty-free license
* to use this applet or source code for non-commercial
* use ONLY.
*
* This copyright must be included in any copies of this code.
*
* All other rigths reserved. Copyright phillip r. tiongson, 1997.
*
* In other words, if you aren't making money from selling this code
* it is fine to use it. If you are making money, please give me some.
* thanks, if you want to use it, contact me,
* phillip tiongson, at sdallas@mit.edu.
*
* @author Phillip R. Tiongson
* @version 1.0
*/
public class Intro
extends java.applet.Applet
implements java.lang.Runnable
{
public static final String name = "Intro";
public static final String version = "1.0";
public boolean DEBUG = false;
Thread runner;
Image background;
protected MediaTracker tracker;
int[] mouseX = {200, 200, 200, 200, 200}, mouseY = {200, 200, 200, 200, 200};
Vector rects;
/** Performs applet initialization.
*/
public void init()
{
this.setBackground(Color.black);
this.setForeground(Color.white);
if (getParameter("DEBUG") != null) {
dPrint("Debugging is on");
DEBUG = true;
}
offscreensize = size();
rects = new Vector();
parseHTMLFile(rects);
getImages();
showStatus("ready");
}
/** to prevent flicker
*/
public void update (Graphics g) {
paint(g);
}
// These are for the offscreen drawing buffer.
Image offscreen;
Dimension offscreensize;
Graphics offgraphics;
/** This method overrides the paint method. It double buffers the drawing by drawing first
to the offscreen buffer, then blasting it to the Graphics g.
*/
int backX = 0, backY = 0;
boolean initme = true;
public void paint(Graphics g) {
Dimension d = size();
// if no offscreen buffer image, make a new one
if ((offscreen == null) || (d.width != offscreensize.width)
|| (d.height != offscreensize.height)) {
offscreen = createImage(d.width, d.height);
offscreensize = d;
offgraphics = offscreen.getGraphics();
offgraphics.setFont(getFont());
}
if (initme) {
offgraphics.setColor(getBackground());
offgraphics.fillRect(0,0,d.width, d.height);
offgraphics.setColor(Color.red);
offgraphics.drawString("Loading images...please wait.", 20, 20);
g.drawImage(offscreen, 0, 0, this);
return;
}
offgraphics.clipRect(0,0,d.width,d.height);
offgraphics.drawImage(background, backX, backY, this);
for(Enumeration e = rects.elements(); e.hasMoreElements();) {
((HotSpot) e.nextElement()).paint(offgraphics, backX, backY, DEBUG);
}
// Blast image to Graphics g.
g.drawImage(offscreen, 0, 0, this);
}
/** The main entry point for the applet.
*/
public void start()
{
repaint();
if (runner == null)
{
runner = new Thread(this);
runner.start();
}
}
/** Called when you create a new thread with this class.
*/
int decay;
float incrementX = 0, incrementY = 0;
int idleCount = 0;
//int lastX = 0, lastY = 0;
//boolean hit;
HotSpot On;
public void run()
{
//runner.setPriority(Thread.MIN_PRIORITY);
while (Thread.currentThread() == runner) {
try {
runner.sleep(100);
} catch (InterruptedException e) {
System.err.println("insomnia "+e);
};
if (decay == 1) {
if (Math.abs(incrementX) < 1) incrementX = 0;
if (Math.abs(incrementY) < 1) incrementY = 0;
incrementX *= .75f;
incrementY *= .75f;
} if (decay == 0) {
incrementX = -(float)(Math.sin((mouseX[2] - mouseX[0]) * Math.PI/2000.0f) * 100.0f);
incrementY = -(float)(Math.sin((mouseY[2] - mouseY[0]) * Math.PI/2000.0f) * 50.0f);
} if (decay == 2) {
incrementX = 0;
incrementY = 0;
}
// System.out.println("dx = "+backX+ " inc "+incrementX);
backX += (int) incrementX;
backX = (int) Math.min(Math.max(-backW+offscreensize.width, backX), 0);
backY += (int) incrementY;
backY = (int)Math.min(Math.max(-backH+offscreensize.height, backY), 0);
//boolean nohit = true;
if (idleCount > 1) {
if (idleCount < 25) {
for (Enumeration e = rects.elements(); e.hasMoreElements();) {
HotSpot h = (HotSpot) e.nextElement();
if (h.inside(mouseX[4], mouseY[4])) {
dPrint("inside." +idleCount);
On = h;
h.show();
//hit = true;
//nohit = false;
continue;
} // if
h.hide();
} // for
} // if
} // if
//if (nohit) repaint();
dPrint("idle = "+idleCount);
if (idleCount < 0) {
/*
for (Enumeration e = rects.elements(); e.hasMoreElements();) {
HotSpot h = (HotSpot) e.nextElement();
h.hide();
} //for
*/
if (On != null) On.hide();
} // if
idleCount++;
//if (!((lastX == backX) && (lastY == backY) && !hit)) {
repaint();
//hit = false;
//}
//lastX = backX;
//lastY = backY;
}
}
/** Stops the applet from executing.
*/
public void stop()
{
if (runner != null)
{
runner.stop();
runner = null;
}
}
/** Free up any applet resources.
*/
public void destroy()
{
background = null;
for (Enumeration e = rects.elements(); e.hasMoreElements(); ) {
((HotSpot) e.nextElement()).image = null;
}
}
/** Returns a text description of the applet.
*/
public String getAppletInfo()
{
return name + " version " + version;
}
public boolean handleEvent(Event event) {
switch (event.id) {
case Event.KEY_PRESS:
// Utils.dPrint("Got a key: "+(char)event.key);
switch((char) event.key){
case 'q':
stop();
break;
case 'r':
start();
break;
default:
break;
} // switch
repaint();
return true;
case Event.MOUSE_DOWN:
idleCount = -1;
mouseX[0] = event.x;
mouseY[0] = event.y;
decay = 2;
dPrint("mouse down (x,y): ("+mouseX[0]+","+mouseY[0]+")");
return true;
case Event.MOUSE_UP:
idleCount = -1;
mouseX[1] = event.x;
mouseY[1] = event.y;
if ((mouseX[1] == mouseX[0]) && (mouseY[1] == mouseY[0])) {
mouseX[3] = mouseX[1] - backX;
mouseY[3] = mouseY[1] - backY;
for (Enumeration e = rects.elements(); e.hasMoreElements();) {
HotSpot h = (HotSpot) e.nextElement();
if (h.inside(mouseX[3], mouseY[3])) {
dPrint("got it.");
h.openHREF(this);
// repaint();
break;
}
}
dPrint("Clicked at abs ("+mouseX[3]+","+mouseY[3]+").");
decay = 2;
} else {
decay = 1;
}
mouseX[2] = mouseX[0];
mouseY[2] = mouseX[0];
return true;
case Event.MOUSE_DRAG:
idleCount = -1;
mouseX[2] = event.x;
mouseY[2] = event.y;
decay = 0;
dPrint("mouse drag (x,y): ("+mouseX[2]+","+mouseY[2]+")");
return true;
case Event.MOUSE_MOVE:
// To fix netscape bug, netscape produces erroneous Mouse_move messages.
if ((mouseX[4] == (event.x - backX)) && (mouseY[4] == (event.y - backY))) {
//System.out.println("breaking");
break;
}
idleCount = -1;
mouseX[4] = event.x - backX;
mouseY[4] = event.y - backY;
dPrint("mouse move (x,y): ("+mouseX[4]+","+mouseY[4]+")");
return true;
} // switch
return super.handleEvent(event);
} // handleEvent
private void parseHTMLFile(Vector destination) {
Vector nodes = new Vector();
int number = Integer.parseInt(getParameter("NumberOfNodes"));
for (int i = 0; i < number; i++) {
String value = getParameter("Node"+i);
if (value != null) { nodes.addElement(value); }
else { System.err.println("The parameters for Node "+i+" were missing");}
} // for
for (Enumeration e = nodes.elements(); e.hasMoreElements(); ) {
String text = (String) e.nextElement();
StringTokenizer parser = new StringTokenizer(text, ",;");
boolean absolute = false;
boolean newBrowser = false;
boolean sound = false;
String url = "";
int x = 0;
int y = 0;
Rectangle rect = null;
Polygon poly = null;
URL href = null;
Image image = null;;
try {
String value = parser.nextToken();
if (value.equals("1")) {absolute = true; dPrint("Absolute. "); }
if (value.equals("2")) {sound = true; dPrint("sound. "); }
if (parser.nextToken().equals("1")) {newBrowser = true; dPrint("newBrowser. "); }
url = parser.nextToken();
if (!url.equals("none")) {
href = new URL(getDocumentBase(), url);
dPrint("HREF = "+url+" "+href);
}
url = parser.nextToken();
if (!url.equals("none")) {
URL imageLoc = new URL(getDocumentBase(), url);
image = getImage(imageLoc);
dPrint("IMAGEURL = "+url+" "+image);
} // if
x = Integer.parseInt(parser.nextToken());
y = Integer.parseInt(parser.nextToken());
int numberLeft = parser.countTokens();
if (numberLeft > 4) {
poly = new Polygon();
for (int i = 0; i < numberLeft/2; i++) {
poly.addPoint(Integer.parseInt(parser.nextToken()), Integer.parseInt(parser.nextToken()));
}
} else {
int x1 = Integer.parseInt(parser.nextToken());
int y1 = Integer.parseInt(parser.nextToken());
int w = Math.abs(x1 - Integer.parseInt(parser.nextToken()));
int h = Math.abs(y1 - Integer.parseInt(parser.nextToken()));
rect = new Rectangle(x1, y1, w, h);
}
if (poly != null) {
destination.addElement(new HotSpot(absolute, newBrowser, sound, href, image, x, y, poly));
dPrint("added a poly");
} else {
destination.addElement(new HotSpot(absolute, newBrowser, sound, href, image, x, y, rect));
dPrint("added a rect");
}// else
} // try
catch (MalformedURLException mue) { System.err.println("This is not a good url: "+url); }
catch (NoSuchElementException nsee) { System.err.println("not enough tokens in: "+text); }
catch (NumberFormatException mie) { System.err.println("Number not corrent "+mie); }
} // for
} // parseHTML
int backW = 1, backH = 1;
private void getImages() {
String toOpen = "background.jpg";
String tempP = getParameter("background");
if (tempP != null) toOpen = tempP;
background = getImage(getDocumentBase(), toOpen);
tracker = new MediaTracker(this);
int i = 0;
tracker.addImage(background, i);
i++;
for (Enumeration e = rects.elements(); e.hasMoreElements(); i++) {
HotSpot h = (HotSpot) e.nextElement();
if (h.image == null) continue;
// Image temp = getImage(h.imageLoc);
tracker.addImage(h.image, i);
}
try {
tracker.waitForAll();
} // try
catch (InterruptedException e) {
System.err.println("Got interrupted while waiting.");
showStatus("Can't read images.");
} // catch
if (tracker.isErrorID(0)) {
System.err.println("We can't get the background image sorry.");
showStatus("Can't read background image, sorry.");
} // if
initme = false;
backW = background.getWidth(this);
backH = background.getHeight(this);
} // getImages
private static Random r = new Random();
/** returns a random int from 0 to i.
if you pass it a 1, it returns 0 half the time and 1 the other half.
Also, if i = -1, it computes +1 or -1 for you.
*/
public static int RandomInt(int i) {
int range = Math.round((i * r.nextFloat()));
//dPrint("int: "+i+"\t got: "+range);
if ((i == -1) && (range == 0)) {
//dPrint("+1 :-)");
return 1;
}
return range;
}
/** A private method to print debug statements
*/
private void dPrint(String s) {
if ( DEBUG == true )
System.out.println(s);
} // dPrint
} // Intro