| 03-07-2006, 08:57 PM | #1 |
well, what I am trying to do is quickly move a unit along the ground in a parabola like thing, ex. O Target of Ability I I I ** (It won't post how I want to show it, but I think you get the idea) I but basically a sideways parabola, like a jump, but along the ground on the x/y axis I so instead of going in a straight line to the target, you go at an arc outward O Caster Position any ideas or thoughts of how to accomplish this movement? |
| 03-07-2006, 09:01 PM | #2 |
Hmm, you could define and calculate the points of the parabola in an independant x/y system and then rotate the points around the origin to the angle between the caster and the target. |
| 03-07-2006, 09:13 PM | #3 |
JASS:function JumpParabola takes real dist, real maxdist,real curve returns real local real t = (dist*2)/maxdist-1 return (-t*t+1)*(maxdist/curve) endfunction dist is the current distance and maxdist is the maximum distance |
| 03-08-2006, 12:12 AM | #4 | |
could you show me how to use this, I am a little confused here i have to keep checking the guys distance to where he is trying to get? so distance should always be something like: DistanceBetweenPoints(GetUnitLoc(u),GetSpeelTargetLoc()) max distance would be the distane between unit location at spell effect and target and real curve is what you suggested, 1.8, what exactly is the real that this gives me? the location to move the unit to or what? and how exactly could I use it to not make my guy jump, but to have him go how I want it to? Quote:
im lost again incase there is any misunderstanding this is what I am looking for ( there is no change in the units fly height), this shows the movement wanted from the caster: ![]() |
| 03-08-2006, 05:21 AM | #7 |
aight Vex ill give it a whirl, though I dont fully understand it all :( and Shadow, again, what is the real that you are given with the equation? is that supposed to be the unit fly height(z), since you are manually setting the movement along the x/y ( jsut wondering for future jump spells) just typing this all in as I go along: so, we got point A,B, and C, will add more as I go A = caster position B = target position C = PolarProjectionBJ(A,SquareRoot(((DistanceBetweenPoints(A,B)/2)^2)+200^2),45) -----200 just as a set number to work from now now as far as moving my unit, i am a little lost do I set a = 0 and b = 1 then each run of the trigger set a = a + .01 and b = b - .01, and run the function 100 times to get the curve, setting my x and y coordinates using your equations? |
| 03-08-2006, 08:13 AM | #8 |
Correct, as vex said, a goes from 0 to 1. |
| 03-08-2006, 07:40 PM | #9 |
well, i tried, and failed misserably, after some debugging it seems that the dummy unit is created at the ending point, and slowly goes backwards towards the starting point( if I remove the part for destroying the timer if the unit is near the ending point), so if I changed it to a = 1 and b = 0, and subtract from a and add to b, it creates the dummy at the start point, and moves it very slowly to the end point( lowering the trigger run speed to .007 solves this and makes it go at the speed wanted) , no curve, just a straight line... :( , anywho, here is what I got JASS:function BezierCurve takes real Ax, real Ay, real Bx, real By, real Cx, real Cy, real a, real b returns location local real x = (Ax*(a*a)) + (Bx*2*a*b) + (Cx*(b*b)) local real y = (Ay*(a*a)) + (By*2*a*b) + (Cy*(b*b)) // use equations suggested to get points...btw how do I remove location leak here, I tried and it gave me errors local location l = Location(x,y) return l endfunction function ShadowBreeze_Walk takes nothing returns nothing local timer t = GetExpiredTimer() local real x1 = GetHandleReal(t,"x1") local real y1 = GetHandleReal(t,"y1") local real x2 = GetHandleReal(t,"x2") local real y2 = GetHandleReal(t,"y2") local real x3 = GetHandleReal(t,"x3") local real y3 = GetHandleReal(t,"y3") local real a = GetHandleReal(t,"a") local real b = GetHandleReal(t,"b") local location l = BezierCurve(x1,y1,x3,y3,x2,y2,a,b) //Get position using equations call SetUnitPositionLoc(GetHandleUnit(t, "dum"),l) call SetUnitAnimation(GetHandleUnit(t, "dum"), "walk") if IsUnitInRangeXY(GetHandleUnit(t, "dum"),x2,y2, 100) or GetUnitState(GetHandleUnit(t, "dum"), ConvertUnitState(0)) <= 0 then // end of dummy is near end point call KillUnit(GetHandleUnit(t, "dum")) call RemoveUnit(GetHandleUnit(t, "dum")) call FlushHandleLocals(t) call PauseTimer(t) call DestroyTimer(t) endif call SetHandleReal(t,"a",a + .01) // make a go from 0 - 1 and b from 1-0 like Vex said call SetHandleReal(t,"b",b - .01) set t = null call RemoveLocation(l) set l = null endfunction function ShadowBreeze_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local timer t = CreateTimer() local real x1 = GetUnitX(u) // reals for point A local real y1 = GetUnitY(u) local location l = GetSpellTargetLoc() local real x2 = GetLocationX(l) // reals for Point C local real y2 = GetLocationY(l) local unit dum = CreateUnit(p, 'n000', x1, y1, a) local real dist = SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/2 local real dist2 = SquareRoot((dist*dist)+(200*200)) // used Pythagoreaum Thereom to get location of point B local real x3 = x1 + dist2 * Cos(a * bj_DEGTORAD) // Reals for point B local real y3 = y1 + dist2 * Sin(a * bj_DEGTORAD) call SetHandleReal(t,"x3",x3) call SetHandleReal(t,"y3",y3) call SetHandleReal(t,"x1",x1) call SetHandleReal(t,"y1",y1) call SetHandleReal(t,"a",0) // set a to 0 and b to 1 like Vex said to start with call SetHandleReal(t,"b",1) call UnitApplyTimedLife(dum, 'BTLF', 2) call SetHandleReal(t,"x2",x2) call SetHandleReal(t,"y2",y2) call SetHandleHandle(t, "dum", dum) call SetUnitTimeScalePercent(dum, 10000) call SetUnitAnimation(dum, "walk") call TimerStart(t, .025, true, function ShadowBreeze_Walk) call TriggerSleepAction(0) call MoveUnitToPolarProjection(u,SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))+50, a) call SetUnitFacing(u,bj_RADTODEG * Atan2(GetUnitY(u)-y2,GetUnitX(u)-x2)) // this is unit targetable, so gotta move the caster to the target set t = null set u = null call RemoveLocation(l) set l = null set dum = null endfunction Vex.... helpppp... |
| 03-08-2006, 09:00 PM | #10 |
From what I've seen is that point A and B should be calculated when the spell begins, not every time (should stay constant) otherwise it screws the effect. I am gonna check the details later |
| 03-09-2006, 12:41 AM | #11 |
ouch??? I believe all teh points are calculated at the beggining of the spell JASS:call SetHandleReal(t,"x3",x3) call SetHandleReal(t,"y3",y3) call SetHandleReal(t,"x1",x1) call SetHandleReal(t,"y1",y1) call SetHandleReal(t,"x2",x2) call SetHandleReal(t,"y2",y2) and they are never changed throughout the spell... |
| 03-09-2006, 01:48 AM | #12 |
JASS://function BezierCurve takes real Ax, real Ay, real Bx, real By, real Cx, real Cy, real a, real b returns location // local real x = (Ax*(a*a)) + (Bx*2*a*b) + (Cx*(b*b)) // local real y = (Ay*(a*a)) + (By*2*a*b) + (Cy*(b*b)) // use equations suggested to get points...btw how do I remove location leak here, I tried and it gave me errors // local location l = Location(x,y) // return l //endfunction //The answer is to do not use a function, or use 2 functions, or even one function because the formula is the same for x and y. //Or you can make it take a location and use MoveLocation function BezierCurveValue takes real a, real b, real A, real B, real C returns real return A*a*a+2*B*a*b+C*b*b endfunction function ShadowBreeze_Walk takes nothing returns nothing local timer t = GetExpiredTimer() local real x1 = GetHandleReal(t,"x1") local real y1 = GetHandleReal(t,"y1") local real x2 = GetHandleReal(t,"x2") local real y2 = GetHandleReal(t,"y2") local real x3 = GetHandleReal(t,"x3") local real y3 = GetHandleReal(t,"y3") local real a = GetHandleReal(t,"a") local real b = 1-a //old: GetHandleReal(t,"b") local unit dum=GetHandleUnit(t, "dum") //for god's sake, do you know how heavy is such a handle var call? //you were calling it thousands of times call SetUnitPosition(dum, BezierCurveValue(a,b,x1,x3,x2), BezierCurveValue(a,b,y1,y3,y2)) call SetUnitAnimation(dum, "walk") //Using a constant is for sure faster than ConvertUnitState: if IsUnitInRangeXY(dum,x2,y2, 100) or GetUnitState(dum,UNIT_STATE_LIFE) <= 0 then // end of dummy is near end point call KillUnit(dum) call RemoveUnit(dum) call FlushHandleLocals(t) call PauseTimer(t) call DestroyTimer(t) endif call SetHandleReal(t,"a",a + .01) //Note that an increment of 0.01 means that it will need 100 timer cycles to complete the move. // make a go from 0 - 1 and b from 1-0 like Vex said //no need : call SetHandleReal(t,"b",b - .01) set t = null set dum=null endfunction function ShadowBreeze_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local timer t = CreateTimer() local real x1 = GetUnitX(u) // reals for point A local real y1 = GetUnitY(u) local location l = GetSpellTargetLoc() local real x2 = GetLocationX(l) // reals for Point C local real y2 = GetLocationY(l) local unit dum = CreateUnit(p, 'n000', x1, y1, a) //what 'a'? , I don't see any declaration for that local real dist = SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))/2 local real dist2 = SquareRoot((dist*dist)+(200*200)) // used Pythagoreaum Thereom to get location of point B local real x3 = x1 + dist2 * Cos(a * bj_DEGTORAD) // Reals for point B local real y3 = y1 + dist2 * Sin(a * bj_DEGTORAD) // I don't get the logic of these calculations, and I don't know how do you calculate a // most likely the calculation of a call SetHandleReal(t,"x3",x3) call SetHandleReal(t,"y3",y3) call SetHandleReal(t,"x1",x1) call SetHandleReal(t,"y1",y1) //call SetHandleReal(t,"a",0) // set a to 0 and b to 1 like Vex said to start with // No need to save a, it already starts at 0. //call SetHandleReal(t,"b",1) No, no need to save b in game cache call UnitApplyTimedLife(dum, 'BTLF', 2) call SetHandleReal(t,"x2",x2) call SetHandleReal(t,"y2",y2) call SetHandleHandle(t, "dum", dum) call SetUnitTimeScalePercent(dum, 10000) call SetUnitAnimation(dum, "walk") call TimerStart(t, .025, true, function ShadowBreeze_Walk) call TriggerSleepAction(0) call MoveUnitToPolarProjection(u,SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))+50, a) call SetUnitFacing(u,bj_RADTODEG * Atan2(GetUnitY(u)-y2,GetUnitX(u)-x2)) // this is unit targetable, so gotta move the caster to the target set t = null set u = null call RemoveLocation(l) set l = null set dum = null endfunction |
| 03-09-2006, 06:40 AM | #13 |
ty a mil Vex, works like a charm now and it seems funny to me, but most of what you had me change was just for asthetic purposes, and didnt seem to really change at all what it was really doing, the main prob may have been the angle a, that I fixed, ty again! my only complaint Vex is this, at times, the arc looks perfect, and other times, it looks ok, and other times it looks like crap I could use it 10 times in a row from the same spot to the same spot and each time it looks different, why the variability? |
| 03-09-2006, 10:24 AM | #14 |
I would blame your angle a calculation. And the difference between calling GetHandeUnit(t,"dum") 13 times in a row and just calling it once is a huge performance difference |
| 03-09-2006, 08:39 PM | #15 |
i fixed that, and yes it was my angle i still had it screwed up, instead of using the angle between the target and caster, then adding or subtracting 45 to it to get my point C, i was just using 45 and -45, it looks amazing now, ty for your help again! id give +rep but it seems i need to spread it still more... :( |
