Sprite start and end positions (lightning effect) question
by Christian · in Torque 2D Beginner · 10/30/2013 (11:18 pm) · 6 replies
I've been working on a lightning effect, which is just a lightning sprite that is sized and angled to go from point A to B.
The issue is how to get the image to start and end at the desired position on the map.
Currently I'm setting the angle of the lightning sprite to point from point A to B (which works fine).
But the position is always off. If I put the image at point A, it will go about halfway to point be, the other half of the lightning bolt going the opposite direction (since it was centered on point A). So I tried putting it exactly in-between point A and B by averaging their x and y positions, which still is about 25% off.
Wondering if anyone has made an effect similar to this and has tips. Thanks.
The issue is how to get the image to start and end at the desired position on the map.
Currently I'm setting the angle of the lightning sprite to point from point A to B (which works fine).
But the position is always off. If I put the image at point A, it will go about halfway to point be, the other half of the lightning bolt going the opposite direction (since it was centered on point A). So I tried putting it exactly in-between point A and B by averaging their x and y positions, which still is about 25% off.
Wondering if anyone has made an effect similar to this and has tips. Thanks.
#2
Trying to understand what you mean exactly in a couple spots (I did just learn a ton on vectors too when attempting this).
When you said "Set its position half its width along the vector to the target". Can you clarify that? I have the width of the lightning bolt as a constant currently.
With the distance from point A to B and getting a normalized vector of that distance, and multiplying by half the distance. I'm a little confused as well. I thought normalizing a vector was for the angle, not the distance?
Included the code I've been using below.
10/31/2013 (8:31 pm)
Hey Richard,Trying to understand what you mean exactly in a couple spots (I did just learn a ton on vectors too when attempting this).
When you said "Set its position half its width along the vector to the target". Can you clarify that? I have the width of the lightning bolt as a constant currently.
With the distance from point A to B and getting a normalized vector of that distance, and multiplying by half the distance. I'm a little confused as well. I thought normalizing a vector was for the angle, not the distance?
Included the code I've been using below.
%pos1 = %monster.Position; %pos2 = %target.Position; %new_x = %pos1.x + %pos2.x / 2; %new_y = %pos1.y + %pos2.y / 2; %pos3 = %new_x SPC %new_y; //%vector_normalize = VectorNormalize(%pos3); //$pos3 = %pos3; %dx = %pos1.x - %pos2.x; %dy = %pos1.y - %pos2.y; %dist = mSqrt(%dx*%dx + %dy*%dy); //%new_dist = %dist / 2 * %vector_normalize; %bolt = new Sprite(); %bolt.Position = %pos3; %bolt.Size = 3 SPC %dist; %bolt.explosion_scale = 2; %bolt.SceneLayer = 2; %bolt.SceneGroup = 30; //bullets %shape_index = %bolt.createCircleCollisionShape(3); %bolt.setCollisionShapeIsSensor(%shape_index,1); %bolt.setCollisionCallback(true); %bolt.Image = "ToyAssets:lightning_effect"; //%bolt.setImageFrame(0); %worldposition = %pos2; %origin = %pos1; %angle = -mRadToDeg(mAtan(%worldposition.x-%origin.x, %worldposition.y-%origin.y)); myScene.add(%bolt); %bolt.RotateTo(180 + %angle, 1000);
#3
Might have to fiddle with the angle - I haven't tested that but it should be on the right track....
11/01/2013 (6:45 am)
Normalizing is for angles, sure - but it's a unit vector pointing in the direction you want to go. If you scale that unit vector by the distance you want to go, you go that distance in that direction.%dx = %pos1.x - %pos2.x; %dy = %pos1.y - %pos2.y; %dist = mSqrt(%dx*%dx + %dy*%dy);can be replaced with
%dist = Vector2Distance(%pos1, %pos2);and then
%angle = -mRadToDeg(mAtan(%worldposition.x-%origin.x, %worldposition.y-%origin.y));becomes
%angle = Vector2AngleBetween(%pos1, %pos2); %boltPos = VectorNormalize(Vector2Sub(%pos1, %pos2)); %boltPos = VectorScale(%boltPos, (%dist / 2)); %bolt.setPosition(%boltPos.x, %boltPos.y); %bolt.rotateTo(180+%angle, 32);
Might have to fiddle with the angle - I haven't tested that but it should be on the right track....
#4
11/01/2013 (8:36 am)
You know, perhaps we can simplify a little if we change%boltPos = VectorNormalize(VectorVector2Sub(%pos1, %pos2)); %boltPos = VectorScale(%boltPos, (%dist / 2));to this
%boltPos = Vector2Sub(%pos2, %pos1); // might be %pos1, %pos2 instead %boltPos = VectorScale(%boltPos, 0.5);So we would use %dist to scale the length of the lightning bolt and just directly scale the vector between the two objects for placement.
#5
Set target to 90 degrees, angle is 53
Set target to 180 degrees, angle is 8
Set target to 270 degrees, angle is 38
Set target to 0 degrees, angle is 138
Don't see any conceivable pattern to it. It's weirder too, the farther/closer I go, the angle changes (which it shouldn't be if it is going at the same angle).
Have tried a variety of changes to the %boltPos, but none have worked as of yet.
So adding any number to %angle doesn't make it correct. Currently both the position and the angle of the bolt are off.
Going to keep experimenting with angles and %boltPos
11/01/2013 (11:36 am)
Set pos2 (target) at 90 degrees from pos1 (origination point) and the angle becomes 53 degrees.Set target to 90 degrees, angle is 53
Set target to 180 degrees, angle is 8
Set target to 270 degrees, angle is 38
Set target to 0 degrees, angle is 138
Don't see any conceivable pattern to it. It's weirder too, the farther/closer I go, the angle changes (which it shouldn't be if it is going at the same angle).
Have tried a variety of changes to the %boltPos, but none have worked as of yet.
%pos1 = %monster.Position;
%pos2 = %target.Position;
%angle = Vector2AngleBetween(%pos1, %pos2);
%boltPos = Vector2Sub(%pos2, %pos1); // might be %pos1, %pos2 instead
%boltPos = VectorScale(%boltPos, 0.5);
%dist = Vector2Distance(%pos1, %pos2);
%bolt = new Sprite();
%bolt.Position = %boltPos;
%bolt.Size = 3 SPC %dist;
%bolt.explosion_scale = 2;
%bolt.SceneLayer = 2;
%bolt.SceneGroup = 30; //bullets
%shape_index = %bolt.createCircleCollisionShape(3);
%bolt.setCollisionShapeIsSensor(%shape_index,1);
%bolt.setCollisionCallback(true);
%bolt.Image = "ToyAssets:lightning_effect";
myScene.add(%bolt);
echo("angle: " @ %angle);
%bolt.RotateTo(%angle, 1000);So adding any number to %angle doesn't make it correct. Currently both the position and the angle of the bolt are off.
Going to keep experimenting with angles and %boltPos
#6
So everything is good and working now.
Thanks for all your help on this.
11/01/2013 (2:53 pm)
It was really bugging me why taking their exact in-between coordinates wasn't producing the right position on the map, then I noticed a mistake in my original code. I was halving the pos2.x and pos2.y instead of halving both pos1 and pos2 together. So with that fixed, the original angle equation worked.So everything is good and working now.
Thanks for all your help on this.
%pos1 = %monster.Position; %pos2 = %target.Position; %new_x = %pos1.x + %pos2.x; %new_y = %pos1.y + %pos2.y; %new_x /= 2; %new_y /= 2; %pos3 = %new_x SPC %new_y; %angle = -mRadToDeg(mAtan(%pos2.x-%pos1.x, %pos2.y-%pos1.y)); %dist = Vector2Distance(%pos1, %pos2); %bolt = new Sprite(); %bolt.Position = %pos3; //%boltPos; %bolt.Size = 3 SPC %dist; %bolt.explosion_scale = 2; %bolt.SceneLayer = 2; %bolt.SceneGroup = 30; //bullets %shape_index = %bolt.createCircleCollisionShape(3); %bolt.setCollisionShapeIsSensor(%shape_index,1); %bolt.setCollisionCallback(true); %bolt.Image = "ToyAssets:lightning_effect"; myScene.add(%bolt); %bolt.RotateTo(%angle + 180, 1000);
Torque Owner Richard Ranft
Roostertail Games