gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > move sprite into any degree?

#9863 - jenswa - Wed Aug 20, 2003 2:27 pm

I know how to rotate a sprite,

but i cannot move the sprite into that direction.
With the degrees, sine and cosine i can calculate how many pixels it should
move in a direction, but i don't get it to work.
Sprites 'flies' off screen.
Can someone explain me how to do this on the gba.
_________________
It seems this wasn't lost after all.

#9866 - iuiz - Wed Aug 20, 2003 4:00 pm

I think there is a bug in your calculating function...

Can you post it (please with comments in your Code).

#9894 - jenswa - Thu Aug 21, 2003 12:03 pm

Here is the code:
Code:

#include "gba.h"
#include "sprite.h"
#include "keypad.h"
#include "dispcnt.h"
#include "car.h"

//sine and consine lookup tables
#include "sincosrad.h"

//variables
int xpos = 120;
int ypos = 60;
s32 move = 2;
s32 dx = 2;
s32 dy = 2;



//chaning dx and dy
void ChangeAngle()
{
   //angle+180, because the car faces down in the pic
   dx = (s32)(COS[angle + 180] * move);
   dy = (s32)(SIN[angle + 180] * move);

}

void GetInput()
{
   if(!(*KEYS & KEY_LEFT))
   {
       angle--;
      if(angle < 0)
         angle = 359;
   }
   if(!(*KEYS & KEY_RIGHT))
   {
      angle++;
      if(angle > 359)
         angle = 0;
   }
   if(!(*KEYS & KEY_A))
   {
      if(ypos < 160 && ypos > 0)
      {
         ypos+=dy;
      }
      if(xpos < 240 && xpos > 0)
      {
         xpos+=dx;
      }
   }
}

int main()
{
   int x;

   //set mode 1 and enable sprites and 1d mapping
   SetMode(MODE_1 | OBJ_ENABLE | OBJ_MAP_1D);

   //load sprite palette
   for(x = 0; x < 256; x++)
      OBJPaletteMem[x] = carPalette[x];

   //set sprites to off screen
   InitializeSprites();

   //set car attributes (rotation 16x16 xpos ypos size doulbe rot flag 256 color)
   sprites[0].attribute0 = COLOR_256 | SQUARE | ROTATION_FLAG | SIZE_DOUBLE | ypos;
   sprites[0].attribute1 = SIZE_16 | ROTDATA(0) | xpos;
   sprites[0].attribute2 = 0;

   //load sprite image data
   for(x = 0; x < 128; x++)
          {
             OAMData[x] = carData[x];
          }

   //the main game loop
   while(1)
   {
      ChangeAngle();         //calculate dx and y
      GetInput();         //read the gba keypad
      RotateSprite(0, angle, zoom, zoom);   //rotate the sprite
      MoveSprite(&sprites[0],xpos,ypos);   //move the car
      WaitForVsync();         //waits for the screen to stop drawing
      CopyOAM();         //copies sprite array into OAM.

   }
}


the file: "sincosrad.h" comes from the tutorials from gbajunkie
and are the sine, cosine and radian loopup tables.

And the source can be downloaded here:
http://home.12move.nl/jenswa/car.zip

Thanx for your help in advance.
_________________
It seems this wasn't lost after all.

#9899 - Lupin - Thu Aug 21, 2003 1:07 pm

I'm not sure, but isnt the result of SIN[] fixed point? Maybe you should check the fixed point format. What's the value of zoom? Use 1<<8 for zoom to make sure it's original size

#9900 - jenswa - Thu Aug 21, 2003 1:11 pm

I have the same for zoom.

And FIXED is mostly defined as s32,
can u check that for me?
_________________
It seems this wasn't lost after all.

#9917 - iuiz - Thu Aug 21, 2003 8:28 pm

Hi,

hmm, if you just move the sprite (wether it is rotated or not) does it work? I thought, that you have saved an angel for your sprite and want to move it into that direction.

I thought, that you have just calculated the distance false.

So, if you have a Sprite that is facing north (0?) and you move it (lets say 2 Pixels) it would move 2 Pixels up. If it is facing right (90?) it would move 2 pixels right, and when it has 45? it would move one Pixel up and one Pixel down.
And I thought that this function must contain a failure.


Or did I get you wrong?


Just try to move it one pixel right, and one down. When it worked rotate the Sprite a bit and do the same movement again (the movement is not depending on the rotation off the Sprite in this example). This way you will be able to focus on the failure (because if this works, your move sprite function is correct).


Cu,
iuiz

#9942 - jenswa - Fri Aug 22, 2003 11:39 am

Yes, the calculations where wrong,
i now have added *PI/180, now it moves into the directions, but way too fast.

so code looks like this:
Code:

dx= (s32)(COS[angle] * PI/180);
 dy = (s32)(SIN[angle] *PI/180);

_________________
It seems this wasn't lost after all.

#9949 - tepples - Fri Aug 22, 2003 7:39 pm

Hint 1: You'll need to keep track of the position of the sprite with subpixel accuracy, as fixed-point numbers.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#9952 - jenswa - Fri Aug 22, 2003 7:51 pm

Let's see if i get the point.

You mean that i should keep track of the numbers behind the komma ( "," or in code the point ".").

example:

3.18

i store the .18 in a variable and then i keep counting untill i reach
the 1 and then i can move the sprite 1 pixel. And of course this is done
for x and y?

Nevertheless i still have this problem, i thought that sine returns a value between -1 and 1.
But in my function, the highest number is 4.

Hmm i think i see the problem, the sine and cosine values i have used
aren't ment to be used in this way (i think) because they are not between
-1 and 1, like i learend at school.

Thanks for your help.
_________________
It seems this wasn't lost after all.

#10122 - iuiz - Wed Aug 27, 2003 6:07 pm

Ok, I am realy bored at this moment, so I took out a Pencil...


www.halof.com/images/sinandcos.jpg

Your Sprite is locatet at (2|2), and lets say Alpha has 26.388? and you want to move it 4,5cm (Pic 1).

(Now I have to google, what "Gegenkathete" and "Hypothenuse" means in English :D - damn, i am not able to find it :()



So, lets repeat, what sinus and cosinus are, because I dont know the English words (look at pic 2)

sin alpha = a / c
cos alpha = b / c



So, if you want to calculate, how much you have to move your Sprite, you have to use the things, that you already know. These are Alpha and c.

Alpha = 26.388?
c = 4,5cm

calculate the way on the x-axis -->
a = sin alpha * c

a = sin 26,388? * 4,5
a= 0,44 * 4,5
a= 1,98cm


calculate the way on the y-axis -->
b= cos alpha * 4,5
short: b = 4,03cm


Variation: The y-axis could be also done with the Pytagoras.


I hope this helped. Now it should be realy easy to create a "callculate movent" function. If not drop me a line :). You dont need Pi, isn't this great?



Cu,
iuiz

ps: To calculate the sin or cos of an var do this:
Code:

#include <math.h>
#include <stdio.h>

void main()
{
   int bla=90;
   float SinBla;
   
   SinBla= (float) (sin(bla));

   printf("%g", SinBla);
}


(Remember that it is in [b]RADIANS[\b])

#10206 - jenswa - Fri Aug 29, 2003 2:09 pm

Thanks for some 3rd grade math teaching.

But i found out my sine and cosine tables were wrong.

Anywayz, i should cast it back to integer and store the subpixel for moving. That was actually whay i was asking for.
_________________
It seems this wasn't lost after all.