迷宮(斜角地圖實例)


這個程式就不多作解釋了,所有的觀念前面都講過了,繪圖時使用迴圈走訪陣列,所以深度問題也自然獲得解決,連結 看看效果。
  • Maze25D.java
package cc.openhome;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JApplet;

public class Maze25D extends JApplet implements KeyListener {
// 1: Wall 2: Penguin
private int[][] maze = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1},
{1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1},
{1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1},
{1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1},
{1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1},
{1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1},
{1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};

private Image offScreen, lawnImage;
private Image block, floor, character2;
private Sprite25D sprite;
private int halfWidth, halfHeight;
private int startX, startY;
private int characterImageX;
private Graphics gOffScreen;

public void init() {
addKeyListener(this);

setBackground(Color.white);

//取得影像
MediaTracker mediaTracker = new MediaTracker(this);
floor = getImage(getDocumentBase(), "floor.gif");
block = getImage(getDocumentBase(), "block3.gif");
character2 = getImage(getDocumentBase(), "character2.gif");
mediaTracker.addImage(floor, 0);
mediaTracker.addImage(block, 0);
mediaTracker.addImage(character2, 0);

try {
showStatus("影像載入中(Loading Images)...");
mediaTracker.waitForAll();
} catch (InterruptedException e) {
e.printStackTrace();
}

//建立次畫面
lawnImage = createImage(getWidth(), getHeight());
Graphics lawnGraphics = lawnImage.getGraphics();

offScreen = createImage(getWidth(), getHeight());
gOffScreen = offScreen.getGraphics();

halfWidth = floor.getWidth(this) / 2;
halfHeight = floor.getHeight(this) / 2;

startX = getWidth() / 2;
startY = getHeight() / 8;

// 繪製地板
for (int j = 0; j < maze.length; j++) {
for (int i = 0; i < maze[0].length; i++) {
int x = startX - i * halfWidth + j * halfWidth;
int y = startY + i * halfHeight + j * halfHeight;
lawnGraphics.drawImage(floor, x, y, this);
}
}

sprite = new Sprite25D(0, 1, maze);

new Thread() {
public void run() {
while (true) {
repaint();
// 人物走動動畫
characterImageX += 50;
if (characterImageX >= 300) {
characterImageX = 0;
}
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

public void update(Graphics g) {
paint(g);
}

public void paint(Graphics g) {
gOffScreen.drawImage(lawnImage, 0, 0, this);

// 繪製牆與人物
for (int j = 0; j < maze.length; j++) {
for (int i = 0; i < maze[0].length; i++) {
int x = startX - i * halfWidth + j * halfWidth;
int y = startY - 10 + i * halfHeight + j * halfHeight;

if (maze[i][j] == 1) {
gOffScreen.drawImage(block, x, y, this);
}

if (sprite.getX() == j &&
sprite.getY() == i) {
gOffScreen.drawImage(character2,
x, y, x + 25, y + 25,
characterImageX, 0,
characterImageX + 50, 50, this);
}
}
}
//將次畫面貼到主畫面中
g.drawImage(offScreen, 0, 0, this);
}

//=====實作KeyListener介面 =====
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_RIGHT:
sprite.moveUp();
break;
case KeyEvent.VK_LEFT:
sprite.moveDown();
break;
case KeyEvent.VK_UP:
sprite.moveLeft();
break;
case KeyEvent.VK_DOWN:
sprite.moveRight();
break;
}

repaint();
}

public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}

class Sprite25D {
private int i, j;
private int maze[][];

Sprite25D(int x, int y, int[][] maze) {
this.i = y;
this.j = x;
this.maze = maze;
}

void moveUp() {
if (isMovable(i - 1, j)) {
i--;
}
}

void moveDown() {
if (isMovable(i + 1, j)) {
i++;
}
}

void moveRight() {
if (isMovable(i, j + 1)) {
j++;
}
}

void moveLeft() {
if (isMovable(i, j - 1)) {
j--;
}
}

private boolean isMovable(int i, int j) {
if (i < 0 || j < 0 || j >= maze[0].length ||
i >= maze.length) {
return false;
}

if (maze[i][j] == 0) {
return true;
} else {
return false;
}
}

public int getX() {
return j;
}

public int getY() {
return i;
}
}

以下是使用HTML5 Canvas的方式(如果瀏覽器支援HTML5 Canvas,例如最新版的Firexfox、Chrome、IE9等,可以直接將下面的內容存為HTML或按下檔名連結,直接載入瀏覽器執行觀看結果:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=Big5" http-equiv="content-type">
<script type="text/javascript">
window.onload = function() {
var maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1],
[1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1],
[1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1],
[1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1],
[1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1],
[1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1],
[1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]];

function Sprite(x, y, maze) {
var i = y;
var j = x;

function isMovable(i, j) {
if (i < 0 || j < 0 || j >= maze[0].length ||
i >= maze.length) {
return false;
}

if (maze[i][j] == 0) {
return true;
}
return false;
}

this.moveUp = function() {
if (isMovable(i - 1, j)) {
i--;
}
};

this.moveDown = function() {
if (isMovable(i + 1, j)) {
i++;
}
};

this.moveRight = function() {
if (isMovable(i, j + 1)) {
j++;
}
};

this.moveLeft = function() {
if (isMovable(i, j - 1)) {
j--;
}
};

this.getX = function() {
return j;
};

this.getY = function() {
return i;
};
}

var sprite = new Sprite(0, 1, maze);

var character = document.getElementById('character');
var floor = document.getElementById('floor');
var block = document.getElementById('block');
document.body.removeChild(character);
document.body.removeChild(floor);
document.body.removeChild(block);

var canvas1 = document.getElementById('canvas1');
var canvas2 = document.getElementById('canvas2');
var context1 = canvas1.getContext('2d');
var context2 = canvas2.getContext('2d');

document.body.removeChild(canvas2);

var halfWidth = 32 / 2; // 地板圖片寬 32
var halfHeight = 16 / 2; // 地板圖片高 16

var startX = canvas1.width / 2;
var startY = canvas2.width / 8;

var characterImageX = 0;

var context = context2;

// 繪製地板
function drawFloor() {
for(var j = 0; j < maze.length; j++) {
for (var i = 0; i < maze[0].length; i++) {
var x = startX - i * halfWidth + j * halfWidth;
var y = startY + i * halfHeight + j * halfHeight;
context.drawImage(floor, x, y);
}
}
}

// 繪製牆與人物
function drawBlockAndCharacter() {
for(var j = 0; j < maze.length; j++) {
for (var i = 0; i < maze[0].length; i++) {
var x = startX - i * halfWidth + j * halfWidth;
var y = startY - 10 +
i * halfHeight + j * halfHeight;

if(maze[i][j] == 1) {
context.drawImage(block, x, y);
}

if (sprite.getX() == j &&
sprite.getY() == i) {
context.drawImage(character,
characterImageX, 0, 50, 50,
x, y, 25, 25);
}
}
}
}

document.onkeydown = function(event) {
switch (event.which) {
case 39: // 右
sprite.moveUp();
break;
case 37: // 左
sprite.moveDown();
break;
case 38: // 上
sprite.moveLeft();
break;
case 40: // 下
sprite.moveRight();
break;
}
};

setTimeout(function() {
drawFloor();
drawBlockAndCharacter();

if(context === context2) {
document.body.replaceChild(canvas2, canvas1);
context = context1;
}
else {
document.body.replaceChild(canvas1, canvas2);
context = context2;
}

context.clearRect(0, 0, canvas1.width, canvas1.height);

characterImageX += 50;
if (characterImageX >= 300) {
characterImageX = 0;
}

setTimeout(arguments.callee, 250);
}, 250);
};
</script>
</head>
<body>
<canvas id="canvas1" width="600" height="400"></canvas>
<canvas id="canvas2" width="600" height="400"></canvas>
<img id="character" src="images/character2.gif"
style="visibility: hidden"/>
<img id="floor" src="images/floor.gif"
style="visibility: hidden"/>
<img id="block" src="images/block3.gif"
style="visibility: hidden"/>
</body>
</html>