Hello Guest, please login or register.
Did you miss your activation email?
Login with username, password and session length.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - aab

Pages: [1]
1
Coding / old tutorial on referencing
« on: September 18, 2007, 03:51:00 pm »

Old one that i did a while ago; Couldnt find it ona  search but someone asked about it so here it is again.



A simple tutorial on using an alias for a variable.

This is quite an early tutorial, however the last part 'mentions' security and efficiency of a class, and requires many months of phsycological C++'ing to go through completely.

There is ALOT to read through, but its seperated into chunks so if you only want to hear of a chunk at a time ok.
Ok..so the chunks each have alot to read through themselves... But it should read quickly as i analyse and explain in the detail that exists...
Some people say in detail, yes, but when i say the detail that exists... i mean everything.

Anyway, the chunks read fast, and theres no summary as the point is...after you read through this, you will never forget lol.





You may have already come accross the method of aliasing variables before realising other uses of it, in the form of a referenced parameter.

For that reason I'll refer to them as references (Also because my grammers horrible and im not sure how to use the word 'alias' properly).


Referencing Parameters (Most of you can read past this part)

   Assuming you can create a function, and pass parameters to a function:


   When you pass parameters to a function, you are giving it a value that it can use to vary what it does, and how it does it.
   Inside that function, there can be if statements and arithmetic operations which vary the results of the operations in that function:
   
   This is neat as you can use that function many times, and each time it will act slightly differently depending on how you want it to.

   So, eg you could make a function NewLines, that prints a new line the number of times you ask it to:
   
Code: [Select]
#include<iosteam>

void NewLines ( int numNewLines )
{
for( int t=0; t<numNewLines ; ++t )
{
std::cout<<std::endl;
}
}

int main()
{
using namespace std;

int numberOfGaps = 5;

cout<< "start" ;
NewLines ( numberOfGaps ) ; //print 5 new lines
cout<< "end" ;

cin.get();
return 0;
}

      The parameter in the function (eg: numNewLines) is a new variable, created inside that function, for its use only.
   When you call the function and pass a parameter (eg: NewLines( numberOfGaps ) ), it makes the new variable in the function, and makes its value equal to the variable you pass, at the very start of the function.
   /*Strictly, It doesnt eg go 'int numNewLines=numberOfGaps;' when the function is called, however for standard variables (int,float,double etc) the effect of what it does do is the same.*/
   However, because the parameter in the function was only made equal to the variable passed to it at the start of the function, any changes to the variable inside the function, arent going to affect the variable outside the function. The functions variable only copies the value of the passed variable: They are not the same.

   But what if you wanted to get some value back from the function?
   Well you can return ( assuming you know what that is: If you dont you dont
   need to to understand this section of this tutorial ).
   Unless you return some sort of object, or a value with a meaning to you (eg: if(1) doA() else if(2) doB() else.. ) your limited here, until you learn that you can reference parameters.

   This is where references are usefull:
   Referenced parameters are actually the same as the variable that is passed into the function:
   They may have a different name, but as long as they are the same type, its compiles.
   Therefore changes to the variable inside the function, are changes to the variable outside the function.
   Thus, this variable can be called an 'alias' (Same thing, but different name);

   This type of parameter can also be called a 'reference', because it 'references the location of the parameter passed to the function', wheras a normal parameter (eg: int numNewLines) creates a new variable in a new location, and copies the value from the passed parameters location into its location.

   The syntax for a referencing parameter is to put an ampersand inbetween the typename and the variables identifier.
   eg:
   
