這個程式就不多作解釋了,所有的觀念前面都講過了,繪圖時使用迴圈走訪陣列,所以深度問題也自然獲得解決,連結 看看效果。
- 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>

