God Damned Angles!


devlkore

^_^
Joined
Jul 15, 2004
Messages
274
Website
www.sparktasty.net
Howdy,
I'm having trouble getting things to move in directions other than the four main ones. I know that you need to use "angle" and "advance".

The problem with that is that because the resolution is quite low, it calculates things wrong when it's rounding for the low resolution. This just means you can't go in all directions.

Then there's the "resolution" command, which in theory should solve my problem straight away, but then the angles are all messed up!

I tried multiplying the angle by the resolution (fenix resolution, not screen resolution) to see if "resolution" affected angles too, but that's messed up as well.

Does any know how to fix this or know of any examples (with source) of things moving in ALL directions.

ThanX, BYEEEEE!!
 
By ALL directions, you must have a comething you turn on place and the walk forward, a bit like the Resident Evil controls, right?

If you can explain me in short words how to use the angle and advance commands, I could try to think of a solution (besides that, I`m learning something new :D)
 
Using "angle" is as simple as saying "angle=#;" and "advance" goes something like this "advance(#)" and "resolution" is like this "resolution=#".

The number for "angle" is in thousandths (?) of degrees if I remember correctly, and 0 is to the right, so to make something point upwards, you use "angle = -9000" (I think).

The number for "advance" is how many pixels you want it to move in the direction specified with "angle".

"Resolution" just increases the resolution of the processes co-ordinates. So assuming you set the screen mode to 320x240, if you were to set a processes resolution to 4, it would actually calculate all of it's movement based on 1280x960 resolution.

The thing is, I can use advance and angle together fine, and I can use resolution fine, but I can't use them together without the angles getting messed up.
 
Okay, I didn`t understand that :D Do you have a code segment showing this used on a image or something?

Oh, and could you give me the source for your megarun tech demo? It doesn`t have to be commented...
 
Post your e-mail address and I'll send you the source to both tech demos, the Megarun one is updated (ie, you can run in both directions) and the other one (SNKvsMrT) uses "angle" and "advance", you will see the problem of not using "resolution" in SNKvsMrT when you move back and forward over and over again.
 
Very much so, the angle goes in thousands of a degree, where of course 0 faces right. To get the corresponding angle multiply the 'normal' degree with 1000(90 degree angle would be a 90*1000 = 90000 fenix-degree angle) to get the fenix version.

0 * 1000 = 0 = right
90 * 1000 = 90000 = up
180 * 1000 = 180000 = left
270 * 1000 = 270000 = down
360 * 1000 = 360000 = right

Resolution(local variable, so changable independently for every process) applies only to the x and y coordinates, resolution equals 1 by default, meaning that one pixel on the screen corresponds with 1 step in the x/y value. Setting resolution to for example 10 would mean that one pixel corresponds with 10 steps in x/y value, or the place (100,100) on screen would become(100*10,100*10). It's easy if you want more precise movement, but it can be ugly if you want to measure the distance between two processes(Fenix does not convert the variable scale back automatically).

Advance(INT distance) is easy for movement along the angle the process has, given the amount of steps in the coordinates you want to move. You can of course move backwards with a negative value. The advantage of advance() is that you don't have to worry about the sin/cos you normally would use when trying to advance in a specific direction.

Xadvance(INT angle, INT distance) does the same as advance, but with an extra angle parameter to be added to the current angle before the process is moved. Using zero for angle has the same result Advance() would have with the same distance. Though the advantage shows when you would want to move your process sideways, moving to the left is easy with Xadvance(90000,distance) and to the right with Xadvance(-90000,distance). If you would want to do this with advance you would have to add the angle to the process' angle, then advance(), and afterwards substract the angle again. This does it in one command.

Advance() and Xadvance() use steps, not pixels, so if you use 10 as resolution you will have to multiply the amount you want to advance with 10 too.

One last thing, if you want your process to use angle/advance to move forward and maybe shoot things in that direction, make sure to draw your graphic facing right, you'll get very weird flying bullets if you don't(flying always 90 degrees the wrong way!).
 
ThanX Moogle, I wasn't so sure about Xadvance before. I will definately be using Xadvance in my new game.

Quiest, check your e-mail :p

A quick question, is there any way of referencing the "victim" of a collision check, that is to say that if I have a bullet process (spawned by the player) and an enemy process and I include the collision code on the enemy, so if it touches a bullet type process it dies, would I be able to send commands to the bullet that touched it without doing a separate collision check on the bullet too?
 
That is one of the cool things about processes, all their ID's are odd numbers and considered true in a false-true sense. So if you have been including if(collision(type bullet)) in your code collision didn't return true or false but false or the ID of the colliding process. you can catch this by for example:

Code:
bulletprocess = collision(type bullet);
if(bulletprocess)
  signal(bulletprocess, s_kill);
end

When there are multiple processes of the specified type colliding collision() returns their ID's in consecutive calls to collision(), after all colliding ID's have been cycled through it keeps returning false untill it is reset with a frame command and starts over again.
 
Thanks for that ^^

I asked myself the same question, but didn`t want to ask, because I could do it the other way :D
 
I still don't properly understand it.

All I want is to be able to give commands to a single bullet that touches an enemy ship (for example), to make it disappear.

You lost me on the cycling bit.

Sorry if I sound like an idiot.
 
imagine that you have 3 bullets colliding with your ship. Normally you would've done:
Code:
BulletID = collision(type bullet);
if(BulletID)
  signal(BulletID,s_kill);
end
That doesn't do the trick then, since it would leave two bullets that are colliding too alive. So if you would do this:
Code:
loop
  BulletID = collision(type bullet);
  if(BulletID)
    signal(BulletID,s_kill);
  else
    break;
  end
end
Now, the first time collision is called it returns the ID of one of the colliding bullets. That one gets killed, and in the next iteration collision() gives the ID of the second bullet process, that gets terminated and in the next iteration the ID of the third and last colliding bullet is passed onto BulletID. Needless to say, that bullet had it's days counted. The next iteration there are no colliding bullets that haven't had their ID's passed on already(in fact, those colliding are dead too, but that doesn't matter to collision() ) so collision returns zero. Zero is not true so the break; command gets executed and the loop ends, and all colliding bullets have been taken care of.

