Spaceship rotation

Hello everyone!

I have a little ship on a black background I like to call ‘outer space’.

I want to move it like, the up arrow moves it forward and the side
arrows change direction. What’s the best way to do this?

I’ve asked Mr. Google but all I find is code to do the actual bitmap
rotation, but I’m using SGE for that.

Please be as specific as possible, last time I asked something similar
people came up with algebraic and geometric functions I have no idea about.

Thanks, SDL town! ;]

i believe sdl_gfx lib has a bitmap rotozoom thing in it.

you could also port abrash’s

or if it’s it’s own opengl poly (2d on ogl) just rotate that (assuming
textures are poly specific on their coords / whatever, rather than world).

-WillOn 8/22/07, L-28C wrote:

Hello everyone!

I have a little ship on a black background I like to call ‘outer space’.

I want to move it like, the up arrow moves it forward and the side
arrows change direction. What’s the best way to do this?

I’ve asked Mr. Google but all I find is code to do the actual bitmap
rotation, but I’m using SGE for that.

Please be as specific as possible, last time I asked something similar
people came up with algebraic and geometric functions I have no idea
about.

Thanks, SDL town! ;]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

The question is a little underspecified. Will has the answer for
rotation, but did you need help with key handling too?

JohnOn 8/22/07, Will Langford wrote:

i believe sdl_gfx lib has a bitmap rotozoom thing in it.

you could also port abrash’s

or if it’s it’s own opengl poly (2d on ogl) just rotate that (assuming
textures are poly specific on their coords / whatever, rather than world).

-Will

On 8/22/07, L-28C wrote:

Hello everyone!

I have a little ship on a black background I like to call ‘outer space’.

I want to move it like, the up arrow moves it forward and the side
arrows change direction. What’s the best way to do this?

I’ve asked Mr. Google but all I find is code to do the actual bitmap
rotation, but I’m using SGE for that.

Please be as specific as possible, last time I asked something similar
people came up with algebraic and geometric functions I have no idea
about.

Thanks, SDL town! ;]


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Note: This is pretty off-topic for the SDL list, a general game programming
list would be more appropriate. But, to reward this improper behavior… :wink:

So you have it rotating, so you presumably already have the following
info about the ship:

X,Y position
Angle rotation

So what you sound like you need is momentum. What I would do is have
some momentum variables, call them “xm” and “ym”, or “dx” and “dy”, or
whatever you prefer. (I’m going with the standard “Space War” or
"Asteroids" ship movement… you apply thrust, and the ship goes. The ship
does not stop going until you thrust the other direction.)

During each execution of your game loop, apply the momentum to your ship.
Something like:

// Apply the thrust:
x += xm;
y += ym;

// Wrap around the edges:
if (x < 0) // Wrap from left to right
x += screen->w;
else if (x >= screen->w) // Wrap from right to left
x -= screen->w;
if (y < 0) // Wrap from top to bottom
y += screen->h;
else if (y >= screen->h) // Wrap from bottom to top
y -= screen->h;

This is great, except now you need to be able to change your momentum.
For example, if you push the UP arrow, make the ship ‘go forward’,
where ‘forward’ depends on what direction it’s facing.

For this, you just need some trigonometry. Let’s go the slow way and
assume your X,Y coordinates and XM,YM momentum values are all floats,
and just use the math library’s sin() and cos() functions. A faster way
would be to use ints and fixed-point math (as I did in my game "Vectoroids,"
which kept it snappy on FPU-less devices, such as the Sharp Zaurus PDA).

if (keysym == SDLK_UP)
{
xm += cos(angle) * thrust_speed;
ym -= sin(angle) * thrust_speed;
}

Oh, and of course that assumes angle is in radians. If it’s in degrees
(0 through 360), you’ll need to convert it to radians, which is what
sin() and cos() in the C math library expect:

xm += cos(angle * (M_PI / 180.0)) * thrust_speed; // Mmm… pie. drool

Depending on your game logic, etc., you may want to throttle your
speed to a certain limit. Esp. if your motion literally goes from one
X,Y position to the next, without checking for collisions in between…

(You’d want line intersect routines for that, for example.)

