2016-05-12 76 views
0

我已經建立了一個塔防遊戲,並已經得到它,所以你可以放下塔樓,敵人來到你身邊。但是,塔樓正在對其半徑內的所有怪物造成傷害。我希望它能讓塔只對周圍的一個敵人造成傷害。如何讓玩家鎖定其半徑內的一個敵人?

我設置了兩個變量:monsterList和towerList。它們都是對象,並且我已經設置好它,以便在某個事件中,它會向指定的變量添加敵人或塔。因此,當您選擇一個空白區域來放置一個塔時,它會將一個對象變量添加到列表中。當你點擊下一級時,這也會發生,但它會創建可以在路徑中移動的動態怪物。它看起來有點像這樣:

//the variables 
var monsterList = {}; 
var towerList = {}; 

//how towers or enemies are added 
var Monster = { 
    x:10, 
    y:10, 
    type:"Red", 
    id:Math.random() 
} 
monsterList[Monster.id] = Monster; 

所以,這就是我創建的怪物,並以同樣的方式,根據不同的參數,對於塔。當一個怪物沿着這條路走下去並進入塔內時,塔會攻擊到達的任何和所有怪物。我希望它只鎖定在1範圍內的怪物。這裏是我的碰撞設置:

//loops through all the monsters and towers and tests if any of them are 
//colliding. If they are colliding, it will decrease the monster's health by 
//1/30 of the tower's damage. This is because I have an interval looping 
//through this code 30 times a second. So, it deals the damage per second. 
for(var key in monsterList){ 

    for(var i in towerList){ 

     if(Collision(towerList[i], monsterList[key])){ 
      monsterList[key].health -= (towerList[i].damage/30); 
     } 

     if(monsterList[key].health <= 0) delete monsterList[key]; 
    } 
} 
//and this is the Collision() function. It pretty much returns true if the 
//monster is within the tower's range which is defined by an argument to the 
//tower called radius. 
function Collision(tower, monster){ 
    return ((monster.y >= (tower.y - tower.radius*20)) && 
    (monster.x >= (tower.x - tower.radius*20)) && 
    (monster.y <= (tower.y + tower.height + tower.radius*20)) && 
    (monster.x <= (tower.x + tower.width + tower.radius*20))); 
} 

謝謝你的幫助!

+1

現有的答案似乎有問題。那麼,如果你想破壞的範圍有多重?最近的?最新的?最健康的?最弱的? –

+0

@GarrGodfrey的問題很重要,請回答。你需要爲每個塔處理一個'currentTarget',並且有一個'selectTarget'方法,根據你的選擇策略+當前的遊戲狀態更新'currentTarget'。 – GameAlchemist

回答

1

你需要在你的塔是這樣的:

var tower = { 
    ... //your tower properties 
    target: null 
} 

,然後在你的循環:

for(var key in monsterList){ 
    for(var i in towerList) { 

     if(!towerList[i].target && Collision(towerList[i], monsterList[key])) { 
      towerList[i].target = key; 
      monsterList[key].health -= (towerList[i].damage/30); 
     } 

     if(towerList[i].target) { 
      monsterList[towerList[i].target].health -= (towerList[i].damage/30); 
     } 

     if(monsterList[key].health <= 0) 
      delete monsterList[key]; 
    } 
} 

,你也可以寫在一個更可讀的方式循環:

monsterList.forEach(function(monster) { 

    towerList.forEach(function(tower) { 
     if (!tower.target && Collision(tower, monster) 
      tower.target = monster 

     if (tower.target) 
      tower.target.health -= tower.damage/30; 

     if (tower.target.health <= 0) { 
      var monsterIndex = monsterList.indexOf(tower.target); 
      delete monsterList[monsterIndex]; 
     } 
    }); 
}); 
+0

是的,除了我在C#中寫下我的建議之外,我得出的結論幾乎相同。 – Ryan

0

我可能會提出的一個建議是重新設計你的塔級,以包含一個跟蹤哪個怪物的成員塔在上。

public void Main() { 
     List<Tower> towers = new List<Tower>(); 
     List<Monster> monsters = new List<Monster>(); 
     foreach(var tower in towers) { 
      if(tower.monsterTargeted==null) {//Find monster in range 
       tower.monsterTargeted=monsters.FindAll(x => GetDistance(tower.location,x.location)<tower.range).OrderBy(x => GetDistance(tower.location,x.location)).FirstOrDefault();//can be null 
      } 
      if(tower.monsterTargeted!=null) {//attack targeted monster 
       DamageMonster(tower.monsterTargeted.MonsterID,tower.damage); 
      } 
     } 
    } 

    private double GetDistance(Point p1,Point p2) { 
     double x = p1.X-p2.X; 
     double y = p1.Y-p2.Y; 
     return Math.Sqrt(x*x+y*y); 
    } 

    private class Monster { 
     public long MonsterID; 
     public Point location; 
    } 

    private class Tower { 
     public Monster monsterTargeted; 
     public Point location; 
     public double range; 
     public double damage; 
    } 

當然,這是C#代碼,但理論是健全的。迫使你的塔追蹤它瞄準的是哪些怪物,從而強化塔與怪物之間的多對一關係。