Public Group

# Direction and laser

This topic is 4522 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've done a whole lot of work now trying to get the right direction of the shot of a laser tower, will ask here before quitting for the day. I've done something like this to get the coordinates of where the laser shot should end, like way points:
SDL_Rect Lasereye::LaserCoordinates(Laser s) {
SDL_Rect coordinate;

// fix all coordinates here and remove this comment
if (s.direction == 0 || s.direction == 1) {
coordinate.x = x-17;
coordinate.y = y+154;
} else if (s.direction == 2 || s.direction == 3) {
coordinate.x = x-63;
coordinate.y = y+140;
} else if (s.direction == 4 || s.direction == 5) {
coordinate.x = x-83;
coordinate.y = y+129;
} else if (s.direction == 6 || s.direction == 7) {
coordinate.x = x-102;
coordinate.y = y+110;
} else if (s.direction == 8 || s.direction == 9) {
coordinate.x = x-118;
coordinate.y = y+89;
} else if (s.direction == 10 || s.direction == 11) {
coordinate.x = x-138;
coordinate.y = y+11;
} else if (s.direction == 12 || s.direction == 13) {
coordinate.x = x-138;
coordinate.y = y+11;
} else if (s.direction == 14 || s.direction == 15) {
coordinate.x = x-139;
coordinate.y = y+4;
} else if (s.direction == 16 || s.direction == 17) {
coordinate.x = x-50;
coordinate.y = y-4;
} else if (s.direction == 18 || s.direction == 19) {
coordinate.x = x-121;
coordinate.y = y-54;
} else if (s.direction == 20 || s.direction == 21) {
coordinate.x = x-103;
coordinate.y = y-84;
} else if (s.direction == 22 || s.direction == 23) {
coordinate.x = x-49;
coordinate.y = y-124;
} else if (s.direction == 24 || s.direction == 25) {
coordinate.x = x+102;
coordinate.y = y-104;
} else if (s.direction == 26 || s.direction == 27) {
coordinate.x = x+136;
coordinate.y = y-62;
} else if (s.direction == 28 || s.direction == 29) {
coordinate.x = x+149;
coordinate.y = y-39;
} else if (s.direction == 30 || s.direction == 31) {
coordinate.x = x+159;
coordinate.y = y-10;
} else if (s.direction == 32 || s.direction == 33) {
coordinate.x = x+154;
coordinate.y = y+38;
} else if (s.direction == 34 || s.direction == 35) {
coordinate.x = x+133;
coordinate.y = y+91;
} else if (s.direction == 36 || s.direction == 37) {
coordinate.x = x+115;
coordinate.y = y+113;
} else if (s.direction == 38 || s.direction == 39) {
coordinate.x = x+82;
coordinate.y = y+138;
} else if (s.direction == 40 || s.direction == 41) {
coordinate.x = x+72;
coordinate.y = y+142;
} else if (s.direction == 42 || s.direction == 43 || s.direction == 44) {
coordinate.x = x+8;
coordinate.y = y+156;
}

return coordinate;
}

