Maze2
迷路を表示する
Maze2.java
/* appletviewer Maze2.java
*/ import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class Maze2 extends Applet implements KeyListener { Dimension size; Image back; Graphics buffer; double dCenterX; // 中央の座標 double dCenterY; double dBaseX; // 基準長 double dBaseY; int block[][]; int aiX[] = {0, 1, 0, -1}; int aiY[] = {-1, 0, 1, 0}; int iPosX; // 現在地 int iPosY; int iDir; // 方向 0:北 1:東 2:南 3:西 int iMode; // モード 0:移動 1:マップ表示 // 初期処理 public void init() { size = getSize(); back = createImage(size.width, size.height); buffer = back.getGraphics(); dCenterX = size.width / 2.0; dCenterY = size.height / 2.0; dBaseX = size.width * 0.4; dBaseY = size.height * 0.4; block = new int[21][21]; makeMaze(); iPosX = 1; iPosY = 1; iDir = (block[2][1] == 0) ? 1 : 2; iMode = 0; addKeyListener(this); } // 更新 public void update(Graphics g) { paint(g); } // 描画 public void paint(Graphics g) { switch (iMode) { case 0: // 移動 // 背景 buffer.setColor(Color.white); buffer.fillRect(0, 0, size.width, size.height); // 補助線 buffer.setColor(Color.green); buffer.drawLine(0, 0, size.width, size.height); buffer.drawLine(size.width, 0, 0, size.height); // ブロック for (int iDist = 6; 0 <= iDist; iDist--) { int iX = iPosX + iDist * aiX[iDir]; int iY = iPosY + iDist * aiY[iDir]; drawBlock(buffer, iX + aiY[iDir], iY - aiX[iDir], -1, iDist); drawBlock(buffer, iX - aiY[iDir], iY + aiX[iDir], 1, iDist); drawBlock(buffer, iX, iY, 0, iDist); } // 現在地と方向 buffer.setColor(Color.black); buffer.drawString("X:" + iPosX + " Y:" + iPosY + " Dir:" + iDir, 20, 10); break; case 1: // マップ表示 // 背景 buffer.setColor(Color.black); buffer.fillRect(0, 0, size.width, size.height); for (int iY = 0; iY < 21; iY++) { for (int iX = 0; iX < 21; iX++) { if (block[iX][iY] == 1) { buffer.setColor(Color.white); buffer.fillRect(iX * 15, iY * 15, 15, 15); buffer.setColor(Color.blue); buffer.drawRect(iX * 15 + 1, iY * 15 + 1, 13, 13); } } } // スタート・ゴール・現在地 buffer.setColor(Color.blue); buffer.fillRect(1 * 15, 1 * 15, 15, 15); buffer.setColor(Color.red); buffer.fillRect(19 * 15, 19 * 15, 15, 15); buffer.setColor(Color.yellow); buffer.fillRect(iPosX * 15 + 3, iPosY * 15 + 3, 9, 9); break; } g.drawImage(back, 0, 0, this); } public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { int iKeyCode = e.getKeyCode(); if (iKeyCode == KeyEvent.VK_SPACE) { iMode = (iMode == 0) ? 1 : 0; } if (iMode == 0) { switch (iKeyCode) { case KeyEvent.VK_LEFT: // 37 if (--iDir < 0) { iDir = 3; } break; case KeyEvent.VK_UP: // 38 if (getBlock(iPosX + aiX[iDir], iPosY + aiY[iDir]) != 1) { iPosX += aiX[iDir]; iPosY += aiY[iDir]; } break; case KeyEvent.VK_RIGHT: // 39 if (3 < ++iDir) { iDir = 0; } break; case KeyEvent.VK_DOWN: // 40 iDir += 2; if (4 <= iDir) { iDir -= 4; } break; } } repaint(); } public void keyReleased(KeyEvent e) { } // 迷路を作る(棒倒し法) private void makeMaze() { // 全体をクリア for (int iY = 0; iY < 21; iY++) { for (int iX = 0; iX < 21; iX++) { block[iX][iY] = 0; } } // 外枠をセット for (int i = 0; i < 21; i++) { block[0][i] = 1; block[20][i] = 1; block[i][0] = 1; block[i][20] = 1; } // 基準点をセット for (int iY = 1; iY <= 9; iY++) { for (int iX = 1; iX <= 9; iX++) { block[iX * 2][iY * 2] = 1; } } // 迷路作成 for (int iX = 1; iX <= 9; iX++) { for (int iY = 1; iY <= 9; iY++) { boolean flag = true; while(flag) { int d = (int)(Math.random() * ((iX == 1) ? 4 : 3)); if (block[iX * 2 + aiX[d]][iY * 2 + aiY[d]] == 0) { block[iX * 2 + aiX[d]][iY * 2 + aiY[d]] = 1; flag = false; } } } } // スタート・ゴール block[1][1] = 2; block[19][19] = 3; } // ブロックの取得 private int getBlock(int iX, int iY) { if (iX < 0 || 20 < iX) { return -1; } if (iY < 0 || 20 < iY) { return -1; } return block[iX][iY]; } // ブロックの描画 private void drawBlock(Graphics g, int iX, int iY, int iDir, int iDist) { double dX; double dX1; double dY; double dY1; int aiX[] = new int[4]; int aiY[] = new int[4]; // ブロックの取得 int iBlock = getBlock(iX, iY); if (iBlock == 0) { return; } // 座標の計算 if (iDist == 0) { dX = dCenterX + 1; dY = dCenterY + 1; } else { dX = dBaseX * 1.0 / iDist; dY = dBaseY * 1.0 / iDist; } dX1 = dBaseX * 1.0 / (iDist + 1); dY1 = dBaseY * 1.0 / (iDist + 1); // 床 if (iBlock != 1) { aiX[0] = (int)(dCenterX + dX * 2 * iDir - dX); aiY[0] = (int)(dCenterY + dY); aiX[1] = (int)(dCenterX + dX * 2 * iDir + dX); aiY[1] = (int)(dCenterY + dY); aiX[2] = (int)(dCenterX + dX1 * 2 * iDir + dX1); aiY[2] = (int)(dCenterY + dY1); aiX[3] = (int)(dCenterX + dX1 * 2 * iDir - dX1); aiY[3] = (int)(dCenterY + dY1); drawWall(g, aiX, aiY, 4, iBlock); return; } // 側面 if (iDir != 0) { aiX[0] = (int)(dCenterX + dX * iDir); aiY[0] = (int)(dCenterY - dY); aiX[1] = (int)(dCenterX + dX1 * iDir); aiY[1] = (int)(dCenterY - dY1); aiX[2] = (int)(dCenterX + dX1 * iDir); aiY[2] = (int)(dCenterY + dY1); aiX[3] = (int)(dCenterX + dX * iDir); aiY[3] = (int)(dCenterY + dY); drawWall(g, aiX, aiY, 4, iBlock); } // 正面 if (0 < iDist) { double dCenterX2 = dCenterX + dX * 2 * iDir; aiX[0] = (int)(dCenterX2 - dX); aiY[0] = (int)(dCenterY - dY); aiX[1] = (int)(dCenterX2 + dX); aiY[1] = (int)(dCenterY - dY); aiX[2] = (int)(dCenterX2 + dX); aiY[2] = (int)(dCenterY + dY); aiX[3] = (int)(dCenterX2 - dX); aiY[3] = (int)(dCenterY + dY); drawWall(g, aiX, aiY, 4, iBlock); } } // 壁の描画 private void drawWall(Graphics g, int[] aiX, int[] aiY, int iPoints, int iBlock) { switch (iBlock) { case 1: // 壁 g.setColor(Color.white); g.fillPolygon(aiX, aiY, iPoints); g.setColor(Color.black); g.drawPolygon(aiX, aiY, iPoints); break; case 2: // スタート床 g.setColor(Color.blue); g.fillPolygon(aiX, aiY, iPoints); break; case 3: // ゴール床 g.setColor(Color.red); g.fillPolygon(aiX, aiY, iPoints); break; } } }