javafx中的tree_JavaFX中的塔防(2)
javafx中的tree
在最后一部分,我們創(chuàng)建了一個(gè)簡單的編輯器,讓我們放置炮塔。 現(xiàn)在,我們將在敵人起源處添加一個(gè)生成點(diǎn),并為其定義攻擊目標(biāo)。 首先,我將通過對(duì)象層向地圖添加更多信息。 這是標(biāo)準(zhǔn)的TMX,因此我們可以在TileMap編輯器中進(jìn)行操作:
為了計(jì)算敵人的攻擊路徑,我們將使用A *算法,它是tilengine模塊的一部分:
因此,讓我們獲取派生點(diǎn)和目標(biāo)并將其存儲(chǔ)為我們的算法:
ArrayList objectGroups = tileMap.getObjectGroups(); for (ObjectGroup objectGroup : objectGroups) { for (final TObject tObject : objectGroup.getObjectLIst()) { if (tObject.getName().equals("spawnpoint")) {spawnpointX = tObject.getX() / turrets.getTilewidth(); spawnpointY = tObject.getY() / turrets.getTileheight();}if (tObject.getName().equals("target")) {targetX = tObject.getX() / turrets.getTilewidth(); targetY = tObject.getY() / turrets.getTileheight();} } }使用這些值,我們可以初始化A *算法,該算法計(jì)算敵人的最短路徑:
AStar.AStarTile start = new AStar.AStarTile((int) spawnpointX, (int) spawnpointY); AStar.AStarTile end = new AStar.AStarTile((int) targetX, (int) targetY); attackPath = AStar.getPath(tileMap, platformLayer, start, end);為了查看結(jié)果,我們將向GameCanvas添加一個(gè)調(diào)試層:
private class AStarLayer extends Layer { public AStarLayer() { } Color pathColor = Color.rgb(255, 100, 100, .2);@Override public void draw(GraphicsContext graphicsContext, double x, double y, double width, double height) { AStar.PathNode start = attackPath; if (start != null) { graphicsContext.setFill(pathColor); graphicsContext.fillRect(start.getX() * tileMap.getTilewidth(), start.getY() * tileMap.getTileheight(), tileMap.getTilewidth(), tileMap.getTileheight()); while (start.getParent() != null) { start = start.getParent(); graphicsContext.fillRect(start.getX() * tileMap.getTilewidth(), start.getY() * tileMap.getTileheight(), tileMap.getTilewidth(), tileMap.getTileheight()); } } } }結(jié)果看起來像這樣:
您會(huì)看到紅色的最短路徑。 由于該算法沒有“看到”背景圖像的結(jié)構(gòu),因此它會(huì)相應(yīng)地計(jì)算路徑,而敵人只會(huì)忽略船的結(jié)構(gòu)(背景應(yīng)該是宇宙飛船的一部分)。 要解決此問題,我們稍后將添加一些不可見的圖塊。 對(duì)于大型游戲,最好使用不可見的碰撞層,這樣可以為您提供更好的性能,并提供更多方式來實(shí)現(xiàn)鎖定段落。 對(duì)我們而言,transparent-tile-approach更好,因?yàn)槲覀儾恍枰~外的圖層,而且如果用戶可以編輯布局,則更容易。
現(xiàn)在,我們需要將敵人擊倒。 為了給Sprite制作動(dòng)畫,我將動(dòng)畫階段合并為一個(gè)圖像:
現(xiàn)在我們可以使用Tiled編輯器從中創(chuàng)建TileSet:
我還使用Tiled向派生點(diǎn)添加了兩個(gè)附加屬性:
第一個(gè)定義了每種類型我想要產(chǎn)生多少個(gè)敵人,第二個(gè)定義了它們產(chǎn)生之間的停頓時(shí)間。 我懷疑他們會(huì)經(jīng)受住時(shí)間的考驗(yàn),但現(xiàn)在讓我們與他們合作。 在用于讀取對(duì)象組的代碼中,我們可以訪問屬性:
if (tObject.getName().equals("spawnpoint")) {Properties properties = tObject.getProperties(); evaluationInterval = Long.parseLong(properties.getProperty("delay")); spawnpointX = tObject.getX() / turrets.getTilewidth(); spawnpointY = tObject.getY() / turrets.getTileheight();}現(xiàn)在我們只有一種怪獸,所以我們可以忽略它而只使用延遲。 首先,我們將從TileSet中創(chuàng)建一個(gè)SpriteAnimation:
final TileSet enemy1 = tileMap.getTileSet("enemy1"); final TileSetAnimation tileSetAnimation = new TileSetAnimation(enemy1, new int[]{0, 1, 2, 3, 4, 5}, 10f);為了產(chǎn)生怪物,我們將定義一個(gè)行為。 那只是一個(gè)定時(shí)方法調(diào)用。 為了支持Lambda表達(dá)式,可能會(huì)在此處對(duì)API進(jìn)行一些更改:
Behavior monsterSpawnBehavior = new Behavior() { int enemyCount = 0;@Override public boolean perform(GameCanvas canvas, long nanos) { new Sprite(canvas, tileSetAnimation, "enemy" + (enemyCount++), ((int)spawnpointTileX) * tileMap.getTilewidth(), ((int)spawnpointTileY) * tileMap.getTileheight(), 46, 46, Lookup.EMPTY); return false; } }; monsterSpawnBehavior.setEvaluationInterval(evaluationInterval); canvas.addBehaviour(monsterSpawnBehavior);所以現(xiàn)在每隔十億分之一秒,一個(gè)新的敵人就會(huì)被添加到運(yùn)動(dòng)場中。 我們稍后可能會(huì)創(chuàng)建一個(gè)EnemySprite類來封裝Behavior。 但是現(xiàn)在,讓我們繼續(xù)使用此Sprite并向其添加Behavior:
sprite.addBehaviour(new SpriteBehavior() { AStar.PathNode start = attackPath;@Override public boolean perform(Sprite sprite) { double x = sprite.getX(); double y = sprite.getY(); double pathX = start.getX() * tileMap.getTilewidth(); double pathY = start.getY() * tileMap.getTileheight(); if (Math.abs(pathX- x) 1) { sprite.setVelocityX(.5); } else if (pathX- x < -1) { sprite.setVelocityX(-.5); } else { sprite.setVelocityX(0); } if (pathY - y > 1) { sprite.setVelocityY(.5); } else if (pathY - y < -1) { sprite.setVelocityY(-.5); } else { sprite.setVelocityY(0); } return true; } });結(jié)果如下:
現(xiàn)在就這樣。 如您所見,通過Behaviors將AI添加到精靈中非常簡單,AStar非常方便。 在下一部分中,我們將注意敵人指向正確的方向,并向炮塔添加一些“行為”。
翻譯自: https://www.javacodegeeks.com/2013/10/tower-defense-in-javafx-2.html
javafx中的tree
總結(jié)
以上是生活随笔為你收集整理的javafx中的tree_JavaFX中的塔防(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Cloud Gateway
- 下一篇: 引吭大叫的意思是什么 怎么理解引吭大叫的