and clipped everything out in photoshop and that was a pain to do. It works but some stuff is not 100%, maybe because I made a mistake or something, so I decided to do it the math way (if there is) and ask here about it instead. First I will explain what my problem is. I am making an enemy tower which constantly fire off laser shots with about 800 milliseconds interval. The range of the shot is 140px (something that doesn't really matter, but that's how it is , 140 is something I picked). Right now the function that shows the laser shots and all that stuff, looks lik e this:
void Lasereye::Shot() {
SDL_Rect coordinate;

// start new delay
if (shootDelay==0) {
shootDelay=800;

lasertime = new Timer;
lasertime->start();

shot=true;
}

// if delay is done
if (lasertime->get_ticks()>=shootDelay && shootDelay!=0) {
shootDelay=0;
delete lasertime;
}

// if shot is true
if (shot) {
Laser laser;

// set coordinates
laser.frame = 0;
laser.startX = x;
laser.startY = y;
laser.x = laser.startX;
laser.y = laser.startY;
laser.direction = frame;

shots.push_back(laser);
shot=false;
}

// loop trough all shot structs in the vector
for (int i=0;i<shots.size();i++) {
coordinate = LaserCoordinates(shots);

if (shots.x < coordinate.x)
shots.x += 2;
else if (shots.x > coordinate.x)
shots.x -= 2;

if (shots.y < coordinate.y)
shots.y += 2;
else if (shots.y > coordinate.y)
shots.y -= 2;

// change between frame 1 and 0
if (shots.frame>=1)
shots.frame=0;
else
shots.frame++;

// show current laser struct
BlitSurface(shots.x-camera.x, shots.y-camera.y, buffer, &shotRect[shots.frame]);

// this line doesn't work because the y pos and x pos can vary now                 because of the angle
if ((shots.x >= shots.x+range) || (shots.y >= shots.startY+range) || (shots.x <= shots.startX-range) || (shots.y <= shots.startY-range)) {
shots.erase(shots.begin() + i);
}
}
}

Laser struct:
struct Laser {
int direction;
int frame;
int startX;
int startY;
int x;
int y;
};

Inherited Lasereye class:
class Lasereye : public Enemy {
public:
Lasereye(int xPos, int yPos, string dir, int range);

void Shot();

SDL_Rect LaserCoordinates(Laser s);

protected:
bool shot;

int range;
int shootDelay;

Timer *lasertime;

vector<Laser> shots;

SDL_Surface *buffer;
SDL_Rect shotRect[1];
};

Here are some pics which explains what I mean. If you have any idea how to make a tower that fires the shots in the right direction, please explain how to do it. Most of the things are already done almost. Picture 1 Picture 2 I hope you understand what I want to do, doesn't have so much time right now so I explained it a little quick. Thankful for help..

##### Share on other sites
What you are trying to do is theoretically impossible.

##### Share on other sites
If I understand you correctly, you are asking how to find the target point of the laser shot, given an angle at which the turret is turned, and a circle with radius 140. You may have to convert to radians first, but afaik, given an angle, in your case,

x = 140 * cos(angle)
y = 140 * sin(angle)

I think that you need to get the angle to be below 90 first, so you'll have to subtract 90 from the angle if it's too large, possibly multiple times. Depending on how often you subtract, the final x or y or both will have to be negative after you calculate them.

