PDA

View Full Version : Math question



ShadowMancer
09-05-2007, 04:40 PM
Alright, I got this info from the net:


R = 2W - P

P = balls path
W = walls angle
R = reflection

And if you wanna know the angle of a moving object. You could figure out it's slope by taking it's last two X and Y coordinates, then devide them

slope = (y2-y1)/(x2-x1)

and after that throw the Arcus Tangens at them. You'll get the Angle returned.


I assume Path means the angle the object is traveling. okay to get that it says get the slope and 'throw the Arcus Tangens at them' there is no ArcTan function in ZScript, does anyone have the formula for this? (I am strateing to study Trig again and Im a bit over my head at the moment :D)

DarkDragon
09-05-2007, 04:45 PM
Well, arctan doesn't have a formula per se... you'd have to either set up some kind of precomputed table (hard without real arrays), or use a numerical approximation.

C-Dawg
09-05-2007, 05:40 PM
Frankly, real-world physics do not a satisfying 2-d game make.

If you're looking to map the path of a ball tossed into the air, just do this:

1. Initially set Vy to a negative number, like -4
2. Initially set Vx to a negative or positive number, depending on the directions
3. Decrement Vy each frame by some amount, like 0.2, to simulate gravity, and cap it at 2 for terminal velocity.
4. Don't change Vx.

What you'll get is a ball that moves in an asthetically pleasing arc and gives the player time to react to it. In lieu of Vy, you could use some equivilant of the Z axis if you're doing it in 2-D.

-C

ShadowMancer
09-05-2007, 07:56 PM
Well actually I am still attempting to get a good reflect effect for 'reflect enemy magic' script, been trying different stuff, I just want to get an effect similar to the battle in LttP with Agahnim. Guess im trying to get too complex with the physics :shrug:

C-Dawg
09-05-2007, 08:32 PM
What you're doing is fine, but here's what I'd do:

(1) The reflectable missile is an FFC that has a ghosted enemy attached, vulnerable only to the sword. (We can set enemies that way, right?)

(2) The FFC is normally stored out of the way off the screen.

(3) When the boss fires, it moves in front of the boss and gets a Vx and Vy that put it on a collision course with Link. (There's a script for this somewhere...)

(4) The FFC checks the ghosted enemy's health each frame. If it drops, the FFC knows it was smacked, so it plays a sound and changes direction. Get Link's location relative to the FFC and send the FFC in the opposite direction exactly the reverse of the operation to send it towards Link in the first place.

Maybe correct the new path slightly in favor of moving towards the boss's current location to help the player.

Does that make sense?

EDIT: Haha, this just gave me a great idea for a CROSSFIAAAHHHHH boss...

ShadowMancer
09-05-2007, 10:03 PM
Yea, that could work, what I was originally planning is to have the FFC be a 'Slash->Next' combo and react when its Data changed. I just tested it and I guess that FFC's dont work with Slash->Next. oh well. I will try your solution C

Get Link's location relative to the FFC and send the FFC in the opposite direction exactly the reverse of the operation to send it towards Link in the first place.

Maybe correct the new path slightly in favor of moving towards the boss's current location to help the player.

That makes perfect sense, and much easier then all the trig I was trying to do :D
Bassicaly it would be almost the same as your knockback for enemy damage, or something similar. Right now the Aim formula I am useing is:


dx = (Link->X+8) - (this->X+8);
dy = (Link->Y+8) - (this->Y+8);
dist = Sqrt(dx*dx + dy*dy);
this->X += rnd_x + (dx / dist) * spd;
this->Y += rnd_y + (dy / dist) * spd;

If you know a way to reverse the direction that would help greatly.

C-Dawg
09-05-2007, 10:38 PM
Nah, my enemy knockback is really rudimentary. It just moves the enemy away from the player while its damaged each frame. It doesn't pick a direction and go.

As for reversing direction - well, when the FFC realizes it's been hit, just run exactly the same operation you did to send it towards Link... only do it in reverse. I'm not sure what your question is.

If your aim function is this (and I'm probably going to borrow it, thanks ;) ):



dx = (Link->X+8) - (this->X+8);
dy = (Link->Y+8) - (this->Y+8);
dist = Sqrt(dx*dx + dy*dy);
this->Vx += rnd_x + (dx / dist) * spd;
this->Vy += rnd_y + (dy / dist) * spd;


Then the bouncing back function would be:



dx = (Link->X+8) - (this->X+8);
dy = (Link->Y+8) - (this->Y+8);
dist = Sqrt(dx*dx + dy*dy);
this->Vx += -(rnd_x + (dx / dist) * spd);
this->Vy += -(rnd_y + (dy / dist) * spd);


(I assume you meant Vx and Vy rather than X and Y and corrected it. If I corrected in error, then just change your +='s to -=)

ShadowMancer
09-06-2007, 11:04 AM
Well actually it worked with just X and Y but I am going to see what happens when I use Vx and Vy. oh btw the rnd_x and ran_y are just Rand(3)-1 to add a little variance to the aim. Since I was originally using this formula for the rapid fire enemy I did not want every fireball to aim at Link with deadly accuarcy (would be almost imposible to win that way :D ) Yeah the reverse should work fairly well, sometimes the simplest soulitons are the hardest to figure out heh.

C-Dawg
09-06-2007, 12:52 PM
Well you wouldn't want to modify the FFC's route every frame, would you? Just find Link's location once when it fires, plot a course, and set Vx and Vy. You can aim with "deadly accuracy" then, and the player has time to get out of the way.

ShadowMancer
09-06-2007, 04:28 PM
Just to clearify here is my entire script (not tested yet because it is still setup to use FFC Slach->Next which is broken)



ffc script boss_fball {
void run (int spd, int reset) {
//setup vars
npc boss = Screen->LoadNPC(1);
int tnum = this->Data;
this->Data = 0;
int shoot = 0;
int dx = 0;
int dy = 0;
int dist = 0;
int rnd_x = 0;
int rnd_y = 0;
int timer = reset;
while (true) {
if (this->Data == 0) {
boss = Screen->LoadNPC(1);
this->X = boss->X;
this->Y = boss->Y;
timer -= 1;
if (timer <= 0){
this->Data = tnum;
timer = reset;
}
}
if (this->Data == tnum && shoot == 0) {
shoot = 1;
dx = (Link->X+8) - (this->X+8);
dy = (Link->Y+8) - (this->Y+8);
dist = Sqrt(dx*dx + dy*dy);
rnd_x = Rand(2)-1;
rnd_y = Rand(2)-1;
}
if (this->Data != 0 && shoot == 1) {
this->X += rnd_x + (dx / dist) * spd;
this->Y += rnd_y + (dy / dist) * spd;
if (this->Data == (tnum+1)){shoot = 2;}
}
if (this->Data != 0 && shoot == 2) {
//Shot is reflected
this->X += -(rnd_x + (dx / dist) * spd);
this->Y += -(rnd_y + (dy / dist) * spd);
}

if(this->X <0 || this->X > 240 || this->Y <0 || this->Y >160) {
this->Data = 0;
shoot = 0;
}
Waitframe();
}
}
}


Although I do know everything works fine except the untested reflect (but it should work)