Might also post at AG.
Alright, what I need is a walkTo(int x1,int x2,int y1, int y2, int speed) void that would move something to x1 to x2 and to y1 to y2... I don't have any idea of how to do it, and I need it so much... I don't know much about trigonometry and such thing, so that's why I would need that one void... Help?
And no loop... It's for use for scripts and such things.
EDIT-Also, speed is how much to move the thing in pixels each time the void is executed.
lucas92 wrote:Might also post at AG.Alright, what I need is a walkTo(int x1,int x2,int y1, int y2, int speed) void that would move something to x1 to x2 and to y1 to y2... I don't have any idea of how to do it, and I need it so much... I don't know much about trigonometry and such thing, so that's why I would need that one void... Help?
And no loop... It's for use for scripts and such things.
EDIT-Also, speed is how much to move the thing in pixels each time the void is executed.
ARGH! The word you're looking for is "function". "void" is a return type. It means that a function does not return anything!
*pant pant pant*
As for your request. So, you want a function that moves... uh, a thing speed pixels in the direction of (x,y)?
Well, an accurate implementation of the function would require an ATan function, which we don't have for some reason. Instead, I propose this naive substitute until we get such a function:
void moveTowards(ffc this, int x, int y, int speed) {
if(this->X < x) {
this->X += speed;
} else if(this->X > x) {
this->X -= speed;
}
if(this->Y < y) {
this->Y += speed;
} else if(this->Y > y) {
this->Y -= speed;
}
}
Oh that's great. 😊
Thank you. It was simpler than I thought. 😊
Wait a minute... It's not so much perfect that function... I mean, it would only go in a direction with a 45 degrees angle... And it isn't what I want... 😞
I guess I will use that one for now...
Well, I just circumvented the lack of ATan, and so you can use this supplemental script, and take its findAngle function to write this script:
import "std.zh"
import "advmath.zh"void moveTowards(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = Sin(angle) * speed;
float dy = Sin(angle) * speed;
this->X += dx;
this->Y += dx;
}
Wow. Just wow.
No doubt I couldn't have done it.
That's just great. Thanks. 😊
DISCLAIMER: I have not tested any of this code, and only know that it compiles. However, if there's any problem with it, please let me know, and I will actually test it.
void moveTowards(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = Cos(angle) * speed;
float dy = Sin(angle) * speed;
if(this->X<x)this->X += dx;
if(this->X>x)this->X -= dx;
if(this->Y<y)this->Y += dy;
if(this->Y>y)this->Y -= dy;
}
Even with the mistakes I fixed, it seems to always follow a 45 degrees line then go up with a 0 degree line...
I've made an example quest... Also try to avoid the armos, it will kill you in one hit... Anyway, I needed that function when it climbs the ceiling.
http://www.mediafire.com/download.php?ytmzfjeemmc
Also there are some mistakes in your advmath.zh file. Missed semicolons and such things.
That's because pkmnfrk is modifying x,y coordinates based off floats instead of storing them in a seperate variable (such as Vx, Vy), I think. Try changing it to this->V and see if that works, or, use this instead:
void Homing(int speed, int ffc_num, int target_x, int target_y){
ffc F=Screen->LoadFFC(ffc_num);
int dx = target_x - F->X;
int dy = target_x - F->Y;
float norm = Sqrt(dx*dx+dy*dy);
if(norm > 0){
F->Vx = dx/norm*speed;
F->Vy = dy/norm*speed;
}
}
edit: Had a spontanious idea to make it better. (untested):
void Homing(int speed, ffc f, int target_x, int target_y){
ffc F=f;
int dx = target_x - F->X;
int dy = target_x - F->Y;
float norm = Sqrt(dx*dx+dy*dy);
if(norm > 0){
F->Vx = dx/norm*speed;
F->Vy = dy/norm*speed;
}
}
Well, my code should work if you change the second Sin to a Cos (brain fart).
But, I would recommend against using the Vx and Vy variables for this purpose. Reason? If for some reason you stop calling moveTo(), the Vx and Vy variables won't magically revert to zero, and the ffc will continue to move.
Heh, I didn't see that either. :eyebrow:
I've had less than adequate results in the past with ZC trying to modify an objects screen position with decimal places though. (I stopped doing it altogether actually) Just thought I'd point that out.
Well, I don't see any particular reason why it wouldn't work (assuming the engine doesn't truncate the positions), but if you're concerned about it:
import "std.zh"
import "advmath.zh"void moveTowards(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = Sin(angle) * speed;
float dy = Cos(angle) * speed;
this->X += Floor(dx);
this->Y += Floor(dx);
}
Cool I'll try that out... Btw, happy new year! 😊
Gleeok wrote:I've had less than adequate results in the past with ZC trying to modify an objects screen position with decimal places though. (I stopped doing it altogether actually) Just thought I'd point that out.
while(true){
Link->X += move(this->Vx,counterx);
Link->Y += move(this->Vy,countery);
counterx = (counterx+1)%(100/factors100(Abs(this->Vx)));
countery = (countery+1)%(100/factors100(Abs(this->Vy)));
}
int move(int s,int c){
int as = Abs(s);
int ret;
if(as < 1){
if(c < as*100/factors100(as)) ret = 1;
else ret = 0;
}else if(as < 2){
if(c < (as-1)*100/factors100(as-1)) ret = 2;
else ret = 1;
}
if(s < 0) ret = -ret;
return ret;
}
int factors100(int s){
for(int i=50;i>0;i--) if((s*100)%i == 0) return i;
}
Takes a speed, and moves an object that doesn't have a Vx/Vy value at that speed. Currently works (well, it works mostly. Some speeds are a little out) for speeds from 0 to 2 (not inclusive).
I'm sure it's not the best way, but I'm quite proud of it. Took me a while to think up.
Obviously you can't actually move an object by half a pixel, that just doesn't make sense.
pkmnfrk wrote:Well, I don't see any particular reason why it wouldn't work (assuming the engine doesn't truncate the positions), but if you're concerned about it:import "std.zh"
import "advmath.zh"void moveTowards(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = Sin(angle) * speed;
float dy = Cos(angle) * speed;
this->X += Floor(dx);
this->Y += Floor(dx);
}
That still doesn't work... It goes an another time with a 45 degrees line... 😞
Also goes always right when it has to go left...
lucas92 wrote:That still doesn't work... It goes an another time with a 45 degrees line... 😞
Also goes always right when it has to go left...
Hang on, maybe I'll just, you know, test it.
EDIT: For cripes sake. I figured out why I was stupid.
import "advmath.zh"void moveTowards(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = RadianSin(angle) * speed;
float dy = RadianCos(angle) * speed;
this->X += dx;
this->Y += dy;
}
ffc script followLink {
void run() {
while(true) {
moveTowards(this, Link->X, Link->Y, 1);
Waitframe();
}
}
}
I fixed a typo, and remembered that findAngle uses Radians, not Degrees. So, I switched Sin and Cos to RadianSin and RadianCos, and it works. It works without rounding off the decimal place, too.
And, since I tested it, I can now say that I guarantee this will work, or your money back.
Still doesn't work... When it has to go up, it goes down, and also it goes left when it has to go right(when it has to go up)... And I did tested your ffc script... 😞
Hold on a minute...
Shouldn't the code be...
import "advmath.zh"void moveTowards(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = RadianCos(angle) * speed;
float dy = RadianSin(angle) * speed;
this->X += dx;
this->Y += dy;
}
ffc script followLink {
void run() {
while(true) {
moveTowards(this, Link->X, Link->Y, 1);
Waitframe();
}
}
}
Changes I made are in bold.
It doesn't matter which way round you use them.
Well, it does matter, but either way, I tested my script, and it worked. So... I dunno what to say. Make sure you're passing a positive speed... that's the only way I can think of to make it go backwards...
?
Plotting y=sint,x=cost is exactly the same as plotting y=cost,x=sint
That doesn't make any sense. For that to be true, COS(t) would have to equal SIN(t), which it does not.
http://www.themathpage.com/atrig/graphs-trig.htm#sine%20graph
http://www.themathpage.com/atrig/graphs-trig.htm#cosine
It's the same wave, but offset by 1/2 Pi
I know the difference between sine and cosine.
It does, however, make sense.
When plotting a circle parametrically, it doesn't matter whether you use sine or cosine on the x or y, provided you don't use them for both (otherwise you'll get a diagonal line, which makes sense as y = x).
Have a look:
ffc script circle{
void run(){
int x = 80; int y = 80;
int r = 32;
while(true){
for(int i;i<360;i++){
int x2 = y+r*Cos(i);
int y2 = x+r*Sin(i);
Screen->PutPixel(6,x2,y2,Rand(10),0,0,0,128);
}
Waitframe();
}
}
}
Will produce the exact same result as:
ffc script circle{
void run(){
int x = 80; int y = 80;
int r = 32;
while(true){
for(int i;i<360;i++){
int x2 = y+r*Sin(i);
int y2 = x+r*Cos(i);
Screen->PutPixel(6,x2,y2,Rand(10),0,0,0,128);
}
Waitframe();
}
}
}
Maybe for plotting a circle, but I believe in experimental data.
The script:
import "advmath.zh"void moveTowards1(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = RadianSin(angle) * speed;
float dy = RadianCos(angle) * speed;
this->X += dx;
this->Y += dy;
}
void moveTowards2(ffc this, int x, int y, int speed) {
int angle = findAngle(this->X, this->Y, x, y);
float dx = RadianCos(angle) * speed;
float dy = RadianSin(angle) * speed;
this->X += dx;
this->Y += dy;
}
ffc script followLink {
void run(int method) {
while(true) {
if(method==1) {
moveTowards1(this, Link->X, Link->Y, 1);
} else if(method==2) {
moveTowards2(this, Link->X, Link->Y, 1);
}
Waitframe();
}
}
}
The results:
On YouTube
FFC #1 calls "moveTowards1", while #2 calls "moveTowards2". Only #1 behaves properly.
Oh, you're making triangles.
Should've read the thread a bit more carefully before I posted really.
It does work for circles though, trust me =P
Hahaha.. "ALL YOUR BASE ARE BELONG TO US!!!" I forgot about that shit. 😃
Yeah, you're both right, and on a related note, It took me way too long to figure out this one:
x += cos(rad)*speed;
y += sin(rad)*speed;
That's the way it goes though, you feel like a dumbass, then a genius, then a dumbass again when you realize that you just figured out something everyone uses already that you probably could've googled in the first place.
I'll take a look at that script a little later joe, thanks...although watching pkmnfrk's video, there doesn't seem to be a problem with that...(maybe it was a bug in an older build?) So FFC's coordinates are stored in floats I guess.
Just be careful about checking absolute position if you use my script, since FFCs won't necessarily be pixel-aligned any more.
So, if you need to check an exact position, do something like:
if(Floor(theffc->X) == 120 && Floor(theffc->Y) == 80) //do something
If I use this on Link (assuming I can); will Link walk, or will he "float"?
Ya, I think you can. Just change "this->" into "Link->". However, he won't animate, he'll just float like you said. And you will probably need to stop the player from pressing any of the direction buttons.
Ok. I know how to get link to walk.
If Link walks over a tile/side warp, will he go where the warp says to go?