planemap.htm

来自「电脑图学(Computer Graphics)是资料结构、演算法与数学的应用」· HTM 代码 · 共 148 行

HTM
148
字号
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>







  
  
  
  
  
  
  
  <link rel="stylesheet" href="css/stdlayout.css" type="text/css">







  
  
  
  
  
  
  
  <link rel="stylesheet" href="css/print.css" type="text/css">







  
  
  
  
  
  
  
  <meta content="text/html; charset=gb2312" http-equiv="content-type">







  
  
  
  
  
  
  
  <title>平面地图</title>
</head>


<body>







<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>







<h1><a href="ComputerGraphics.htm">Computer Graphics:&nbsp;平面地图</a></h1>







这边的平面地图所指的是地形没有高低,只有障碍物的地图,人物在遇到障碍物时将无法前进,问题是如何判断障碍物?<br>
<br>
学过资料结构的话,大家应该都知道老鼠走迷宫这个例子,使用阵列,并在当中填入1表示迷宫的墙,0表示可以前进行的格子,而平面地图也是利用这个方式来制作。<br>
<br>
并不是由绘图区域上的障碍物座标来判断人物是否能前进,而是在一个阵列中判断,将阵列元素设定为1表示障碍物,如下所示:<br>







<img style="width: 536px; height: 194px;" alt="" src="images/planeMap-1.jpg"><br>







<br>
利用两个变数(i, j)来表示人物于阵列中的位置,当人物上下左右移动前,先判断下一个位置是否为0,如果是才可以前进(改变i, j的值),否则就停留在原地。 <br>
<br>
在绘图时,只要根据阵列将指定的图片一格格绘制上去就可以了,如下图所示: <br>
<img style="width: 528px; height: 189px;" alt="" src="images/planeMap-2.jpg"><br>
<br>
<br>








当然障碍物并不一定只有一种,您也可以用其它的元素值表示不同的障碍物,例如2表示树木、3表示水池等等;如果地图较大,可以只绘制指定范围的图形,这并不难,指定阵列中的起始与终止范围就可以了,如下图所示: <br>
<img style="width: 536px; height: 193px;" alt="" src="images/planeMap-3.jpg"><br>
<br>
这个平面地图的制作方式,可以使用于俯视、斜角地图,下面这个程式是个实作的例子,您可以先看看 <a href="maze1.html">效果</a> 程式中使用了事件处理,程式码长了一些,有兴趣的就耐心看完吧! <br>
<ul>
  <li> Maze1.java
  </li>
</ul>