Good luck,On Wed, Aug 22, 2007 at 07:24:49PM -0400, L-28C wrote:

I’ve asked Mr. Google but all I find is code to do the actual bitmap
rotation, but I’m using SGE for that.


-bill!
bill at newbreedsoftware.com
http://www.newbreedsoftware.com/

Note: This is pretty off-topic for the SDL list, a general game programming
list would be more appropriate. But, to reward this improper behavior… :wink:

PS, the sources to my GPL’d games “Agendaroids” and “Vectoroids”
(the latter is based on the former) would probably be useful to look at.

Agendaroids:
http://www.newbreedsoftware.com/agendaroids/

(for X11; meant for the Agenda (now Softfield) VR3 Linux-based PDA,
but should work on any X-Window system, e.g., a Linux desktop)

Vectoroids:
http://www.newbreedsoftware.com/vectoroids/

(uses SDL; originally written for Linux desktop, then scaled down to
run on Sharp Zaurus Linux-based PDA; has been ported to numerous other
platforms SDL runs on, including Nokia 770 Linux-based internet tablet,
Gamepark GP2X, Gamepark GP32 and Sony PlayStation Portable handheld
game systems, Symbian mobile platform, Amiga computers, and
Sega Dreamcast game console... and it won an award!... and I got
a contract to port/rewrite it for BREW-based cellphones, but it was
never released... I've got it on my phone and it's one of my fav phone
games ;^) )

Enjoy!On Wed, Aug 22, 2007 at 04:52:11PM -0700, Bill Kendrick wrote:


-bill!
bill at newbreedsoftware.com
http://www.newbreedsoftware.com/

Bill Kendrick wrote:> On Wed, Aug 22, 2007 at 07:24:49PM -0400, L-28C wrote:

I’ve asked Mr. Google but all I find is code to do the actual bitmap
rotation, but I’m using SGE for that.

Note: This is pretty off-topic for the SDL list, a general game programming
list would be more appropriate. But, to reward this improper behavior… :wink:

So you have it rotating, so you presumably already have the following
info about the ship:

X,Y position
Angle rotation

So what you sound like you need is momentum. What I would do is have
some momentum variables, call them “xm” and “ym”, or “dx” and “dy”, or
whatever you prefer. (I’m going with the standard “Space War” or
"Asteroids" ship movement… you apply thrust, and the ship goes. The ship
does not stop going until you thrust the other direction.)

During each execution of your game loop, apply the momentum to your ship.
Something like:

// Apply the thrust:
x += xm;
y += ym;

// Wrap around the edges:
if (x < 0) // Wrap from left to right
x += screen->w;
else if (x >= screen->w) // Wrap from right to left
x -= screen->w;
if (y < 0) // Wrap from top to bottom
y += screen->h;
else if (y >= screen->h) // Wrap from bottom to top
y -= screen->h;

This is great, except now you need to be able to change your momentum.
For example, if you push the UP arrow, make the ship ‘go forward’,
where ‘forward’ depends on what direction it’s facing.

For this, you just need some trigonometry. Let’s go the slow way and
assume your X,Y coordinates and XM,YM momentum values are all floats,
and just use the math library’s sin() and cos() functions. A faster way
would be to use ints and fixed-point math (as I did in my game "Vectoroids,"
which kept it snappy on FPU-less devices, such as the Sharp Zaurus PDA).

if (keysym == SDLK_UP)
{
xm += cos(angle) * thrust_speed;
ym -= sin(angle) * thrust_speed;
}

Oh, and of course that assumes angle is in radians. If it’s in degrees
(0 through 360), you’ll need to convert it to radians, which is what
sin() and cos() in the C math library expect:

xm += cos(angle * (M_PI / 180.0)) * thrust_speed; // Mmm… pie. drool

Depending on your game logic, etc., you may want to throttle your
speed to a certain limit. Esp. if your motion literally goes from one
X,Y position to the next, without checking for collisions in between…

(You’d want line intersect routines for that, for example.)

Good luck,

(Sorry about the empty message - I keep clicking ‘Send’.)