Important is that collision doesn't care whether or not the process it passes on gets terminated or not, it just passes on all ID's and after that false. Neater way to write it would be:
Code:
while(BulletID = collision(type bullet))
  signal(BulletID,s_kill);
end
But the first is more understandable I think :)
 
Yup, same with me.
I tried to use this, but It doesn`t get me the result I want...

I think it`s easier to stick to

Code:
Process bullet(x,y)
Begin
 ...
 Loop
  ...
  if(collision type(player))return;end;
  frame;
 end;

Process player(x,y)
Begin
 ...
 Loop
  ...
  if(collision type(bullet))dosomethingelse;end;
  frame;
 end;
 
This is still a bit confusing, funnily enough, the last code snippet Moogle posted actually makes the most sense to me, but "BulletID" still confuses me.

I want to have the collision code on the enemies, not the bullets, because it will be too taxing on the processor to check for collisions for 50+ bullets as opposed to about 3-12 enemies.

Is there any way of coding object A (enemy) to get the ID of object B (bullet) without adding any code to object B?

At the moment, my code looks more like Quiest's, with no ID references, just a simple check for an object, and a "return", but I want more control over everything. The thing is, I don't understand the IDs properly. I know that every process has an ID, but I don't know how to single out one object's ID when it touches something.

I really appreciate the help, ThanX guys.

BYEEEEE!!

PS: Hopefully you'll like the end product to make this worth your time :)
 
No and I don't really want to, I've heard about far too many security holes, plus it's just another annoying thing to install.

Can't ICQ connect to IRC channels, I remember when I did use ICQ and not IRC there was something called IRCQ that was part of ICQ or something.
LA!

I'm off to #gp32dev

BYEEEEE!!
 
Bump.
What is to X as Advance is to Y?

Oops, just shot myself in the foot there, anyways I now know the answer to this, but how could I keep the sprite in the middle of the screen in my mode7 angleised source?
Code:
PROGRAM Mode7samp;

GLOBAL
idg;
f;
BEGIN
set_mode(m320x240);
load_fpg("tut21.fpg"); 
WRITE_INT(0,0,0,0,Offset X);
WRITE_INT(0,260,0,0,offset y);
idg=load_fpg("tut21.fpg");
start_mode7(0,idg,1,0,0,200);
m7.camera=id;
ctype=c_m7;
graphic(); 
y=76;
x=57;
LOOP
IF (key(_up)) advance(3);END

IF (key(_down)) advance(-3);END 
IF (key(_right))angle-=2000;END
IF (key(_left)) angle+=2000;END
Y=f;
FRAME;
END
END

PROCESS graphic()
BEGIN
ctype=c_m7;
graph=2;
x=17;
y=79;
LOOP   
IF (key(_up)) advance(3);END

IF (key(_down)) advance(-3);END
IF (key(_right))Xadvance(-90000,3);y=f;END
IF (key(_left)) Xadvance(90000,3);END
FRAME;
END
END
 
That sort of worked, but the Sprite is now too far away from the screen and I can't seem to fix it.
Plus is there a way to make the camera move around without making the sprite turn?

Code:
PROGRAM Mode7samp;

GLOBAL
idg;
f;
BEGIN
set_mode(m320x240);
load_fpg("tut21.fpg"); 
WRITE_INT(0,0,0,0,Offset X);
WRITE_INT(0,260,0,0,offset y);
idg=load_fpg("tut21.fpg");
start_mode7(0,idg,1,0,0,30);

ctype=c_m7;
graphic(); 
y=76;
x=57;
LOOP
IF (key(_up)) advance(3);END

IF (key(_down)) advance(-3);END 
IF (key(_right))angle-=2000;END
IF (key(_left)) angle+=2000;END
Y=f;
FRAME;
END
END

PROCESS graphic()
BEGIN
ctype=c_m7;

graph=2; 
x=200;
y=76;
m7.camera=id;
LOOP        
size=9000;
IF (key(_up)) advance(3);END

IF (key(_down)) advance(-3);END
IF (key(_right))angle-=2000;END
IF (key(_left)) angle+=2000;END
FRAME;
END
END
 
Back
Top