home *** CD-ROM | disk | FTP | other *** search
- //////////////////////////////////////////////////////////////////////////
- //
- // サンプルプログラム3「15パズル 改良版2」
- // 分割イメージの自動作成 完成度アップ
- // Programmed By T.Tanabe
- //
- // BGMと画像の著作権: ⒞Aris Multimedia Entertainment, Inc. 1993
-
-
- // 各種インポート
- import java.applet.*;
- import java.awt.*;
- import java.util.Random;
- import java.awt.image.CropImageFilter;
- import java.awt.image.FilteredImageSource;
- import java.awt.image.ImageFilter;
-
- // メインアプレット
- public class Puzzle15 extends Applet implements Runnable {
- String sPuzzleFile = "DefaultPict"; // 指定の無いときのファイル名
- int iMoveCnt = 0;
- AudioClip auClick, auBgm;
- Thread thread = null;
- PuzzleCanvas PCanvas;
- Label lblMoveCnt;
-
- // 起動直後の初期化処理
- public void init() {
- String s;
-
- // パラメータの指定がある場合、ファイル名を変更する
- if ((s = getParameter("file")) != null) { sPuzzleFile = s; };
-
- PCanvas = new PuzzleCanvas();
-
- // イメージの読み込み&設定
- showStatus("Now Data Loading ...");
- MediaTracker mt = new MediaTracker(this);
- Image img = getImage(getDocumentBase(), "Images/"+sPuzzleFile+".gif");
- mt.addImage(img, 0);
- try {
- mt.waitForID(0);
- } catch(InterruptedException e) return;
- PCanvas.setImage(img);
-
- // サウンドの設定
- auBgm = getAudioClip(getDocumentBase(), "Sounds/BGM.au");
- auClick = getAudioClip(getDocumentBase(), "Sounds/Click.au");
-
- // 画面下部のカウント表示&ニューゲームボタンの設定
- lblMoveCnt = new Label("Move Count = 0", Label.LEFT);
- Panel pnl = new Panel();
- pnl.setLayout(new GridLayout(1,2, 100, 0));
- pnl.add(lblMoveCnt);
- pnl.add(new Button("New Game"));
-
- setLayout(new BorderLayout());
- add("Center", PCanvas);
- add("South", pnl);
- }
-
- // アプレット周囲の空白設定(インセット)
- public Insets insets() {
- return new Insets(10, 10, 10, 10);
- }
-
- // アプレット開始&再開
- public void start() {
- if (thread == null) {
- thread = new Thread(this);
- thread.start();
- }
- }
-
- // スレッド実行
- public void run() {
- if (auBgm != null) auBgm.loop();
- }
-
- // アプレット一時停止
- public void stop() {
- if (thread != null) {
- auBgm.stop();
- thread.stop();
- thread = null;
- }
- }
-
- //アクションイベントの処理
- public boolean action(Event evt, Object what) {
- if (evt.target instanceof Button) {
- // New Gameボタンが押されたらゲームを初期状態にする
- PCanvas.InitAll();
- PCanvas.repaint();
- lblMoveCnt.setText("Move Count = 0");
- iMoveCnt = 0;
- showStatus("");
- return true;
- }
- return false;
- }
-
- // マウスダウンイベントの処理
- public boolean mouseDown(Event evt, int x, int y) {
- if (evt.target instanceof PuzzleCanvas && PCanvas.bClear == false) {
- // マウスダウンがパズルエリアに対して発生(ゲーム中のみ)
- int mx = x / PuzzleCanvas.PARTS_SIZE,
- my = y / PuzzleCanvas.PARTS_SIZE;
-
- int bx = PCanvas.getBlinkX(), by = PCanvas.getBlinkY();
- if ((mx == bx || my == by) && (mx - bx + my - by) != 0) {
- // X,Yのどちらか一方が一致したとき
- while(mx - bx + my - by != 0) {
- // 移動可能な限りブランクを移動する
- if (mx < bx) PCanvas.MoveBlink(PuzzleCanvas.LEFT);
- else if (mx > bx) PCanvas.MoveBlink(PuzzleCanvas.RIGHT);
- else if (my < by) PCanvas.MoveBlink(PuzzleCanvas.UP);
- else if (my > by) PCanvas.MoveBlink(PuzzleCanvas.DOWN);
- bx = PCanvas.getBlinkX(); by = PCanvas.getBlinkY();
- }
- PCanvas.repaint();
- iMoveCnt = iMoveCnt + 1;
- lblMoveCnt.setText("Move Count = " + iMoveCnt);
- auClick.play();
- // クリアチェック
- if (PCanvas.isClear()) {
- PCanvas.GameClear();
- showStatus("Game Clear!!");
- }
- return true;
- }
- }
- return false;
- }
- }
-
- // パズルキャンバス用のクラス
- class PuzzleCanvas extends Canvas {
- // 定数定義
- static final int UP = 0;
- static final int RIGHT = 1;
- static final int DOWN = 2;
- static final int LEFT = 3;
- static final int PARTS_SIZE = 60;
- static final int PUZZLE_SIZE = 4;
- static final int PARTS_MAX = PUZZLE_SIZE * PUZZLE_SIZE;
-
- static Random random = new Random();
- Rectangle rc = new Rectangle(0, 0,
- PARTS_SIZE * PUZZLE_SIZE, PARTS_SIZE * PUZZLE_SIZE);
- Image imgOrignal, imgParts[] = new Image[PARTS_MAX];
- int iArea[] = new int[PARTS_MAX];
- int iBlink;
- boolean bClear;
- boolean bFirstDraw = true;
-
- // コンストラクタ
- PuzzleCanvas() {
- InitAll();
- }
-
- public int getBlinkX() { return iBlink % PUZZLE_SIZE; }
- public int getBlinkY() { return iBlink / PUZZLE_SIZE; }
- public int indexToX(int n) { return n % PUZZLE_SIZE; }
- public int indexToY(int n) { return n / PUZZLE_SIZE; }
-
- // パズルのイメージをセットするメゾット
- public void setImage(Image img) {
- imgOrignal = img;
- ImageFilter cropImg;
- Graphics g;
- MediaTracker mt = new MediaTracker(this);
- for (int i = 0; i < PARTS_MAX; i++) {
- cropImg = new CropImageFilter(indexToX(i) * PARTS_SIZE,
- indexToY(i) * PARTS_SIZE, PARTS_SIZE, PARTS_SIZE);
- imgParts[i] = createImage(new FilteredImageSource(
- img.getSource(), cropImg));
- mt.addImage(imgParts[i], 1);
- }
- try {
- mt.waitForID(1);
- } catch(InterruptedException e) return;
- }
-
- // 再描画のオーバーライト
- public void update(Graphics g) {
- g.clipRect(rc.x, rc.y, rc.width, rc.height);
- paint(g);
- bFirstDraw = true;
- }
-
- // 描画処理
- public void paint(Graphics g) {
- g.drawImage(imgOrignal, 250, 0, 120, 120, this);
- for (int i = 0; i < PARTS_MAX; i++) drawParts(g, i);
- }
-
- // パズルのパーツを1つ描画する
- public void drawParts(Graphics g, int pos) {
- int x = indexToX(pos) * PARTS_SIZE,
- y = indexToY(pos) * PARTS_SIZE;
-
- if (pos != iBlink || bClear)
- g.drawImage(imgParts[iArea[pos]], x, y, this);
-
- if (bClear == false) {
- if (pos != iBlink)
- g.drawRect(x, y, PARTS_SIZE - 1, PARTS_SIZE - 1);
- else
- g.fillRect(x, y, PARTS_SIZE, PARTS_SIZE);
- }
- }
-
- //全て初期化
- public void InitAll() {
- for (int i = 0; i < PARTS_MAX; i++) iArea[i] = i;
- iBlink = Math.abs(random.nextInt() % PARTS_MAX);
- Shafull();
- bClear = false;
- bFirstDraw = true;
- rc.reshape(0, 0, PARTS_SIZE * PUZZLE_SIZE + 130, PARTS_SIZE * PUZZLE_SIZE);
- }
-
- // パズルパーツをシャッフルする
- public void Shafull() {
- for (int i = 0; i < 500; i++)
- MoveBlink(Math.abs(random.nextInt() % 4));
- }
-
- // ブランクカーソルの移動処理
- public void MoveBlink(int iDir) {
- int movOfs[] = {-PUZZLE_SIZE, 1, PUZZLE_SIZE, -1};
-
- if (isMoveOK(iDir)) {
- if (bFirstDraw) {
- // 表示後、始めの描画はクリップのための初期設定
- bFirstDraw = false;
- rc.reshape(getBlinkX() * PARTS_SIZE,
- getBlinkY() * PARTS_SIZE, PARTS_SIZE, PARTS_SIZE);
- } else {
- // 2回目以降は、以前の範囲に追加
- rc.add(new Rectangle(getBlinkX() * PARTS_SIZE,
- getBlinkY() * PARTS_SIZE, PARTS_SIZE, PARTS_SIZE));
- }
- int tmp = iArea[iBlink + movOfs[iDir]];
- iArea[iBlink + movOfs[iDir]] = iArea[iBlink];
- iArea[iBlink] = tmp;
- iBlink = iBlink + movOfs[iDir];
- rc.add(new Rectangle(getBlinkX() * PARTS_SIZE,
- getBlinkY() * PARTS_SIZE, PARTS_SIZE, PARTS_SIZE));
- }
- }
-
- // ブランクカーソルの指定方向が移動可能か調べる
- boolean isMoveOK(int dir) {
- switch(dir) {
- case LEFT: return getBlinkX() != 0;
- case RIGHT: return getBlinkX() != (PUZZLE_SIZE - 1);
- case UP: return getBlinkY() > 0;
- case DOWN: return getBlinkY() < (PUZZLE_SIZE - 1);
- }
- return false;
- }
-
- // パズルが完成したかどうかを調べる
- public boolean isClear() {
- for (int i = 0; i < PARTS_MAX; i++) {
- if (iArea[i] != i) return false;
- }
- return true;
- }
-
- // パズルが完成したときの処理
- public void GameClear() {
- bClear = true;
- rc.reshape(0, 0, PARTS_SIZE * PUZZLE_SIZE, PARTS_SIZE * PUZZLE_SIZE);
- repaint();
- }
- }
-
-