| 09-15-2009, 02:50 AM | #1 |
(OT: Alright so right off the bat I feel stupid posting here in comparison to everyone else's threads, especially because I joined today and this is my first post. But I have been lurking for about 5 years without making an account, at THW, here, and sear before that went down. So I feel like I know people but I am still the "look at this noob..." of the thread so >.>) Anyways, I am currently making a spell that I could most easily describe as a boomerang but requires more explanation. Your hero targets a point and effectively moves in a circle starting where he is at, going to where you targeted, and then back to where you casted it from (see fantastic paint image). In addition all enemy units within range get picked up and move along with the hero back to where he casted from. The hero will be hidden this whole time and will be symbolized probably by vex's dummy .mdl with a sfx attached. I have done things similar to this but I cannot for the life of me figure out how I would do the 'formula' for moving the hero. I have the struct, loop, everything setup except for where/how to move the hero. I looked at the boomerang spell that is submitted right now to get somewhat of an idea as to how I would go about this but it moved in an oval and it was kind of hard to understand as just a block of code. So basically can someone point me to a better example/tutorial of this, or could someone help explain how I would go about doing this. I realize this is a pretty broad topic and requires a bit of effort to explain but I would appreciate any links to articles aswell (I am not sure what to google either otherwise I would have, "find next point in circle path" etc. dooesn't exactly bring in the most relevant topics =p. |
| 09-15-2009, 05:14 AM | #2 |
Hmnn, x1 = hero x, y1 = hero y . x2 = target x, y2 = target y . We need the center for that circle, as you can see it is just the middle point: cx = (x1+x2)/2 cy = (y1+y2)/2 The radius of the circle is Distance(cx,cy, x1,x2) Then you just have to make the actual circle, easiest with polar projections. The first ( and last) polar projection angle would be: Atan2( y1-cy, x1-cx), so you then go and increment this angle until you have a circle. For each of these iterations get: x = cx+radius*Cos(ang) y = cy+radius*Sin(ang) And you shall get a point of the circle... |
| 09-15-2009, 07:53 AM | #3 |
There's a cute algorithm for drawing circles. It's not better than what Vex wrote, in fact it really draws an ellipse. e = sqrt(2(1- cos(2pi / period))) x1 = x0 - e*(y0 - cy) y1 = y0 + e*(x1 - cx) // replacing x1 with x0 here will make a spiral instead of an ellipse Period is the number of steps you want it to take to go one full CCW circle. x0,y0 is the current position and x1,y1 is the next position. |
| 09-15-2009, 09:19 PM | #4 |
Alright Vex that is working pretty well and I understand it ok now =p. But there is one thing, with the rough-draft code I have right now: JASS:library Jolt initializer Init globals private Jolt array JOLT private integer total = 0 endglobals //================================================================================ struct Jolt unit c real x real y real x2 real y2 real cx real cy real r real m group g static timer Tim = null static method Loop takes nothing returns nothing local Jolt j local integer i = 0 local real CenterX local real CenterY loop exitwhen i >= total set j = JOLT[i] // if Atan2( j.y-j.cy, j.x-j.cx) != bj_DEGTORAD*AngleBetweenPoints(Location(j.cx,j.cy),Location(GetUnitX(j.c),GetUnitY(j.c))) then call SetUnitX(j.c, j.cx+j.r*Cos(j.m)) call SetUnitY(j.c, j.cy+j.r*Sin(j.m)) set j.m = j.m+.1 call BJDebugMsg("Atan2"+R2S(Atan2( j.y-j.cy, j.x-j.cx))) call BJDebugMsg("Angle"+R2S(bj_DEGTORAD*AngleBetweenPoints(Location(j.cx,j.cy),Location(GetUnitX(j.c),GetUnitY(j.c))))) else set JOLT[i] = JOLT[total-1] set total = total - 1 call j.destroy() endif // set i = i + 1 endloop if total == 0 then call PauseTimer(j.Tim) endif endmethod method onDestroy takes nothing returns nothing // endmethod endstruct function CreateJolt takes unit C, real X2, real Y2 returns nothing local Jolt j local real x local real y set j = Jolt.create() set j.g = CreateGroup() set j.c = C set j.x = GetUnitX(j.c) set j.y = GetUnitY(j.c) set j.x2 = X2 set j.y2 = Y2 set j.cx = (j.x+j.x2)/2 set j.cy = (j.y+j.y2)/2 set j.m = Atan2( j.y-j.cy, j.x-j.cx) //Get Dist btwn pnts set x = j.cx - j.x set y = j.cy - j.y set j.r = SquareRoot(x * x + y * y) call SetUnitX(j.c, j.cx+j.r*Cos(j.m)) call SetUnitY(j.c, j.cy+j.r*Sin(j.m)) set JOLT[total] = j if total == 0 then call TimerStart(Jolt.Tim, .3, true, function Jolt.Loop) endif set total = total + 1 endfunction private function Init takes nothing returns nothing set Jolt.Tim = CreateTimer() endfunction endlibrary This line JASS:if Atan2( j.y-j.cy, j.x-j.cx) != bj_DEGTORAD*AngleBetweenPoints(Location(j.cx,j.cy),Location(GetUnitX(j.c),GetUnitY(j.c))) then Or should I just check if the angle is within 1 degree. Otherwise it works fine =p, it just keeps going in a circle forever. And I realize I am using a bj I just threw it in there to make testing easier, I will remove it later. EDIT: j.c - is the hero (unit) j.x - the heroes X j.y - the heroes Y x2 - the spell targets X y2 - the spell targets Y cx - the center x cy - the center y r - the radius m - the angle that is changed every iteration g - unneeded for this explanation |
| 09-15-2009, 10:10 PM | #5 | |
Quote:
|
| 09-16-2009, 10:04 PM | #6 |
EDIT: O man I got pwnt hard, just realized I was inputting my increment as a degree instead of a radian, lol. Works now, thanks for all the help guys. |