Code: [Select]
void MyFunction ( int & parameter )
{
// [b]. . .[/b]
}
   The '&' symbol, when placed infront of a variable (not inbetween two variables) means 'address of'.
   Lets look at that again, with 'address of' in place, to see how much that makes sense: void MyFunction ( int address of parameter )
   
   If youve used pointers
   {
      Youll see this healthily makes the same sense as it does when assinging a pointer to a variable:

         int x;
         int*px = &x; // px = address of x;

      In addition, note the reverse of using '*'.

      '*' infront of a variable (not inbetween two variables) means 'whats at the address'.
      Such that you can (continuing from above) go:
      
         int y = *px;   // y = 'whats at the address' px  // same result as going y = x;

      And when declaring pointers:

         int 'whats at the address' pointer;
      
      See?.Pointer syntax is incredibly sensible.

      If you have used pointers, youll already know that you could use pointers to do the above, eg:
      
Code: [Select]
void MyFunction ( int * aparameter )
{
*aparameter = 34;
// [b]. . .[/b]
}
      But what if someone calls this like so: MyFunction(0)
      Well, the best possible thing that could happen is the program crashing at runtime.
      You could add in a check that it wasnt 0...But still someone could pass any number
      in, C-cast to a pointer.
      So, by using references, the function is safer, easier to use, and easier to write.
   }

   So now, you can make a function that changes the values of its parameters.
   
   So for example:
   
Code: [Select]
#include<iostream>

void DontMakeFive( int x )
{
x = 5;
}

void MakeFive( int &x )
{
x = 5;
}

int main()
{
using namespace std;

int value = 32; // value is 32


DontMakeFive( value ); // wont do anything as the 'x' in that function is just a copy.

cout<< value ; // =>this will print out '32'


MakeFive( value ); // will change values value.

cout<< value ; // =>this will print out '5'


cin.get();
return 0;
}


   Something you cant do:

   You couldnt call the above like so:

   MakeFive( 45 );

   This is self explanitory of course...You cant make 45, 5.
   In particular, because 45, written into your program, is not a variable: Its a literal value embedded into your compiled code.
   Its not like you can go 45 = 5;





Variable Reference (within same function)

   A declared variable can actually be a reference, and be made '=' to another when declared. In doing this, the two variables are the same, but there are two names for this variable. Several languages dont allow this kind of thing. You can write utterly occluded code, eg:

      x = 5;
      y = 10;
      cout<< x; //prints 10, not 5. lol....How Evil.

   Thats the very minimal of the evil that you can accomplish in C++...But in programming, writing good code is more fun, so well think about how this is usefull.

   This referencing variable is created like so:

      int x;

      int &also_x = x;

      //      eg:
      x=5;
      cout<< also_x;

      This is an 'implicit' property: There are very many in most programming langauges.
      What i mean by 'implicit', is that the what you have written doesnt explicitly compile as it is (ie its the opposite of 'explicit').
   
         ie: the compiler will do things <to the copy of the code it makes for compilation>.
      
      You can think of the compiler implicitly replacing 'also_x' with 'x', and then removing your line of code 'int &also_x = x;' before it compiles to the final object code that can be run by the computer;
      

      The compiler will also do these kind of things for constants and enumerates eg:
         
Code: [Select]

int player_health;
const int max_health = 20;

/*
[b]. . . [/b]
*/

//make players health maximum:

player_health = max_health; //v will be replaced with 20


         You can see constants like that are usefull, as if you wanted to change max_health, you wouldnt have to go through every time you used it, and change it to the new literal value (eg 22 ).
         Its also alot more meaningfull.

         But why would you want to reference a variable?
         I mean...You already have the first one..Whats the point.


         Well..You could sometimes use it to make code thats more readable, or uses less variables

         For example, say you had a file, with someones age, then someones height (as ints), and wanted to print them out:
         //Just pretend ive int main, and #include< using namepacce etc:
         
Code: [Select]
int read_value;
ifstream file( "john.txt" );

file>>read_value;
cout<< "John is " <<read_value<< " Years old ";

file>>read_value;
cout<< "and is" << read_value << "cm tall";

file.close();
         Well, thats ok, but read_value is not a very meaningfull variable name. Ok so who cares in that tiny little snippet of code, anyone can read the next line and see what its being used for. But what about a massive program, with a great deal of reads and outs, and not much meaning around that code?
         Well:
         
Code: [Select]
int
johnsAge,
johnsHeight
;
ifstream file( "john.txt" );

