Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 03/03/12 18:55 Sujet du message: [vJass] Mouvement avec arc
Nom de la fonction : CreateProjectile Créateur : Plein de gens je pense
Fonctions requises : Aucune. Il faut cependant utiliser un modèle d'unité pouvant s'incliner que vous pourrez trouver ici pour que ça marche correctement.
Code :
Secret:
Jass:
library CreateProjectile
globals
private constant integer DummyId = 'dumm' //Référence du dummy
private constant real Interval = 0.01 //Interval de temps pour le timer
endglobals
private function interface ImpactProjectile takes unit u, unit c returns nothing
private struct Projectile
unit u
real x
real y
real h
unit c
real speed
real arc
real aarc
unit dum
effect fx
ImpactProjectile func
endstruct
globals
private timer TimProjectile = CreateTimer()
private Projectile array Ar
private integer Total = 0
endglobals
private function Move takes nothing returns nothing
local Projectile ap
local real xc
local real yc
local real xdum
local real ydum
local real hc
local real hdum
local real d
local real dm
local real dp
local real a
local real adum
local real h
local real r
local real x
local real y
local integer i = 0
loop
exitwhen i >= Total
set ap = Ar[i]
set xc = GetUnitX(ap.c)
set yc = GetUnitY(ap.c)
set xdum = GetUnitX(ap.dum)
set ydum = GetUnitY(ap.dum)
set a = Atan2(yc-ydum, xc-xdum)
set hc = GetUnitFlyHeight(ap.c) + 50
set hdum = GetUnitFlyHeight(ap.dum)
set d = SquareRoot((xdum-ap.x)*(xdum-ap.x)+(ydum-ap.y)*(ydum-ap.y)+(hdum-ap.h)*(hdum-ap.h))
set dm = SquareRoot((xc-ap.x)*(xc-ap.x)+(yc-ap.y)*(yc-ap.y)+(hc-ap.h)*(hc-ap.h))
set dp = d/dm
set h = ap.h + (GetUnitFlyHeight(ap.c)+50-ap.h) * dp + ap.arc * dm * Sin(dp*bj_PI)
set r = 90 + Atan((h-GetUnitFlyHeight(ap.dum))/ap.speed) * bj_RADTODEG
set x = xdum + ap.speed * Cos(a)
set y = ydum + ap.speed * Sin(a)
if dm-d >= 0 then
call SetUnitX(ap.dum, x)
call SetUnitY(ap.dum, y)
else
call SetUnitX(ap.dum, xc)
call SetUnitY(ap.dum, yc)
call DestroyEffect(ap.fx)
call KillUnit(ap.dum)
call ap.func.execute(ap.u, ap.c)
set ap.u = null
set ap.c = null
set ap.dum = null
set ap.fx = null
set Ar[i] = Ar[Total - 1]
set Total = Total - 1
call ap.destroy()
set i = i - 1
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(TimProjectile)
endif
endfunction
function CreateProjectile takes unit u, unit c, string fx, real size, real speed, real arc, real aarc, ImpactProjectile func returns nothing
local Projectile ap = Projectile.create()
local real xs = GetUnitX(u)
local real ys = GetUnitY(u)
local real xc = GetUnitX(c)
local real yc = GetUnitY(c)
local real a = Atan2(yc-ys, xc-xs) * bj_RADTODEG
set ap.u = u
set ap.x = xs
set ap.y = ys
set ap.h = GetUnitFlyHeight(u) + 50
set ap.c = c
set ap.speed = speed * Interval
set ap.arc = arc
set ap.aarc = aarc
set ap.dum = CreateUnit(GetOwningPlayer(u), DummyId, xs, ys, a)
set ap.fx = AddSpecialEffectTarget(fx, ap.dum, "origin")
set ap.func = func
if Total == 0 then
call TimerStart(TimProjectile, Interval, true, function Move)
endif
set Ar[Total] = ap
set Total = Total + 1
set u = null
set c = null
endfunction
endlibrary
Utilisation :
Voici un petit exemple d'utilisation :
Jass:
function ImpactProjectile takes unit u, unit c returns nothing
call UnitDamageTarget(u, c, 50, false, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
set u = null
set c = null
endfunction
Ce qui va envoyer un projectile sur la cible et lui infliger 50 pts de dégâts à la collision.
Juste pour que tout soit clair :
• GetTriggerUnit() : L'unité lanceuse du projectile (ah bon?)
• GetSpellTargetUnit() : L'unité cible
• "Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl" : Le modèle attaché au projectile
• 1 : La taille du projectile
• 1200 : La vitesse du projectile
• 0.15 : L'arc (correspond au même que celui dans l'éditeur d'objet, donc allez-y lentement sur les valeur . Au-delà de 2, on voit à peine le projectile).
• ImpactProjectile : Fonction appelée quand le projectile touche sa cible. Elle doit prendre pour arguments deux unités ; la première est l'unité lanceuse, la deuxième la cible.
Copyright : Libre
Remarques : Ca fait des jolies courbes comme les projectiles faits par l'éditeur de donnée. Le modèle tiré du système détaillé plus haut permet d'incliner l'unité vers le haut/bas, donc rend le mouvement réaliste. _________________
Dernière édition par Sapeur-Goblin le 08/03/12 17:57; édité 16 fois
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 03/03/12 19:43 Sujet du message:
Petite review vite faite :
- Il faut mettre un exemple dans son ensemble : avec la fonction d'initialisation et la récupération des xs/xc/speed/etc à chaque étape.
- Ce serait bien de mettre un lien direct vers le dummy (en voilà un).
- Tu devrais utiliser "bj_PI" et "bj_RADTODEG", ce sera plus lisible et je n'pense pas que ça ait une influence sur la vitesse d'exécution (à priori, ça a juste une influence insignifiante sur le temps de chargement de la map).
- Tu devrais garder une cohérence dans les noms de tes variables : je vois pas pourquoi SPEED, HEIGHT_MIN et ARC sont en majuscule.
Au niveau du système en lui-même, j'ai pas testé, mais je pense qu'il y a quelques erreurs :
- La direction "a" est calculé selon la source et la destination, il serait plus judicieux de la calculer selon la position du projectile et la destination.
- "if dm-d >= SPEED then" à transformer en "if dm-d >= 0 then" (parce que tu rajoutes déjà SPEED dans d). C'pas une grosse différence mais voilà quoi.
- J'ai plusieurs remarques mais qui dépendent de la façon selon laquelle est obtenue la position source et la position ciblée à chaque instant.
Sinon, ça pourrait se révéler intéressant. _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 03/03/12 22:54 Sujet du message:
Voilà, j'ai corrigé les erreurs.
J'améliorerais d'ici peu la fonction pour qu'elle puisse supporter des unités aériennes. Parce que là, si l'unité cible est aérienne, il n'y a aucun moyen d'élever le projectile.
Edit : Si on utilise un arc assez grand, 0.5 par exemple, des effets bizarres apparaissent lors de la mort du projectile. On dirait qu'il est téléporté quelque part autours de la cible. Je ne vois pas d'où ça peut venir...
Deuxième édit : C'est bon, les unités aériennes sont gérées. Par contre il y a toujours ce petit soucis d'effet à la mort du projectile :/. En fait plus l'intervalle du timer est petit, plus ces effets sont présents. _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 05/03/12 17:10 Sujet du message:
J'ai édité mon poste, j'ai fait un système beaucoup plus simple d'utilisation, il gère tout.
Si vous (je pense particulièrement à Troll-Brain ) avez des recommandations quant à l'amélioration, allez-y, lâchez tout .
Ps : Il y a toujours ce problème atterrissage pas très net de temps en temps. Ca le fait chez tout le monde ou j'ai un problème? Si oui, qu'est-ce qui pourrait en être la cause? _________________
Inscrit le: 21 Fév 2010 Messages: 1785 Sujets: 22 Spécialité en worldedit: La modestie Médailles: 1 (En savoir plus...)
Posté le: 05/03/12 18:30 Sujet du message:
Ça le fait sans aucun doute à tout le monde, mais je testerai un autre jour. Pour l'optimisation, on verra ça un autre jour aussi, mais il doit y avoir moyen de ^^.
Juste une remarque en passant : tu devrais mettre un argument "speed" exprimé en distance/seconde, et pas distance/interval. Tu as juste à mettre "set ap.speed = speed * Interval" et l'argument speed correspondra à celui qu'on met dans l'éditeur d'objet. _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 07/03/12 15:32 Sujet du message:
C'est bon pour le speed.
Sinon j'ai mis à jour le code à cause d'un petit défaut qu'il avait : il calculait la distance en deux dimensions et non en 3, ce qui pouvait causer des problèmes avec les unités aériennes.
Le problème de atterrissage semble venir de SetUnitX/Y : j'ai essayé avec SetUnitPositionLoc et il a disparu...
Edit : Ce problème vient du fait que la fonction Atan2 renvoie des angles improbables vers la fin...
Second edit : Cet éditeur est une blague. J'ai créé ma propre fonction pour calculer des angles : résultat, quand je calcule un angle mais que je ne le réutilise pas après, il correspond au bon angle. Quand je le réutilise, il change -.-'. J'ai sérieusement l'impression d'avoir un problème avec mon pc . _________________
Inscrit le: 14 Oct 2009 Messages: 719 Sujets: 40 Spécialité en worldedit: Les bugs Médailles: 1 (En savoir plus...)
Posté le: 08/03/12 17:56 Sujet du message:
Désolé pour ce double poste mais éditer l'autre aurait été un peu de trop . C'était juste pour dire que j'ai réussi à enlever le bug d'atterrissage, c'était plus un bug qu'autre chose. _________________
Inscrit le: 23 Aoû 2007 Messages: 7143 Sujets: 147 Spécialité en worldedit: le troll, le flood, la vulgarité, mon coeur balance Médailles: 2 (En savoir plus...)
Posté le: 09/03/12 21:12 Sujet du message:
Les noms courts non explicites sont à bannir, du style "local real a".
Tout simplement parce que ça rend le code plus difficile à lire, et donc sources d'erreurs possible.
Evidemment il existe quelques exceptions tel que "i,j,k" pour les variables d'incrémentation de loop, "n" pour un indice de tableau, etc.
A la limite c'est "acceptable" pour le code que l'utilisateur n'est pas censé modifié, mais ça ne l'est pas pour les en tête des API (les arguments des fonctions fournies pour l'utilisateur) _________________
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum