技术开发 频道

Java中2.5D游戏八方走法实现原理及相关代码

  在本系列博文在后面会涉及到此部分,在这里先给出一个基本概念。

  首先,要转换坐标为斜45度时位置,至少需要以下参数。

  1、mapX(地图X坐标)

  2、mapY(地图Y坐标)

  3、mapMaxY (Y轴的最大纵深)

  4、tileWidth(每块小图宽度)

  5、tileHeight(每块小图高度)

  而后我们才可以根据基础参数换算坐标位置:

  screenX (屏幕坐标X)

  screenY (屏幕坐标Y)

  screenX = (mapX - mapY + mapMaxY) * (tileWidth / 2);

  screenY = (mapX + mapY) * (tileHeight / 2);

  bevelMapX (倾视的X坐标)

  bevelMapY (倾视的Y坐标)

  bevelMapX = ((screenY / tileHeight) + (screenX - (mapMaxY * tileWidth/2)) / tileWidth);

  bevelMapY = ((screenY / tileHeight) - (screenX - (mapMaxY * tileWidth/2)) / tileWidth);

  这时得到的bevelMapX及bevelMapY,就是斜45度时的绘图位置,以此坐标绘制准备好的斜视图,就自然会呈现在斜视情况下的X,Y点位置上。

  由于本例中为非等距实现,也就是在2D地图上直接位移角色单元到斜点,故此不需要额外的进行地图坐标换算处理,但是人物坐标则需偏移。

  下面开始我们用代码示例说话:

  Role.java(负责描述一个角色单元的行为)

  1 package org.loon.game.simple.alldirection.rpg;
  2 import java.awt.Color;
  3 import java.awt.Graphics;
  4 import java.util.List;
  5 import org.loon.game.simple.alldirection.GraphicsUtils;
  6 public class Role implements Config {
  7     private static final int SPEED = 4;
  8     public static final double PROB_MOVE = 0.02;
  9     private int x, y;
10     private int px, py;
11     private int direction;
12     private int count;
13     private boolean isMoving;
14     private int movingLength;
15     private int moveType;
16     private String message;
17     private Thread threadAnime;
18     private RpgSprite sprite;
19     private RpgMap map;
20     private String name;
21     private String partyName;
22     private int ioffsetX;
23     private int ioffsetY;
24     private boolean autoFinder;
25     private boolean isLoop;
26     public Role(String fileName, int x, int y, int direction, int moveType,
27             RpgMap map) {
28         sprite = new RpgSprite(fileName);
29         this.x = x;
30         this.y = y;
31         px = x * CS;
32         py = y * CS;
33         ioffsetX = sprite.getImageWidth() - CS;
34         ioffsetY = sprite.getImageHeight() - CS;
35         this.direction = direction;
36         this.count = 0;
37         this.moveType = moveType;
38         this.map = map;
39         this.roleLoop();
40     }
41     private void roleLoop() {
42         isLoop = true;
43         threadAnime = new Thread(new AnimationThread());
44         threadAnime.start();
45     }
46     public void stop() {
47         isLoop = false;
48         threadAnime = null;
49     }
50     public void setXandY(Cell2D cell) {
51         setXandY(cell.x(), cell.y());
52     }
53     public void setXandY(int x, int y) {
54         this.x = x;
55         this.y = y;
56     }
57     public Cell2D getCell2D() {
58         return new Cell2D(x, y);
59     }
60     private synchronized void redress() {
61         if (autoFinder) {
62             move();
63         }
64         if (px < 0) {
65             px = 0;
66         }
67         if (py < 0) {
68             py = 0;
69         }
70         if (px > map.getWidth() - CS) {
71             px = map.getWidth() - CS;
72             x = map.getRow() - 1;
73         }
74         if (py > map.getHeight() - CS) {
75             py = map.getHeight() - CS;
76             y = map.getCol() - 1;
77         }
78     }
79     public synchronized void draw(Graphics g, int offsetX, int offsetY) {
80         redress();
81         int aspect = 0;
82         switch (direction) {
83         case UP:
84             aspect = RpgSprite.UPPER_RIGHT;
85             break;
86         case DOWN:
87             aspect = RpgSprite.LOWER_LEFT;
88             break;
89         case LEFT:
90             aspect = RpgSprite.UPPER_LEFT;
91             break;
92         case RIGHT:
93             aspect = RpgSprite.LOWER_RIGHT;
94             break;
95         case TUP:
96             aspect = RpgSprite.UP;
97             break;
98         case TDOWN:
99             aspect = RpgSprite.DOWN;
100             break;
101         case TLEFT:
102             aspect = RpgSprite.LEFT;
103             break;
104         case TRIGHT:
105             aspect = RpgSprite.RIGHT;
106             break;
107         }
108         int nx = px + offsetX - ioffsetX;
109         int ny = py + offsetY - ioffsetY;
110         g.drawImage(sprite.getMove(aspect)[count], nx, ny, null);
111         if (name != null) {
112             int fontHeight = g.getFontMetrics().getHeight();
113             int nameFontWidth = g.getFontMetrics().stringWidth(name);
114             int size = 20;
115             int mx = nx + ioffsetX - nameFontWidth / 2;
116             int my = ny + ioffsetY + size + fontHeight;
117             GraphicsUtils.drawStyleString(g, name, mx, my, Color.black,
118                     Color.white);
119             GraphicsUtils.drawStyleString(g, partyName, mx, my + size,
120                     Color.black, Color.white);
121         }
122     }
123     public synchronized void autoDirection(List startPath) {
124         Cell2D cell1 = (Cell2D) startPath.get(0);
125         try {
126             if (startPath.size() > 1) {
127                 Cell2D cell2 = (Cell2D) startPath.get(1);
128                 int sx = cell2.x() - cell1.x();
129                 int sy = cell2.y() - cell1.y();
130                 direction = Field2D.getDirection(sx, sy);
131             }
132         } finally {
133             startPath.remove(0);
134         }
135     }
136     public synchronized boolean move() {
137         switch (direction) {
138         case LEFT:
139             if (moveLowerLeft()) {
140                 return true;
141             }
142             break;
143         case RIGHT:
144             if (moveLowerRight()) {
145                 return true;
146             }
147             break;
148         case UP:
149             if (moveUpperRight()) {
150                 return true;
151             }
152             break;
153         case DOWN:
154             if (moveUpperLeft()) {
155                 return true;
156             }
157             break;
158         case TLEFT:
159             if (moveLeft()) {
160                 return true;
161             }
162             break;
163         case TRIGHT:
164             if (moveRight()) {
165                 return true;
166             }
167             break;
168         case TUP:
169             if (moveUp()) {
170                 return true;
171             }
172             break;
173         case TDOWN:
174             if (moveDown()) {
175                 return true;
176             }
177             break;
178         }
179         return false;
180     }
181     protected boolean moveLeft() {
182         int nextX = x - 1;
183         int nextY = y;
184         if (nextX < 0) {
185             nextX = 0;
186         }
187         if (!map.isHit(nextX, nextY)) {
188             px -= Role.SPEED;
189             movingLength += Role.SPEED;
190             if (movingLength >= CS) {
191                 x--;
192                 px = x * CS;
193                 isMoving = false;
194                 return true;
195             }
196         } else {
197             isMoving = false;
198             px = x * CS;
199             py = y * CS;
200         }
201         return false;
202     }
203     protected boolean moveRight() {
204         int nextX = x + 1;
205         int nextY = y;
206         if (nextX > map.getCol() - 1) {
207             nextX = map.getCol() - 1;
208         }
209         if (!map.isHit(nextX, nextY)) {
210             px += Role.SPEED;
211             movingLength += Role.SPEED;
212             if (movingLength >= CS) {
213                 x++;
214                 px = x * CS;
215                 isMoving = false;
216                 return true;
217             }
218         } else {
219             isMoving = false;
220             px = x * CS;
221             py = y * CS;
222         }
223         return false;
224     }
225     protected boolean moveUp() {
226         int nextX = x;
227         int nextY = y - 1;
228         if (nextY < 0) {
229             nextY = 0;
230         }
231         if (!map.isHit(nextX, nextY)) {
232             py -= Role.SPEED;
233             movingLength += Role.SPEED;
234             if (movingLength >= CS) {
235                 y--;
236                 py = y * CS;
237                 isMoving = false;
238                 return true;
239             }
240         } else {
241             isMoving = false;
242             px = x * CS;
243             py = y * CS;
244         }
245         return false;
246     }
247     protected boolean moveDown() {
248         int nextX = x;
249         int nextY = y + 1;
250         if (!map.isHit(nextX, nextY)) {
251             py += Role.SPEED;
252             movingLength += Role.SPEED;
253             if (movingLength >= CS) {
254                 y++;
255                 py = y * CS;
256                 isMoving = false;
257                 return true;
258             }
259         } else {
260             isMoving = false;
261             px = x * CS;
262             py = y * CS;
263         }
264         return false;
265     }
266     protected boolean moveLowerLeft() {
267         int nextX = x - 1;
268         int nextY = y - 1;
269         if (nextX < 0) {
270             nextX = 0;
271         }
272         if (nextY < 0) {
273             nextY = 0;
274         }
275         if (!map.isHit(nextX, nextY)) {
276             px -= Role.SPEED;
277             py -= Role.SPEED;
278             movingLength += Role.SPEED;
279             if (movingLength >= CS) {
280                 x--;
281                 px = x * CS;
282                 y--;
283                 py = y * CS;
284                 isMoving = false;
285                 return true;
286             }
287         } else {
288             isMoving = false;
289             px = x * CS;
290             py = y * CS;
291         }
292         return false;
293     }
294     protected boolean moveLowerRight() {
295         int nextX = x + 1;
296         int nextY = y + 1;
297         if (nextX > map.getRow() - 1) {
298             nextX = map.getRow() - 1;
299         }
300         if (nextY > map.getCol() - 1) {
301             nextY = map.getCol() - 1;
302         }
303         if (!map.isHit(nextX, nextY)) {
304             px += Role.SPEED;
305             py += Role.SPEED;
306             movingLength += Role.SPEED;
307             if (movingLength >= CS) {
308                 x++;
309                 px = x * CS;
310                 y++;
311                 py = y * CS;
312                 isMoving = false;
313                 return true;
314             }
315         } else {
316             isMoving = false;
317             px = x * CS;
318             py = y * CS;
319         }
320         return false;
321     }
322     protected boolean moveUpperLeft() {
323         int nextX = x - 1;
324         int nextY = y + 1;
325         if (nextX < 0) {
326             nextX = 0;
327         }
328         if (nextY > map.getCol() - 1) {
329             nextY = map.getCol() - 1;
330         }
331         if (!map.isHit(nextX, nextY)) {
332             px -= Role.SPEED;
333             py += Role.SPEED;
334             movingLength += Role.SPEED;
335             if (movingLength >= CS) {
336                 x--;
337                 px = x * CS;
338                 y++;
339                 py = y * CS;
340                 isMoving = false;
341                 return true;
342             }
343         } else {
344             isMoving = false;
345             px = x * CS;
346             py = y * CS;
347         }
348         return false;
349     }
350     protected boolean moveUpperRight() {
351         int nextX = x + 1;
352         int nextY = y - 1;
353         if (nextX > map.getRow() - 1) {
354             nextX = map.getRow() - 1;
355         }
356         if (nextY < 0) {
357             nextY = 0;
358         }
359         if (!map.isHit(nextX, nextY)) {
360             px += Role.SPEED;
361             py -= Role.SPEED;
362             movingLength += Role.SPEED;
363             if (movingLength >= CS) {
364                 x++;
365                 px = x * CS;
366                 y--;
367                 py = y * CS;
368                 isMoving = false;
369                 return true;
370             }
371         } else {
372             isMoving = false;
373             px = x * CS;
374             py = y * CS;
375         }
376         return false;
377     }
378     /**
379      * 触发事件
380      *
381      * @return
382      */
383     public Role talkWith() {
384         int nextX = 0;
385         int nextY = 0;
386         switch (direction) {
387         case LEFT:
388             nextX = x - 1;
389             nextY = y;
390             break;
391         case RIGHT:
392             nextX = x + 1;
393             nextY = y;
394             break;
395         case UP:
396             nextX = x;
397             nextY = y - 1;
398             break;
399         case DOWN:
400             nextX = x;
401             nextY = y + 1;
402             break;
403         }
404         Role chara;
405         chara = map.getRoles().roleCheck(nextX, nextY);
406         if (chara != null) {
407             switch (direction) {
408             case LEFT:
409                 chara.setDirection(RIGHT);
410                 break;
411             case RIGHT:
412                 chara.setDirection(LEFT);
413                 break;
414             case UP:
415                 chara.setDirection(DOWN);
416                 break;
417             case DOWN:
418                 chara.setDirection(UP);
419                 break;
420             }
421         }
422         return chara;
423     }
424     public int getX() {
425         return x;
426     }
427     public int getY() {
428         return y;
429     }
430     public int getPx() {
431         return px;
432     }
433     public int getPy() {
434         return py;
435     }
436     public void setDirection(int dir) {
437         direction = dir;
438     }
439     public synchronized boolean isMoving() {
440         return isMoving;
441     }
442     public synchronized void setMoving(boolean flag) {
443         isMoving = flag;
444         movingLength = 0;
445     }
446     public String getMessage() {
447         return message;
448     }
449     public void setMessage(String message) {
450         this.message = message;
451     }
452     public int getMoveType() {
453         return moveType;
454     }
455     private class AnimationThread extends Thread {
456         public void run() {
457             while (isLoop) {
458                 if (count < sprite.getSize()) {
459                     count++;
460                 } else {
461                     count = 0;
462                 }
463                 try {
464                     Thread.sleep(300);
465                 } catch (InterruptedException e) {
466                 }
467             }
468         }
469     }
470     public boolean isAutoFinder() {
471         return autoFinder;
472     }
473     public void setAutoFinder(boolean autoFinder) {
474         this.autoFinder = autoFinder;
475     }
476     public int getIoffsetX() {
477         return ioffsetX;
478     }
479     public int getIoffsetY() {
480         return ioffsetY;
481     }
482     public String getName() {
483         return name;
484     }
485     public void setName(String name) {
486         this.name = name;
487     }
488     public String getPartyName() {
489         return partyName;
490     }
491     public void setPartyName(String partyName) {
492         this.partyName = partyName;
493     }
494 }
495
0
相关文章