file>>johnsAge;
cout<< "John is " <<johnsAge<< " Years old ";

file>>johnsHeight;
cout<< "and is" << johnsHeight << "cm tall";

file.close();
         hmm...I liked it better the other way as you only had one variable..Now there are two. Duh that thats not good.
         So..Reference anyone?
         
Code: [Select]
int read_value;
int
&johnsAge = read_value,
&johnsHeight= read_value
;
ifstream file( "john.txt" );

file>>johnsAge;
cout<< "John is " <<johnsAge<< " Years old ";

file>>johnsHeight;
cout<< "and is" << johnsHeight << "cm tall";

file.close();
         Of course, there still exists the possibilty of confusion by someone later on changing one and not realising the change on the other...
         So, you *could* use a confinement on the variables access space:
         
Code: [Select]
int read_value;

ifstream file( "john.txt" );

{
int &johnsAge = read_value;
file>>johnsAge;
cout<< "John is " <<johnsAge<< " Years old ";
}

{
int &johnsHeight= read_value;
file>>johnsHeight;
cout<< "and is" << johnsHeight << "cm tall";
}

file.close();
         A rather simple and slow example that was i suppose....But now lets think about it when weve a large program with lots of nested classes, and we want to do something like:
         
Code: [Select]
for(int t=0; t<GameEngine->GameArea->tiles[player->Body.Layer].num_tiles(); ++t)
{

if(GameEngine->GameArea->tiles[player->Body.Layer][t].CollType)
{


pnt.x = GameEngine->GameArea->tiles[player->Body.Layer][t].x;
pnt.y = GameEngine->GameArea->tiles[player->Body.Layer][t].y;

if( PtInRect(&CloseRect,pnt) )
{

ApplyCollision
(
GameEngine->GameArea->tiles[player->Body.Layer][t].CollType,
&Crect,
GameEngine->GameArea->tiles[player->Body.Layer][t].x,
GameEngine->GameArea->tiles[player->Body.Layer][t].y
);

//and so on.....
         //Pretend you dont know about efficient address iterating if you do.
         Well...thats repeating something...Hard to read..ugly.
         Lets do this instead:
         
Code: [Select]

MyTileGrid & tileList = GameEngine->GameArea->tiles[player->Body.Layer];

for(int t=0; t<tileList.size(); ++t)
{

if( tileGrid[t].CollType)
{


pnt.x = tileList[t].x;
pnt.y = tileList[t].y;

if( PtInRect(&CloseRect,pnt) )
{

ApplyCollision
(
tileList[t].CollType,
&Crect,
tileList[t].x,
tileList[t].y
);

//and so on.....
         Much better, wouldnt you agree?
         And ill bet some of you will look at the first one adn go: "Whait..maybe tommorw..or next year or something" But, if you saw the second version in an example, you'd be ok.


         Another thing to note: A reference must be initiated with a variable to reference.
         eg:
            int&x;
         Is illegal because x has no variable to alias...nothing to be replaced with.


References in a Class(Youll need to know more than the above for this stuff)

   A class can have a reference member.
   
   However, remmember that a reference must be initialised with a variable to reference.

   You must therefore pass a variable to the classes constructor, and this must be assigned to the reference member on its initialisation, which can only be done through the implicit constructor initialisation:
   If youve not done that yourself, youll have to find its explanation somewhere else for now.

   eg:
   
Code: [Select]
class my_class
{
int &reference_member;

public:

explicit //if you dont know why this is here : It stops the compiler using this constructor for casting an integer to my_class (eg you could go instanceOfMyClass = x; and it wouldnt mind.
my_class(int&to_be_referenced):
reference_member( to_be_referenced ) //'reference_membe' initialised with the variable 'to_be_referenced'
{
}
};

   There are situations where this can be usefull, and its again safer than using pointers.

   Now...Lets consider a class referncing its own members:

   
Code: [Select]
class my_class
{
int &reference_member;
int member_to_be_referenced ; //I dont support variable names this long but ..just an examplifying name.

public:

my_class():
reference_member( member_to_be_referenced ) //'reference_membe' initialised with the variable 'to_be_referenced'
{
}
};

   Not much point...
   There may be a little point in doing something like this i suppose:
   
Code: [Select]
struct color
{
char
samples[4],
&red,
&green,
&blue,
&alpha;

color():
red ( samples[0] ),
green ( samples[1] ),
blue ( samples[2] )
alpha ( samples[3] )
{
}
};
   This would allow someone to use this color class in various ways easily.



   But heres something nice and usefull.

   You know how it can be annoying..writing a get function for all these variables in your class, just so that is safer (people not being able to change data and such that would compromise the integrity of the class), just return a copy of the values they want to know:
   
Code: [Select]
class my_class
{
int a,b,c,d,e,f;
public:
inline int geta()const{ return a;};
inline int getb()const{ return b;};
inline int getc()const{ return c;};
inline int getd()const{ return d;};
inline int gete()const{ return e;};
inline int getf()const{ return f;};
};
   Now that not might be that ugly in that example, but if a,b,c,d,e,f are all different sizes, its a mess to read.
   Well...A public const member could be accessed from outsid the class, but wouldnt be allowed to be changed.

   So...What about a const reference to that member instead of a get function?
   Seems very sensible doesnt it?
   You want the person to access the values, but withought changing them, and thats exactly what it would do.
   It would replace the refernces name with the refferred, but not allow the user to change it.

   So, for example:
   
Code: [Select]
class my_class
{
int a,b,c,d,e,f;
public:
const int
&const_a,
&const_b,
&const_c,
&const_d,
&const_e,
&const_f;

my_class():
const_a( a ),
const_b( b ),
const_c( c ),
const_d( d ),
const_e( e ),
const_f( f )
{
}
};
   Does that not make you happier?

   You could always make it very small and simple, like:
   
Code: [Select]
class my_class
{
int a_,b_,c_,d_,e_,f_;
public:
const int &a,&b,&c,&d,&e,&f;
my_class():
a(a_),b(b_),c(c_),d(d_),e(e_),f(f_)
{
}
};

   However naming the members const_a is a good idea as it tells the user of the class that its const.
   geta would always be immediately thought of as a function...
   Ill leave the dilemma of how to name these things up to you.....

   Final thing to mention, is that to remmember to consider what happens when the default
   copy constructor and operator= are called.
   The references would be muddled up, referencing variables from the other class, so the compiler,
   in making sure this is recognised, doesnt create a default operator=() or copy constructor.
   Simply define them yourself, withought equating the refernces of course.




Oh and btw....This is all my own heuristic observation so feel free to comment. But i trust myself.

























2
Other Discussion / Ask a Scotsman
« on: August 13, 2007, 03:08:51 am »
Go, ask.
Here to seperate the legends, the myths, the facts...

For example, i am neither drunk nor ginger, but i love whisky and have a ginger beard.

3
LTTP & FSA / [LTTP] 8-Directional Link
« on: June 21, 2006, 12:25:34 pm »
If anyone could (save me time), Lttp link walking, slashing, shooting, hammering, in 8 directions, thank you.



I'd like these new frames in the 16*16 format like the lttp link shown above, however thats an optional part of the request as it wouldnt take me any time to do that myself; As long as they fit into being sliced into 16*16 boxes, they will be fine. I appreciate that slashing and bow shooting might have to overlap horizontally onto two 16*16 frames.
Only one version of everything is needed: ie if flippable or rotatable, that will be done in program, not on the sprite sheet (which should only have the one facing directions, being the one that faces Rightmost).

Also note that as there are already diagonal frames fo standing (from the spin attack) in might be suitable to just edit them with walking and slashing alternatives.

4
Coding / [Example / Listing] 'Proper' Diagonal movement
« on: June 19, 2006, 09:20:13 pm »
Introduction

This is a tutorial about making a character move the right distance when moving diagonally, and not moving too fast.
ie When x is increased by a value, and y is increased by a value, the total distance moved is faster than i would be if the user just moved along x or along y.

Someone asked me about this, so i replied in style  :D



This tutorial can be applied to almost any language: Correctly sized diagonal movement is a very simple thing, but also quite important. Everyone should implement this concept in their games as:
(A) its very easy, and
(B) moving too fast diagonally gives people easy ways to avoid enemies, and looks and feels very wrong.

The example code used is Pseudo.
Comments are C++ style '// comment till end of line', and C-style /* comment till :*/ .

You must understand or know of pythagoras theorum to do read Method(A) below, and be able to use sine and cosine to understand Method(B).



Contents / Overview

Firstly, DIAGRAM HERE.
(Open in new window so you can Alt+Tab between text and diagram)
(contains all figures used in this tutorial)

A common approach to movement in fangames is to have X change by 'speed' and have Y change by 'speed'. However, when the user wants the character to mvoe in both an X direction, and a Y direction, the diagonal movement ends up too fast (see fig 0 ).

There are two ways of understanding how to fix this: One (I'll call 'B') is more general/mathematical, and can be applied to moving in any direction (not just 8 direction moving that we want). The other (I'll call 'A' ) is more geometric and intuitive. Youll have guessed by now that ill do A first. :)

...

For this method, it must be understood that if a triangle has sides of length a, b, c, and the entire triangle is scaled uniformally such that a is q times larger, then the new triangles lengths are q*a, q*b, q*c.
ie, let triangle ABC be a scaled copy off of triangle abc, such that A = q*a.

Then: B = q*b, and C = q*c.

(See fig 1).



Method(A):

We want the diagonal movement of the player to be of length 'speed', but when moving in both an x and a y direction, it ends up larger than speed.
How much larger though?

We can only move our character in terms of his x coordinate and y coordinate.
So, we can check if we are moving diagonally: If we are, reduce the x movement (xmove) and y movement (ymove) so that the diagonal movement is smaller.
Our current algorithm:

Code: [Select]

  /*
Just pretend that the amount of x to move, and amount of y to move are calculated by this.
The actual code might involve if KeyDown(LeftArrow) then xmove = -1 and so on
  */

GetMovement( xmove, ymove ) 

  /*
Our algorithm:
  */

if ( xmove is not 0 ) and ( ymove is not 0 ) // moving in both x and y directions, ie diagonally

x = x + fraction * xmove // Where fraction is less than 1, so that movement is reduced.
y = y + fraction * ymove //

else

x = x + xmove // We could further question if xmove was 0 and only change y.
y = y + ymove // But this is simple and neat as it is.



If we find out what the value of fraction is, we can have equal movement in 8 directions.

Consider the case where speed is 1. Then the total distance moved ends up as sqrt( 1*1 + 1*1 ), by pythagoras (where sqrt( A ) means 'the square root of A' ).
So it ends up as sqrt( 1 + 1 ) --> sqrt( 2 )
Look at Fig 0: if speed was 1, the 'actual movement' would be sqrt( 2 ).

This is sqrt( 2 ) times too much;
ie:
   speed = 1,
   'actual movement' = sqrt( 2 )

So, the diagonal 'actual movement' = sqrt( 2 ) * speed, which is sqrt( 2 ) times the value we want 'actual movement' to be. If we divide 'actual movement' by sqrt( 2 ), then we will get speed ( in this case we tested, where speed = 1 ).
Of course (of course!) we cannot just change speed to a lower value as 'actual movement' will decrease also. However, its not only true that 'actual movement' is sqrt( 2 ) times as much as speed, for speed = 1. It doesnt matter what speed is: actual movement is always sqrt( 2 ) times as much.
Reassuring example (though obviously not proof):
speed = 3
'actual movement' = sqrt( 3*3 + 3*3 ) = sqrt( 18 ) = sqrt( 9 * 2) = sqrt( 2 ) * sqrt( 9 ) = sqrt( 2 ) * 3 = sqrt( 2 ) * speed
, which is sqrt( 2 ) times too much!


Now, consider a triangle whos diagonal side is of length 'speed'. We could scale the triangle with lengths 'xmove', 'ymove' and 'actual length' down, such that its lengths were Axmove, Bymove, and speed. (See fig 2 ) So, by the triangle scale rule, because to scale down from 'actual length' to 'speed', you need to divide by sqrt( 2 ) (as weve shown), then that means also that:
Axmove = xmove / sqrt( 2 )
Bymove = ymove / sqrt( 2 )

Because this triangle has diagonal length 'speed', then the x and y values we went to move are the length of the other sides, so we just need to find out what these lengths are, and convert xmove and ymove to them when moving diagonally.

If you look back at the algorithm above, youll remmember that we wanted fraction*xmove and fraction*ymove to be such that when moving those by those values, the diagonal movement ended up as 'speed'.
Well, using the triangle we just scaled, Axmove = fraction*xmove, and Bymove = fraction*ymove.
So,
fraction*xmove = xmove / sqrt( 2 )
fraction*ymove = ymove / sqrt( 2 )

( See fig 2 )

Therefore fraction = 1 / sqrt( 2 ).
sqrt( 2 ) is approximately 1.414, and 1/sqrt(2  ) is approximately 0.707.
Rather than actually using expensive sqrt commands, just making fraction a constant in the above code, such that fraction = 0.707, will mean that everything is solved!
(or put in the values of fraction: Though that makes things less readable and harder to change).


Method(B):

The second way of understanding this is through trigonometry.

A circle has equal distance from its centre, to the point on its edge/circumference in any direction. For example, if you wanted to draw a perfect, circle, but your compass was cheap and crap (most cheap ones are), you would only need another pencil: Rotate it from the centre of the circle, and keep the pencil your drawing with at the same position as rotate the 'radius' pencil. Its hard to keep the pencil in place, but it proves the point.
The x component from the circles centre to any point on its circumference, and the same y component, can be calculated using the length from the centre to this point (ie radius) and the angle.
The angles for 8 directions are every 45 degrees from 0?? to 360?? (or every Pi/4 degrees from 0 to 2*Pi in radians)

Where r is the radius, and A is the angle,
x = r * cos ( A )
y = r * sin ( A )
   
Ill point out that for anyone worries about wether it should be '-', or about converting coordinates to upside down pc screens ...All you have to do is think vertically flipped. No 'conversion' is ever needed in code. Its not like you though up was 'positive' before maths class anyway!

r is speed of course (calculations from the circle allowing us equal movement in any direction), and A is of the set  k * 45?? (or Pi/4) where k = ?? 0, 1, 2, 3 ...


So, cos of A and sin of A will be one of ?? 1 / sqrt( 2 ) for 45??, 135??, 225??, 315??, and either 1 or 0 for 0??, 90??, 180??, 270??.

Right is 0??.
Down and to the right is 45??
Down is 90??
Down and to the left is 135?? etc.

Example1:
When moving left  ( direction: 180??), x = r * cos( 180?? ), y = r * sin( 180?? )    =>   x = r * (-1),  y = r * 0  =>   x = -r,  y = 0, which is perfectly moving left by a distance of 'r'.

Example2:
When moving down and to the right (45??), x = r * cos( 45?? ), y = r * sin( 45?? ) = > x = r * 1/sqrt( 2 ), y = r* 1/ sqrt( 2 ).
Checking the total distance moved, we get:
distance = sqrt(  ( r * 1/sqrt( 2 ) )^2  +  ( r* 1/ sqrt( 2 ) )^2 )
= sqrt( r*r / sqrt(2)*sqrt(2)  +   r*r / sqrt(2)*sqrt(2)  )
= sqrt( r*r / 2 + r*r /2 )
= sqrt( 2*( r*r/2) )
= sqrt( r*r )
= r
which is the distance we want to move.
x and y both move positively, and so the movement is right and down.

This shows that the x = r * 1/sqrt( 2 ), and y = r * 1/sqrt( 2 ) when at 45??.
For other angles, the signs work out as well, and as r = speed, we have:

x = speed * 1/sqrt( 2 )
y = speed * 1/sqrt( 2 )

So fraction is 1/sqrt( 2 ) as before.


Corollary

Because Trigonometry allows direction in any angle, we can do more things with these ideas:

First it must be known that to find the angle from an x and y movement, you take the arctan of y/x.
How this is defined depends on your api, but it may be something like: arctan( y, x ) or atan( y, x ).
To find the radius, we use pythagoras ie sqrt( x*x + y*y ), as you know.


cos and sin can be used in code as well, to allow you to move in any direction:
x = x + speed * cos ( Angle );
y = y + speed * sin ( Angle );
This can be used for things such as fireballs that some lanterns shoot at you in zelda games, or the bones that stalfos throw at you.
Because cos and sin are not the fastest things in the world, if your 'bone' or fireball keeps moving in the direction it started in until it hits a wall, you can store off the cos of the angle and sin of the angle in an xmove and ymove particularly for the bone.

Sometimes, you might want things that change direction constantly.

Consider teh vulture in The legend of Zelda: A link to the past - The one that circles around you in the Desert Of Mystery.
For a simple emulation, You could make its position:
vulture.x = player.x + radius * cos( Angle )
vulture.y = player.y + radius * sin( Angle )
Angle = Angle + 3??

Then it would spin around the player in a circle, as angle increases.
Adding in a check for Angle being >= 360??, and then reducing it by 360?? so its looping back round again, would be worth it, just so that its better for cos and sin to use (less accuracy for very large numbers), and that its easier for you to query the value of Angle for eg being >180 so that means vulture is above player etc.
To further simulate the vulture, by making radius increase, the vulture will move outwards in a spiral, getting further away while rotating around the player.
By decreasing, he will get closer and closer to the player.
If you make it decrease until a minimum, then increase towards a maximum then decrease again etc, you can make the vulture move in and out while circling the player like the link to the past one does.
Cubic polynomials could be used more cheaply to make this very smoothly, or just sin like so:
radius = ( BiggestRadius + SmallestRadius ) *0.5   + (BiggestRadius - SmallestRadius)*0.5*sin( RadiusChange )

Where RadiusChange ranges through 0 to 360.
( BiggestRadius + SmallestRadius ) *0.5 is the MiddleRadius, and (BiggestRadius - SmallestRadius)*0.5 is how much to add to that to get the biggest radius, as well as how much to subtract to get the smallest radius.
Because sin goes smoothly (continuously) from
0 up to 1, down to 0, down to -1, up to 0 and so on,
then radius will go from:
Middle up to Biggest, down to Middle, Down to Smallest, Up to Middle and so on.




Notes

Final note: If trying to mimic The legend of Zelda: Link to the past, notice that link actually moves slower diagonally than left ot right. fraction would be less than 1/ sqrt( 2 )



References

[1] Me. ::)

[/font]

5
Other Discussion / MOVED: Windows
« on: June 06, 2006, 09:46:02 pm »
This topic has been moved to Spam.

http://www.zfgc.com/index.php?topic=3855.0

If brought up as a discussion about the differences between Operating systems it might have been different...

6
Graphics / Boss: Puppet
« on: April 15, 2006, 07:30:33 pm »
To use as a boss, will have to be programmed with rotating components etc:

Click thumbnail

7
Discussion / How'd you rather play Z on phone
« on: April 07, 2006, 11:13:38 pm »
These two mock-ups show the scaled up, and normal pixeled versions on a screen size of 176*220.

If you could, post opinions and if you think assuming a screen size such as that is assuming too much, and that a much smaller screen size should be assumed etc.
Thanks.

Also: consider that the phones actual screen probably wont be as big on your phone as the examples above are, though the pixels will be defined as the examples

Pages: [1]

Contact Us | Legal | Advertise Here
2013 © ZFGC, All Rights Reserved



Page created in 0.051 seconds with 31 queries.

anything