import java.awt.*; import java.awt.image.*; //画像を扱うクラスをインポート import java.applet.AudioClip; //音声を扱うクラスをインポート import java.awt.event.*; import java.applet.*; public class Puzzle9 extends Applet implements MouseListener { int appWidth; int appHeight; Image orgimg; Image image[]; int data[]; int xp[]; int yp[]; int status; int movefr; int count; boolean b1_flag; boolean b2_flag; AudioClip drag; AudioClip good; AudioClip shuffle; AudioClip reset; Image offimg; Graphics offscr; final int MS = 3; //マスの数(一辺の) final int MSS = 50; //マスのサイズ final int AKI = 8; //空いている増すの数(画像を読み込むマス) final Font FONT1 = new Font("Dialog", Font.BOLD, 20); final Font FONT2 = new Font("Courier", Font.BOLD, 16); final Font FONT3 = new Font("Courier", Font.BOLD, 24); public void init() { appWidth = getSize().width; //アプレットのサイズを取得 appHeight = getSize().height; image = new Image[MS*MS]; //イメージを分割する数 data = new int[MS*MS]; //データの数 for (int i = 0 ; i < MS*MS ; i++) { data[i] = i; } status = 0; //ステータスの初期化 count = 0;//カウント(ボタンをクリックした数)の初期化 b1_flag = true;//ボタン1の初期化 b2_flag = true; //ボタン2の初期化 xp = new int[MS*MS]; //x座標の配列 yp = new int[MS*MS]; //y座標の配列 int cell = 0; for (int i = 0 ; i < MS ; i++) { for (int j = 0 ; j < MS ; j++) { xp[cell] = (20+1) + ((MSS+1)*j); //左20空けてマスのx座標を指定 yp[cell] = (30+1) + ((MSS+1)*i); //上30空けてマスのy座標を指定 cell++; } } String param = null; param = getParameter("tani.jpg"); //画像読み込み if (param != null) { orgimg = getImage(getDocumentBase(), param); } else { orgimg = makeDefalut(); //画像データがなかったらmakeDefalut()をイメージにする } makeImages(); drag = getAudioClip(getDocumentBase(), "drag.au"); //音声データを読み込む good = getAudioClip(getDocumentBase(), "good.au"); shuffle = getAudioClip(getDocumentBase(), "shuffle.au"); reset = getAudioClip(getDocumentBase(), "reset.au"); if (drag != null) drag.play(); //音声を再生 if (drag != null) drag.stop(); if (good != null) good.play(); if (good != null) good.stop(); if (shuffle != null) shuffle.play(); if (shuffle != null) shuffle.stop(); if (reset != null) reset.play(); if (reset != null) reset.stop(); setBackground(new Color(200,200,255)); //背景色を指定 offimg = createImage(appWidth, appHeight); //スクリーンのイメージ offscr = offimg.getGraphics(); //スクリーンに描画するためのオブジェクト addMouseListener(this);//MouseListenerをアプレット自身に登録 } public void paint(Graphics g) { offscr.setColor(getBackground()); offscr.fillRect(0,0, appWidth, appHeight); offscr.setColor(Color.white); //タイトルを書いている(色を白に指定) offscr.setFont(FONT1); offscr.drawString("9 Matrix Puzzle", 70,20); offscr.setColor(Color.gray); for (int i = 0 ; i <= MS ; i++) { offscr.drawLine(20,30+(MSS+1)*i, 20+(MSS+1)*MS,30+(MSS+1)*i); //マス目(線で)を書いている offscr.drawLine(20+(MSS+1)*i,30, 20+(MSS+1)*i,30+(MSS+1)*MS); } for (int i = 0 ; i < MS*MS ; i++) { //イメージをマス内に表示 if (data[i] == AKI) { offscr.setColor(Color.lightGray); offscr.fillRect(xp[i],yp[i], MSS,MSS); } else { offscr.drawImage(image[data[i]],xp[i],yp[i], this); } } offscr.setColor(Color.black); //クリック回数を表示 offscr.setFont(FONT2); offscr.drawString("COUNT: " + Integer.toString(count), 190,114); if (status == 2 && cmpData() == true) {//完成したらGood!!を表示 offscr.setColor(Color.magenta); offscr.setFont(FONT3); offscr.drawString("Good!!", 190,142); } offscr.setColor(Color.pink); //ボタン1の状態を指定 offscr.fill3DRect(190,30, 85,54, b1_flag); offscr.setColor(Color.black); offscr.setFont(FONT2); int offset1 = b1_flag ? 0 : 1; offscr.drawString(" Start ", (198 + offset1),(46 + offset1)); offscr.drawString(" & ", (198 + offset1),(62 + offset1)); offscr.drawString("Shuffle", (198 + offset1),(78 + offset1)); offscr.setColor(Color.pink); //ボタン2の状態を指定 offscr.fill3DRect(200,158, 60,22, b2_flag); offscr.setColor(Color.black); offscr.setFont(FONT2); int offset2 = b2_flag ? 0 : 1; offscr.drawString("Reset", (208 + offset2),(174 + offset2)); g.drawImage(offimg, 0,0, this); } public void update(Graphics g) { if (status == 1) { //ボタン1でのマウスイベント shuffle(); //シャッフル count = 0; //カウントを0にする if (shuffle != null) shuffle.play(); //シャッフルの音を実行 status = 2; } if (status == 3) { //ボタン2のマウスイベント for (int i = 0 ; i < MS*MS ; i++) { //データを初期化 data[i] = i; } count = 0; //カウントを0にする if (reset != null) reset.play(); //リセットの音を実行 status = 0; //ステータスを0にする } if (status == 4) {//マス目内部のマウスイベント処理 int moveto = 999; if ((movefr % MS) > 0 && data[movefr - 1] == AKI) { //左への処理 data[movefr - 1] = data[movefr]; data[movefr] = AKI; moveto = movefr - 1; } if ((movefr % MS) < MS-1 && data[movefr + 1] == AKI) { //右への処理 data[movefr + 1] = data[movefr]; data[movefr] = AKI; moveto = movefr + 1; } if ((movefr / MS) > 0 && data[movefr - MS] == AKI) { //上への処理 data[movefr - MS] = data[movefr]; data[movefr] = AKI; moveto = movefr - MS; } if ((movefr / MS) < MS-1 && data[movefr + MS] == AKI) { //下への処理 data[movefr + MS] = data[movefr]; data[movefr] = AKI; moveto = movefr + MS; } if (moveto != 999) { if (drag != null) drag.play(); //ドラッグ音を実行 count++; //カウント(クリック回数)を数える if (cmpData()) { //完成したら if (good != null) good.play(); //good音を実行 } } status = 2; } paint(g); } public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (status == 0 || status == 2) { if ( 190 < x && x < (190 + 85) && 30 < y && y < (30 + 54)) { b1_flag = false; } } if (status == 2) { if ( 200 < x && x < (200 + 60) && 158 < y && y < (158 + 22)) { b2_flag = false; } } if (status == 2) { for (int i = 0 ; i < MS*MS ; i++) { if ( xp[i] < x && x < xp[i] + MSS && yp[i] < y && y < yp[i] + MSS) { movefr = i; status = 4; } } } repaint(); return; } public void mouseReleased(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (b1_flag == false) { if ( 190 < x && x < (190 + 85) && 30 < y && y < (30 + 54)) { status = 1; } } if (b2_flag == false) { if ( 200 < x && x < (200 + 60) && 158 < y && y < (158 + 22)) { status = 3; } } b1_flag = true; b2_flag = true; repaint(); return; } public void mouseExited(MouseEvent e) { b1_flag = true; b2_flag = true; repaint(); return; } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public boolean cmpData() { boolean flag = true; for (int i = 0 ; i < MS*MS ; i++) { if (data[i] != i) flag = false; } return flag; } public void shuffle() { //シャッフルする for (int i = 0 ; i < MS*MS ; i++) { data[i] = i; } int aki = AKI; int i = 0; int ii = 100 + (int)(Math.random() * 2); int work; while (i < ii) { switch ((int)(Math.random() * 4)) { case 0: if ((aki / MS) > 0) { work = data[aki]; data[aki] = data[aki - MS]; data[aki - MS] = work; aki = aki - MS; i++; } break; case 1: if ((aki / MS) < (MS - 1)) { work = data[aki]; data[aki] = data[aki + MS]; data[aki + MS] = work; aki = aki + MS; i++; } break; case 2: if (aki % MS > 0) { work = data[aki]; data[aki] = data[aki - 1]; data[aki - 1] = work; aki = aki - 1; i++; } break; case 3: if (aki % MS < (MS - 1)) { work = data[aki]; data[aki] = data[aki + 1]; data[aki + 1] = work; aki = aki + 1; i++; } break; } } } void makeImages() { //イメージの分割 int w = MSS; int h = MSS; for (int i = 0 ; i < MS ; i++) { for (int j = 0 ; j < MS ; j++) { int pixels[] = new int[w * h]; PixelGrabber pg = new PixelGrabber(orgimg, w*j, h*i, w, h, pixels, 0, w); try { pg.grabPixels(); } catch (InterruptedException e) { System.out.println("interrupted waiting for pixels!"); } ImageProducer ip = new MemoryImageSource(w, h, pixels, 0, w); image[(i * MS) + j] = createImage(ip); } } } Image makeDefalut() {//指定したイメージがなかった場合 Image di; Graphics dg; di = createImage((MSS * MS),(MSS * MS)); dg = di.getGraphics(); dg.setColor(Color.lightGray); dg.fillRect(0,0, (MSS * MS),(MSS * MS)); dg.setColor(Color.blue); //フォントカラーは青 dg.setFont(new Font("Courier", Font.BOLD, 46)); char c[] = {'A','B','C','D','E','F','G','H',' '}; //ABCDEFGHをマスに記述 int k = 0; for (int j = 0 ; j < MS ; j++) { for (int i = 0 ; i < MS ; i++) { dg.drawChars(c, k, 1, MSS*i + 10, MSS*j + 42); k++; } } return di; } } |