2016-05-12 7 views
0

Ich habe ein Tower Defense-Spiel eingerichtet und habe es so bekommen, dass du Türme niederlegen kannst und Feinde auf dich zukommen. Aber die Türme fügen allen Monstern in ihrem Radius Schaden zu. Ich will es so, dass die Türme nur einem Feind Schaden zufügen, der sie umgibt.Wie kann man einen Spieler in seinem Radius auf einen Gegner sperren lassen?

Ich habe zwei Variablen eingerichtet: MonsterList und TowerList. Sie sind beide Objekte, und ich habe sie so eingerichtet, dass sie bei einem bestimmten Ereignis der angegebenen Variablen einen Feind oder einen Turm hinzufügen. Wenn Sie also einen leeren Bereich zum Ablegen eines Turms auswählen, wird eine Objektvariable zur Liste hinzugefügt. Dies passiert auch, wenn du auf die nächste Ebene klickst, aber es erzeugt dynamische Monster, die sich durch den Pfad bewegen können. Es sieht ein bisschen wie folgt aus:

//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; 

Also, das ist, wie ich die Monster und auf die gleiche Weise, aber mit unterschiedlichen Argumenten schaffen, für einen Turm. Wenn ein Monster den Pfad verlässt und in die Reichweite des Turms gelangt, greift der Turm alle Monster an, die sich in Reichweite befinden. Ich möchte, dass nur 1 Monster innerhalb seiner Reichweite gesperrt wird. Hier ist, wie ich meine Kollision Setup:

//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))); 
} 

Vielen Dank für die Hilfe!

+1

bestehende Antworten scheinen Probleme zu haben. Also, wenn es mehrere in Reichweite gibt, die SIE beschädigen wollen? Der Nächste? Das Neueste? Die gesündeste? Die Schwächsten? –

+0

@GarrGodfreys Frage ist wichtig, bitte beantworten Sie es. Sie müssen ein 'currentTarget' für jeden Turm behandeln und eine' selectTarget' Methode haben, die 'currentTarget' basierend auf Ihrer Auswahlstrategie + dem aktuellen Spielstatus aktualisiert. – GameAlchemist

Antwort

1

Sie brauchen etwas, wie diese auf Ihren Türmen:

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

und dann auf der Schleife:

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]; 
    } 
} 

und Sie auch die Schleife in einer besser lesbaren Art und Weise schreiben können:

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

Yup, das ist ungefähr die gleiche Schlussfolgerung, zu der ich gekommen bin, außer dass ich meinen Vorschlag in C# geschrieben habe. – Ryan

0

Ein Vorschlag, den ich haben könnte, ist, Ihre Turmklasse neu zu entwerfen, um ein Mitglied einzuschließen, das verfolgt, welches Monster das ist Der Turm ist eingeschaltet.

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; 
    } 

Zugegeben, das ist C# -Code, aber die Theorie ist solide. Wenn du deinen Turm dazu zwingst, zu verfolgen, auf welche Monster er zielt, erzwingt er eine Beziehung zwischen Türmen und Monstern.