2014-05-18 4 views
0

J'ai actuellement un problème avec mon code (écrit en Javascript); J'ai des objets qui continuent à remplir au fil du temps. Un exemple d'un objet:Mouvement linéaire entre deux points qui bougent constamment la position

monster.push({ 
range: 200, 
attackSpeed: 500, 
lastFire: 100, 
id: 'ogre', 
speed : 50, 
pos:[canvas.width*Math.random(), canvas.height*Math.random()], 
sprite: new Sprite('images/sheet_characters.png',[508,224],64,64],6,[0]) 

et

hero={ 
attackSpeed: 200, 
lastGetHit: Date.now(), 
lastFire: Date.now(), 
health : 100, 
speed: 256, //pixel/second 
pos:[canvas.width/2,canvas.height/2], 
sprite: new Sprite('images/sheet_characters.png',[256,0],[32,32],8,[0]) }; 

Le champ de position des objets changent assez souvent et je veux ajouter une fonction qui détermine la pente entre le monstre et le héros (nous voulons le monstre tire sur le héros) et l'attaque doit suivre un mouvement linéaire.

Ce que j'ai actuellement

for(var i=0; i<monster.length; i++){ 
     var mob = monster[i]; 
     mob.sprite.update(delta); //animatie 

     var newPos = moveTowards(mob, hero, delta); 
     mob.pos[0] = newPos[0] 
     mob.pos[1] = newPos[1] 
     if(checkBounds(mob.pos,mob.sprite.size)){ 
      monster.splice(i,1); 
     } 
     mobAttacks(mob); 


     var attack = enemyAttacks[i]; //atacks updaten 
     attack.sprite.update(delta); 
     attack.pos[0] = attack.speed * Math.cos(attack.direction))); 
     attack.pos[1] = attack.speed * Math.sin(attack.direction))); 
     if(checkBounds(attack.pos,attack.sprite.sieze)){ 
      enemyAttacks.splice(i,1); 
     } 
    } 

Dans cette boucle for je peux accéder à la position du monstre que les incendies ainsi que la position de héros comme il est une variable globale. Maintenant, la fonction d'attaque est la suivante:

function mobAttacks(object) 
{ 
    var distance = Math.sqrt(Math.pow((hero.pos[0]-object.pos[0]),2) +    Math.pow((hero.pos[1]-object.pos[1]),2)); 
    if(Date.now() - object.lastFire > object.attackSpeed && object.range >= distance) 
    { 
     deltaY = hero.pos[1] - object.pos[1]; 
     deltaX = hero.pos[0] - object.pos[0]; 
     var direction = Math.atan(deltaY/deltaX); 
     enemyAttacks.push({ 

     pos:[(object.pos[0]+object.sprite.size[0]/2), (object.pos[1]+object.sprite.size[1]/2)],      
     direction: direction, 
     speed: 128, //pixel/s 
     sprite: new Sprite('images/sheet_objects.png', [231,3],[24,24],6,[0]) 
     }); 
     object.lastFire = Date.now(); 
    } 
} 

L'angle entre les deux objets est calculée et je fais un nouvel objet (l'attaque) à la position de départ du monstre.

Le résultat est assez étrange:

La pente est hors tension, de même que la position Y du rocher. Aussi, quand le héros est sur le côté gauche du monstre, il n'y a pas de rocher à repérer.

Après quelques heures de bricolage avec le code, je suis arrivé à la conclusion que je ne pouvais pas résoudre mon problème actuel.

EDIT:

attack.pos[0] += attack.speed * Math.cos(attack.direction)*delta; 
attack.pos[1] += attack.speed * Math.sin(attack.direction)*delta; 

résolu le problème que les blocs ne sont coulés plus d'une position aléatoire. Maintenant, l'angle ne devient pas négatif quand je suis dans le 2ème ou 3ème kwadrant (position à gauche vue du point de vue du monstre)

+0

Peut-être une réponse: vous devriez regarder dans la fonction 'Math.atan2' – minopret

+0

je m'attendrais plutôt à attack.pos [0] + = attack.speed * Math.cos (attack.direction))); (+ = au lieu de =). même pour y. – GameAlchemist

Répondre

5

Obtenez tout le trig de votre code, ce n'est pas nécessaire. Laissez

deltaX = hero.pos[0] - object.pos[0]; 
deltaY = hero.pos[1] - object.pos[1]; 

puis

distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); 
deltaX /= distance; 
deltaY /= distance; 

fera <deltaX,deltaY> un vecteur normalisé (une avec une longueur de 1).

Ensuite, vous pouvez mettre à jour la position de l'attaque pour delta temps en utilisant simplement:

attack.pos[0] += attack.speed * attack.deltaX * delta; 
attack.pos[1] += attack.speed * attack.deltaY * delta; 

Si vous n'avez aucune utilité pour la vitesse et la direction séparément, vous pouvez également pré-multiplier speed en deltaX et deltaY lors de l'initialisation de l'attaque, ce qui signifie que la mise à jour ne devient

attack.pos[0] += attack.deltaX * delta; 
attack.pos[1] += attack.deltaY * delta; 

qui est agréable et simple.

+0

Merci beaucoup! Cela fonctionne 100% –