Anyway, I understood your code, except, where/how do you modify the
momentum variables? I know it’s with the left/right keys, but how exactly?

And congrats for the award! :smiley:
I once got a 2nd place award, but it sucks because there were only 2 of
us… :confused:

Bill Kendrick wrote:> On Wed, Aug 22, 2007 at 07:24:49PM -0400, L-28C wrote:

I’ve asked Mr. Google but all I find is code to do the actual bitmap
rotation, but I’m using SGE for that.

Note: This is pretty off-topic for the SDL list, a general game programming
list would be more appropriate. But, to reward this improper behavior… :wink:

So you have it rotating, so you presumably already have the following
info about the ship:

X,Y position
Angle rotation

So what you sound like you need is momentum. What I would do is have
some momentum variables, call them “xm” and “ym”, or “dx” and “dy”, or
whatever you prefer. (I’m going with the standard “Space War” or
"Asteroids" ship movement… you apply thrust, and the ship goes. The ship
does not stop going until you thrust the other direction.)

During each execution of your game loop, apply the momentum to your ship.
Something like:

// Apply the thrust:
x += xm;
y += ym;

// Wrap around the edges:
if (x < 0) // Wrap from left to right
x += screen->w;
else if (x >= screen->w) // Wrap from right to left
x -= screen->w;
if (y < 0) // Wrap from top to bottom
y += screen->h;
else if (y >= screen->h) // Wrap from bottom to top
y -= screen->h;

This is great, except now you need to be able to change your momentum.
For example, if you push the UP arrow, make the ship ‘go forward’,
where ‘forward’ depends on what direction it’s facing.

For this, you just need some trigonometry. Let’s go the slow way and
assume your X,Y coordinates and XM,YM momentum values are all floats,
and just use the math library’s sin() and cos() functions. A faster way
would be to use ints and fixed-point math (as I did in my game "Vectoroids,"
which kept it snappy on FPU-less devices, such as the Sharp Zaurus PDA).

if (keysym == SDLK_UP)
{
xm += cos(angle) * thrust_speed;
ym -= sin(angle) * thrust_speed;
}

Oh, and of course that assumes angle is in radians. If it’s in degrees
(0 through 360), you’ll need to convert it to radians, which is what
sin() and cos() in the C math library expect:

xm += cos(angle * (M_PI / 180.0)) * thrust_speed; // Mmm… pie. drool

Depending on your game logic, etc., you may want to throttle your
speed to a certain limit. Esp. if your motion literally goes from one
X,Y position to the next, without checking for collisions in between…

(You’d want line intersect routines for that, for example.)

Good luck,

L-28C wrote:

Hello everyone!

I have a little ship on a black background I like to call ‘outer space’.

I want to move it like, the up arrow moves it forward and the side
arrows change direction. What’s the best way to do this?

I had a similar question a number of years ago, back when I was in high school, and I found the very simple answer in a college-level physics text book I picked up in the school library.

The answer is simply vectors. I don’t know how familiar you are with vector math and trigonometry, but a very basic understanding is enough to make this work. From the fact that you just mention turning left and right, I’m assuming you’re working in just 2D. This makes space simulations MUCH simpler to implement. Free rotation in three dimensions, as you need for a 3D space sim, can be a pretty complicated problem, but 2D rotation is very simple.

A full explanation of how to do all of this is a bit beyond what I want to do in this message. However, this website should tell you most of what you need to know about vectors: http://www.glenbrook.k12.il.us/GBSSCI/PHYS/CLASS/vectors/vectoc.html

That page doesn’t cover how to rotate vectors, but that’s a very simple application of trigonometry. That is:

finalX = initialX * sin(angle) + initialY * cos(angle)
finalY = initialY * sin(angle) + initialX * cos(angle)

So putting that all together. Your ship needs 3 basic vectors: Position, velocity and heading. The heading vector, unlike the other two, needs to be normalized (scaled to a length of 1), which the link above should tell you how to do. Now each frame you do the following:

