//Puzzle 2.0 by Axel Fontaine 1998 //axel-fontaine@usa.net //http://freezone.exmachina.net/Axel //This is my first java applet! //Feel free to use it as you wish! //If you use it, or if you have any suggestions, I'd love to hear from you ! //Development history //1.0 Initial release //1.1 - Added support for an URL to jump to when the puzzle is completed // Thanks to Joe for the suggestion // - Added support for loading images located at any URL //2.0 - Added support for multiple images (animation) and a delay separating them // Thanks to my dad for the suggestion // - Puzzle doesn't generate any impossible puzzles anymore //Known issues // Applet gets stuck at Loading images when an Image isn't found. //It is distributed under the GNU GPL (www.gnu.org to find a copy). //It is provided "as is" with no warranty of any kind. //I may not be held liable for any damage this software caused. import java.applet.*; import java.awt.*; import java.awt.image.*; import java.lang.Math; import java.lang.Integer; import java.lang.NumberFormatException; import java.util.Random; import java.net.URL; import java.net.MalformedURLException; public class Puzzle extends Applet implements Runnable { int AppletW, AppletH; Thread t; Image[] Bitmaps; URL[] bitmapURL; int CurrentImage; int NumImages = 0; int imageDelay = 200; //Delay between 2 consecutive images boolean Initialized = false; Image offScrImage; Graphics offScrGC; Image[][][] Pieces; int[] PieceW, PieceH; Point[][] RightPos; Point pblack; boolean error = false; boolean completed = false; MediaTracker tracker; URL JumpTo; static final int dirLeft = 0; static final int dirRight = 1; static final int dirUp = 2; static final int dirDown = 3; public String getAppletInfo() { return "Puzzle v2.0, by Axel Fontaine"; } void urlError(String urlType) { String errorMsg = "Puzzle: "+urlType+" URL not found"; showStatus(errorMsg); System.err.println(errorMsg); } public void init() { Dimension d = size(); AppletW = d.width; AppletH = d.height; bitmapURL = new URL[255]; String bitmap = null; do { bitmap = getParameter("IMAGE"+NumImages); if (bitmap != null) { try { bitmapURL[NumImages] = new URL(bitmap); } catch (MalformedURLException e) { try { bitmapURL[NumImages] = new URL(getDocumentBase(),bitmap); } catch (MalformedURLException e2) { urlError("Image"+NumImages); bitmap = null; NumImages--; } } NumImages++; } } while (bitmap != null); System.err.println("Puzzle: Total images:"+NumImages); if (NumImages == 0) { error = true; repaint(); return; } String jump = getParameter("JUMPTO"); try { JumpTo = new URL(jump); } catch (MalformedURLException e) { try { JumpTo = new URL(getDocumentBase(),jump); } catch (MalformedURLException e2) { urlError("Jump To"); } } String delayparam = getParameter("DELAY"); try { Integer dp = new Integer(delayparam); if (dp.intValue() > 0) { imageDelay = dp.intValue(); } } catch (NumberFormatException n) {} offScrImage = createImage(AppletW, AppletH); offScrGC = offScrImage.getGraphics(); offScrGC.setColor(Color.black); } public void start() { if ((t == null) && (!error)) { t = new Thread(this); t.start(); } } public void stop() { if ((t != null) && (!error)) { t.stop(); t = null; } } public void updateOffScreen() { int posx = 0; int posy = 0; for (int i = 0; i<4; i++) { for (int j = 0; j<4; j++) { if ((i == pblack.x) && (j == pblack.y)) { // offScrGC.setColor(Color.black); //already set in init offScrGC.fillRect(posx, posy, AppletW/4, AppletH/4); } else { offScrGC.drawImage(Pieces[CurrentImage][RightPos[i][j].x][RightPos[i][j].y], posx, posy, AppletW/4, AppletH/4, Color.white, this); } posy += AppletH/4; } posx += AppletW/4; posy = 0; } } public void run() { if (!Initialized) { repaint(); Bitmaps = new Image[NumImages]; MediaTracker tracker = new MediaTracker(this); showStatus("Puzzle: Loading images..."); for (int i=0; i 0) { RightPos[pblack.x][pblack.y] = RightPos[pblack.x-1][pblack.y]; RightPos[pblack.x-1][pblack.y] = p; pblack.x--; illegaldir = dirRight; legal = true; } break; case dirRight: if (pblack.x < (4-1)) { RightPos[pblack.x][pblack.y] = RightPos[pblack.x+1][pblack.y]; RightPos[pblack.x+1][pblack.y] = p; pblack.x++; illegaldir = dirLeft; legal = true; } break; case dirUp: if (pblack.y > 0) { RightPos[pblack.x][pblack.y] = RightPos[pblack.x][pblack.y-1]; RightPos[pblack.x][pblack.y-1] = p; pblack.y--; illegaldir = dirDown; legal = true; } break; case dirDown: if (pblack.y < (4-1)) { RightPos[pblack.x][pblack.y] = RightPos[pblack.x][pblack.y+1]; RightPos[pblack.x][pblack.y+1] = p; pblack.y++; illegaldir = dirUp; legal = true; } break; } } while (!legal); } showStatus(""); Initialized = true; } repaint(); while (true) { try { CurrentImage++; if (CurrentImage == NumImages) { CurrentImage = 0; } updateOffScreen(); repaint(); Thread.sleep(imageDelay); } catch (InterruptedException e) { stop(); } } } public Point posToPuzzle(Point pos) { return new Point(pos.x/(AppletW/4),pos.y/(AppletH/4)); } public void didSucceed() { completed = true; for (int i = 0; i<4; i++) { for (int j = 0; j<4; j++) { if ((RightPos[i][j].x != i) || (RightPos[i][j].y != j)) { completed = false; return; } } } } public boolean mouseDown(Event event, int x, int y) { if (completed || error || (!Initialized)) { return false; } Point ppos; ppos = new Point(x,y); ppos = posToPuzzle(ppos); if (((pblack.y == ppos.y) && ((pblack.x == (ppos.x+1)) || (pblack.x == (ppos.x-1)))) || ((pblack.x == ppos.x) && ((pblack.y == (ppos.y+1)) || (pblack.y == (ppos.y-1))))) { Point tmp = RightPos[ppos.x][ppos.y]; RightPos[ppos.x][ppos.y] = RightPos[pblack.x][pblack.y]; RightPos[pblack.x][pblack.y] = tmp; pblack = ppos; didSucceed(); repaint(); if (completed && (JumpTo != null)) { getAppletContext().showDocument(JumpTo); } } return false; } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { if (error) { g.setColor(Color.black); g.drawString("Error !",10,10); g.drawString("Details on Java Console",10,40); return; } if (completed) { // Scale the big image to the width and height of the applet g.drawImage(Bitmaps[CurrentImage], 0, 0, AppletW, AppletH, Color.black, this); return; } if (Initialized) { g.drawImage(offScrImage, 0, 0, this); } else { g.setColor(Color.black); g.drawString("Loading...",10,25); } } }