if 0 to 90 represents the upper right quadrant, with angle zero = horizontal (not sure if that is proper in math, but it shouldn't matter in this example), then

90-180 - x negative
180-270 - x and y negative
270-360 - y negative

Afterwards you still need to translate by position of turret, since these are relative to a turret at origin.

There may be a more elegant solution, but I think this should work.

##### Share on other sites
Something in that style is what i'm looking for. I kind of understand the most of it but there are so much things that is not clear yet. For example, isn't it necessary to include the xy position of the turret too in order to get it right. How are they included in the formula?

The first function I posted is the function that calculates the waypoint/coordinate the lasershot should follow, it varies depending on which frame the turret currently is on. The reason I check both 0 and 1, 1 and 2 in all if statements is because every sprite is shown two times, else it becomes too fast.

The first turret that is shown in frame 0 and 1 is almost turned down, a little bit to the left. I'm not really sure how i'm supposed to use the formulas. The angle 190 is something I thought sounded appropriate, don't really know.

if (s.direction == 0 || s.direction == 1) {
angle = 190;
coordinate.x = s.startX +- int(range * cos(angle));
coordinate.y = s.StartY +- int(range * sin(angle));
}

Not sure if it is + or - or neither, that's why it is +- for the moment (range = 140).

How would it look like if the coordinate the current laser should follow is like this (red dot on pic)? it would help a lot to know.
First coordinate

Maybe I can just add a loop which loops trough all 360 degrees that sounds like a fairly easy thing to do, is that possible? Not sure, but something in this style:

for (int i=0;i<360;i++) {
coordinate.x = 140 * cos(i);
coordinate.y = 140 * sin(i);
}

I'm really confused right now, like how i'm supposed to add the startX and startY positions in the formula etc.

##### Share on other sites
Quote:
 Original post by lightbringerI think that you need to get the angle to be below 90 first, so you'll have to subtract 90 from the angle if it's too large, possibly multiple times. Depending on how often you subtract, the final x or y or both will have to be negative after you calculate them.

No, you shouldn't have to do that.

[Edited by - Ezbez on July 2, 2006 7:43:53 AM]

##### Share on other sites
Quote:
 Original post by passwordSomething in that style is what i'm looking for. I kind of understand the most of it but there are so much things that is not clear yet. For example, isn't it necessary to include the xy position of the turret too in order to get it right. How are they included in the formula?

1) start with the assumption that the turret is at the origin.
2) the point you are looking for should be given by the formulae shown above.
3) As Ezbez already pointed out, I made a mistake - the sin() and cos() functions will already give you the proper sign so you don't have to mess with that.
4) after you've calculated that, add the current turret coordinates.
5) the new point after all these steps is the point you are trying to fire at. (you don't really need to calculate this. rather, it would make more sense to keep everything relative to the turret, and only add the turret coordinates when drawing something on screen)

If you are still confused at this point, you need to google trigonometry and vector algebra.

Quote:
 Original post by passwordMaybe I can just add a loop which loops trough all 360 degrees that sounds like a fairly easy thing to do, is that possible?

There's no reason to do that. For travelling to that point, you just need to scale the vector. For instance, if the target point is at (-10, 5) (relative to the turret) and your animation takes five frames, you could each frame move the projectile by (-10, 5) * 0.2 = (-2, 1)

##### Share on other sites
Quote:
Original post by lightbringer
Quote:
 Original post by passwordSomething in that style is what i'm looking for. I kind of understand the most of it but there are so much things that is not clear yet. For example, isn't it necessary to include the xy position of the turret too in order to get it right. How are they included in the formula?

1) start with the assumption that the turret is at the origin.
2) the point you are looking for should be given by the formulae shown above.
3) As Ezbez already pointed out, I made a mistake - the sin() and cos() functions will already give you the proper sign so you don't have to mess with that.
4) after you've calculated that, add the current turret coordinates.
5) the new point after all these steps is the point you are trying to fire at. (you don't really need to calculate this. rather, it would make more sense to keep everything relative to the turret, and only add the turret coordinates when drawing something on screen)

If you are still confused at this point, you need to google trigonometry and vector algebra.

Quote:
 Original post by passwordMaybe I can just add a loop which loops trough all 360 degrees that sounds like a fairly easy thing to do, is that possible?

There's no reason to do that. For travelling to that point, you just need to scale the vector. For instance, if the target point is at (-10, 5) (relative to the turret) and your animation takes five frames, you could each frame move the projectile by (-10, 5) * 0.2 = (-2, 1)

Thanks, I managed to find out how it worked while testing.
int(range * cos(angle)) is the x position
int(range * sin(angle)) is the y position

I hope this isn't somehow connected or made to work with the cartesian coordinate system only, because that is a little different from what SDL is using.

##### Share on other sites
Quote:
 Original post by passwordI hope this isn't somehow connected or made to work with the cartesian coordinate system only, because that is a little different from what SDL is using.

^ y
|
|
+---> x

is how it works, usually

+---> x
|
|
v y

Another typical arrangement, origin at the upper left. Does SDL look like this? If you run into trouble, you'll have to compute y = height - y as the last step before drawing.

1. 1
Rutin
41
2. 2
3. 3
4. 4
5. 5

• 16
• 18
• 12
• 14
• 9
• ### Forum Statistics

• Total Topics
633361
• Total Posts
3011525
• ### Who's Online (See full list)

There are no registered users currently online

×