<pre>package onlyfun.caterpillar.graphics.animation;<br> <br>import java.awt.*; <br>import java.awt.event.*;<br>import javax.swing.JApplet;<br> <br>public class Maze1 extends JApplet <br>                          implements KeyListener {<br>    private int appletWidth, appletHeight, <br>                blockWidth, blockHeight;<br>    private Image character, floor, block1, block2;<br>    private Image backGround, offScreen; <br> <br>    private Graphics drawOffScreen; <br>    private SpriteAndMaze spriteAndMaze; <br> <br>    private int[][] <br>           maze = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, <br>                   {0,0,0,0,0,1,0,0,2,0,0,1,1,0,0,0,2,2}, <br>                   {2,0,1,0,1,0,0,0,2,0,1,0,0,1,1,0,2,2}, <br>                   {2,0,0,0,0,0,1,1,2,0,1,0,1,0,0,0,0,2}, <br>                   {2,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,2}, <br>                   {2,1,0,1,0,1,1,0,1,1,0,0,1,0,0,0,0,2}, <br>                   {2,1,0,0,0,0,1,0,0,2,0,0,0,0,2,0,2,2}, <br>                   {2,1,0,0,2,0,1,1,1,2,0,1,0,0,2,0,1,2}, <br>                   {2,1,1,1,1,0,0,0,1,2,0,0,0,0,1,0,0,2}, <br>                   {2,0,0,0,0,0,0,0,1,0,0,1,1,0,2,1,0,2}, <br>                   {2,0,2,0,1,0,0,0,1,0,1,0,0,0,0,0,0,2}, <br>                   {2,1,2,0,0,0,1,1,1,0,1,0,1,1,2,1,0,2}, <br>                   {2,0,0,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0}, <br>                   {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}; <br>    <br>    private int characterImIndexX, characterImIndexY;<br>    private int characterWidth, characterHeight;<br> <br>    public void init() { <br>        addKeyListener(this);  <br> <br>        setBackground(Color.white); <br>      <br>        //取得Applet的高度、宽度<br>        appletWidth  = getSize().width; <br>        appletHeight = getSize().height;  <br> <br>        //取得影像 <br>        MediaTracker mediaTracker = new MediaTracker(this); <br>        character = <br>              getImage(getDocumentBase(),"character.gif"); <br>        floor = getImage(getDocumentBase(),"floor.jpg");          <br>        block1 = getImage(getDocumentBase(),"block1.gif"); <br>        block2 = getImage(getDocumentBase(),"block2.gif"); <br>        mediaTracker.addImage(character,0); <br>        mediaTracker.addImage(floor,0); <br>        mediaTracker.addImage(block1,0); <br>        mediaTracker.addImage(block2,0); <br>      <br>        try { <br>            showStatus("影像载入中(Loading Images)..."); <br>            mediaTracker.waitForAll(); <br>        } <br>        catch(InterruptedException e){ <br>            e.printStackTrace();<br>        } <br>      <br>        spriteAndMaze = new SpriteAndMaze(0, 1, maze);<br>        <br>        blockWidth = appletWidth / maze[0].length;<br>        blockHeight = appletHeight / maze.length;<br>        characterWidth = character.getWidth(this)/3;<br>        characterHeight = character.getHeight(this)/4;<br>        characterImIndexY = characterHeight;<br>        <br>        //建立次画面 <br>        offScreen = createImage(appletWidth, appletHeight);<br>        drawOffScreen = offScreen.getGraphics(); <br> <br>        // 建立地图<br>        backGround = createImage(appletWidth, appletHeight);<br>        Graphics g = backGround.getGraphics();<br>        // 绘地版<br>        for(int i = 0; i &lt; maze.length; i++) {<br>            for(int j = 0; j &lt; maze[0].length; j++) {<br>                g.drawImage(floor, j*blockWidth, <br>                             i*blockHeight, blockWidth, <br>                             blockHeight, this);<br>            }<br>        }<br>        // 绘障碍物        <br>        for(int i = 0; i &lt; maze.length; i++) { <br>            for(int j = 0; j &lt; maze[0].length; j++) {<br>                switch(maze[i][j]) {<br>                    case 1:<br>                        g.drawImage(block1, j*blockWidth, <br>                            i*blockHeight, blockWidth, <br>                            blockHeight, this);<br>                        break;<br>                    case 2:<br>                        g.drawImage(block2, j*blockWidth, <br>                            i*blockHeight, blockWidth, <br>                            blockHeight, this);<br>                        break;<br>                    default:<br>                        g.drawImage(floor, <br>                            j*blockWidth, i*blockHeight,<br>                            blockWidth, blockHeight, this);<br>                }<br>            }<br>        }<br>    } <br> <br>    public void paint(Graphics g) {<br>        // 在背后绘地图<br>        drawOffScreen.drawImage(backGround, 0, 0, this);<br>        // 贴人物<br>        drawOffScreen.drawImage(character, <br>                spriteAndMaze.getLocationX()*blockWidth, <br>                spriteAndMaze.getLocationY()*blockHeight, <br>                (spriteAndMaze.getLocationX()+1)*blockWidth, <br>                (spriteAndMaze.getLocationY()+1)*blockHeight,<br>                 characterImIndexX, <br>                 characterImIndexY,<br>                 characterImIndexX+characterWidth, <br>                 characterImIndexY+characterHeight,<br>                 this);<br>        <br>        //将次画面贴到主画面中 <br>        g.drawImage(offScreen, 0, 0,this); <br>    } <br> <br>    public void update(Graphics g) { <br>        paint(g);                      <br>    } <br>    <br>   //=====实作KeyListener介面 =====<br>    <br>    public void keyTyped(KeyEvent e)  { } <br> <br>    public void keyPressed(KeyEvent e) { <br>        int key = e.getKeyCode(); <br>    <br>        characterImIndexX = <br>                 characterImIndexX + characterWidth;<br>        <br>        switch(key) {<br>            case KeyEvent.VK_RIGHT:<br>                spriteAndMaze.moveRight();<br>                characterImIndexY = characterHeight;<br>                break;<br>            case KeyEvent.VK_LEFT:<br>                spriteAndMaze.moveLeft();<br>                characterImIndexY = characterHeight * 3;<br>                break;<br>            case KeyEvent.VK_UP:<br>                spriteAndMaze.moveUp();<br>                characterImIndexY = 0;<br>                break;<br>            case KeyEvent.VK_DOWN:<br>                spriteAndMaze.moveDown();<br>                characterImIndexY = characterHeight * 2;<br>                break;<br>        }<br>        <br>        if(characterImIndexX &gt;= character.getWidth(null))<br>            characterImIndexX = 0;<br>        <br>        repaint();<br>    } <br> <br>    public void keyReleased(KeyEvent e) {} <br>}  <br> <br>class SpriteAndMaze { <br>    private int i, j; <br>    private int maze[][];  <br>    <br>    public SpriteAndMaze() {}<br>    <br>    public SpriteAndMaze(int x, int y) { <br>        this.i = y; <br>        this.j = x; <br>    }<br>    <br>    public SpriteAndMaze(int x, int y, int[][] maze) {<br>        this(x, y); <br>        this.maze = maze;      <br>    } <br> <br>    public void moveUp() { <br>        if(isMovable(i-1, j)) { <br>            i--; <br>        } <br>    } <br> <br>    public void moveDown() { <br>        if(isMovable(i+1, j)) { <br>            i++; <br>        } <br>    } <br> <br>    public void moveRight() { <br>        if(isMovable(i, j+1)) { <br>            j++; <br>        }<br>    } <br> <br>    public void moveLeft() { <br>        if(isMovable(i, j-1)) { <br>            j--; <br>        } <br>    } <br> <br>    private boolean isMovable(int i, int j) {<br>        if(i &lt; 0 || j &lt; 0 || <br>           j &gt;= maze[0].length || i &gt;=maze.length)<br>            return false;<br>        <br>        if(maze[i][j] == 0)<br>            return true;<br>        else<br>            return false;<br>    }<br>    <br>    public int getLocationX() {<br>        return j;<br>    }<br>    public int getLocationY() {<br>        return i;<br>    }<br>    public void setLocationX(int locationX) {<br>        this.j = locationX;<br>    }<br>    public void setLocationY(int locationY) {<br>        this.i= locationY;<br>    }<br>    public int[][] getMaze() {<br>        return maze;<br>    }<br>    public void setMaze(int[][] maze) {<br>        this.maze = maze;<br>    }<br>}</pre>
<br>
<br>







</body>
</html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?