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: 平面地图</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 < maze.length; i++) {<br> for(int j = 0; j < 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 < maze.length; i++) { <br> for(int j = 0; j < 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 >= 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 < 0 || j < 0 || <br> j >= maze[0].length || i >=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 + -
显示快捷键?