2016-05-12 73 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#代码,但理论是健全的。迫使你的塔追踪它瞄准的是哪些怪物,从而强化塔与怪物之间的多对一关系。