if (leftKeyDown) {
// Rotate left
float oldHeadingX = headingX;
float oldHeadingY = headingY;
headingX = oldHeadingX * sin(-rotationRate) + oldHeadingY * cos(-rotationRate);
headingY = oldHeadingY * sin(-rotationRate) + oldHeadingX * cos(-rotationRate);
}
if (rightKeyDown) {
// Rotate right
oldRotationX = headingX;
oldRotationY = headingY;
headingX = oldHeadingX * sin(rotationRate) + oldHeadingY * cos(rotationRate);
headingY = oldHeadingY * sin(rotationRate) + oldHeadingX * cos(rotationRate);
}
if (upKeyDown) {
// Accelerate forward
velocityX = velocityX + acceleration * headingX;
velocityY = velocityY + acceleration * headingY;
}
// Move on the current velocity vector
positionX = positionX + velocityX;
positionY = positionY + velocityY;

Now, if you want speed to be consistent, regardless of frame rate, this needs to get a little bit more complicated. You need to use the SDL_GetTicks() function to get the number of milliseconds since the application started. If you call this every frame, you can subtract the latest results from the results from last frame to figure out how many ms have passed. Divide this by 1000.0 to get a value which represents what percentage of a second has passed. Call this value timeMultiplier.

Now that you have this value, you can store all of your values in “per second” units, such as rotation is “degrees per second”, velocity is “units per second” and acceleration is “units per second per second”. Then change your code per frame as follows:

// Calculate what percentage of a second has passed since the last frame
oldTime = newTime;
newTime = SDL_GetTicks();
float timeMultiplier = (newTime - oldTime) / 1000.0;

if (leftKeyDown) {
// Rotate left
float oldHeadingX = headingX;
float oldHeadingY = headingY;
headingX = oldHeadingX * sin(-rotationRate * timeMultiplier) + oldHeadingY * cos(-rotationRate * timeMultiplier);
headingY = oldHeadingY * sin(-rotationRate * timeMultiplier) + oldHeadingX * cos(-rotationRate * timeMultiplier);
}
if (rightKeyDown) {
// Rotate right
oldRotationX = headingX;
oldRotationY = headingY;
headingX = oldHeadingX * sin(rotationRate * timeMultiplier) + oldHeadingY * cos(rotationRate * timeMultiplier);
headingY = oldHeadingY * sin(rotationRate * timeMultiplier) + oldHeadingX * cos(rotationRate * timeMultiplier);
}
if (upKeyDown) {
// Accelerate forward
velocityX = velocityX + acceleration * timeMultiplier * headingX;
velocityY = velocityY + acceleration * timeMultiplier * headingY;
}
// Move on the current velocity vector
positionX = positionX + velocityX * timeMultiplier;
positionY = positionY + velocityY * timeMultiplier;

This is not the most rigorous solution to making the timing not dependent on frame rate, but it is the simplest, and is adequate for most small games.

Anyway, I see a few other people have already posted similar responses while I was composing this. I hope that, between these various tutorials, you can find all the information you need. I look forward to seeing your results!

Hey,

You might have gotten your answer from the other messages, but if you need anything else, I’m more than halfway finished a really big spaceship game. I have a bunch of stuff you may be interested in, including my own version of SGE that simplifies it as a graphics extension, reduces the dll size to 100kb, and is updated to work with the current SDL versions. I also have a nice function that will cleanly convert coordinates to angles (great for AI and much else in this type of game).

Good luck,
Jonny D> To: sdl at libsdl.org> From: kixdemp at gmail.com> Date: Wed, 22 Aug 2007 19:24:49 -0400> Subject: [SDL] Spaceship rotation> > Hello everyone!> > I have a little ship on a black background I like to call ‘outer space’.> > I want to move it like, the up arrow moves it forward and the side > arrows change direction. What’s the best way to do this?> > I’ve asked Mr. Google but all I find is code to do the actual bitmap > rotation, but I’m using SGE for that.> > Please be as specific as possible, last time I asked something similar > people came up with algebraic and geometric functions I have no idea about.> > Thanks, SDL town! ;]> > _______________________________________________> SDL mailing list> SDL at lists.libsdl.org> http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


Explore the seven wonders of the world
http://search.msn.com/results.aspx?q=7+wonders+world&mkt=en-US&form=QBRE