GP2X Beginner's Programming Question


rokdcasbah

got me a date with botticelli's niece
Joined
Jan 5, 2006
Messages
1,516
Location
up on cripple creek
OK, I am trying my hand at python & pygame and have little prior coding experience. For my first project I am trying to do an arkanoid clone that I will someday compile for the gp2x. Hopefully it will be better than the one included with the docs, else my efforts will have been wasted :)

This probably concerns taste more than anything but I was interested in hearing replies from seasoned vets. I need to make movement vectors for my ball so that it's not just bouncing around with a "slope" of 1 all the time. My ideas were as follows:

1. Treat the movement vectors as separate X & Y vectors (sign for direction, plus magnitude). Magnitude ends up being pixels per frame, so a value between 0 and 1 means 1 pixel every such and such frames, and a value > than 1 means the opposite.

2. Forget the "frame business" and treat it as a slope. x / y. Let the code for the screen update worry about how many pixels to move and in what direction.

Simple enough, right? Just wondering what will cause me the least amount of grief - making code to change angles with a "slope mentality", or having to deal with more than 1 variable?

Many thanks in advance.
 
Both are okay, because they are basically interchangeable.

A vx, vy (velocity x, velocity y) solution will be most efficient. Remember that every frame you will have to do x += vx, y += vy.

If you find it easier to use slope (or angle), either you need to calculate this every frame:

x += speed * cos(φ)
y += speed * cos(φ)

This is quite a lot more expensive, because you need to do two multiplications and a sin and a cos each frame; to counter that, you can precalculate vx and vy from speed and φ when they change, and then the efficiency difference is negligible.

If you use the first model, it's very easy to bounce mirror the bounce against your paddle (vy = -vy). In the second model, it's very easy change speed, or the angle with a different amount than mirroring. Choose what suits you best.
 
i think i'm going vx,vy. i hadn't planned on using cos/sin after my initial ponderings. however, i was looking at a game like ricochet: lost worlds (anyone played it?) where your paddle is roundish and some of the tiles and walls are rounded, and sin/cos might be a lot more powerful if I went that route (as opposed to having, say, 6 different "speeds" each for x and y). but i'm gonna take it slow for now. having never done true OO programming before, i'm excited about the idea of just "dropping" in more advanced physics as i get better.

thanks! (also, rix, thanks for your quick reply to my pm. i'll make a post or something once i have a decent amount of artwork).
 
Stick with vectors - if you need to handle bounces off curves, or slanted surfaces, you can translate the vector into an angle (atan2) then back again (sin,cos) just for the bounce calculation.

You don't even need to do that though - if you can get the normal vector (or the tangent vector - the normal is easy to calculate from that) it's a very simple calculation to bounce your velocity vector in that direction - just subtract 2 * (velocity . normal) * normal - e.g. in C like this:

Code:
void bounce (float vx, float vy, float nx, float ny, float *ovx, float *ovy)
{
    float vnorm;

    // normalize the normal (skip this if you know it's already normalised)
    float nmag = sqrt(nx*nx + ny*ny);
    nx /= nmag;
    ny /= nmag;

    // get velocity component in direction of normal
    vnorm = vx*nx + vy*ny;

    // subtract velocity component twice to bounce in direction of normal
    *ovx = vx - 2*vnorm * nx;
    *ovy = vy - 2*vnorm * ny;
}

That was off the top of my head - sorry if it has any errors but it should illustrate the concept.
 
phew - gfoot, your code is over my head at the moment. however, i get what you're saying...get the tangent or normal to the curve and compute the bounce direction based on the current velocity and normal's "velocity". right? :)

but at the moment i have no code for generating any sort of curves in place. i just finished code for controlling the speed of the ball in either dimension and making sure the ball doesn't go out of bounds. however, i have a problem with my ball speed code and would appreciate some insight...right now i have:


- x & y velocity parameters are passed to ball class. aka how many pixels to move for the next frame
- if the value is between 0 and 1, it gets stored and added until > 1, at which point ball moves 1 pixel (.25 = 1 pixel every 4 frames)
- if wall is hit, velocity gets reversed
- appropriate things get cleared/drawn: "thus evening came, and morning followed: the next frame."

problem is this: what to do with a velocity of, say, x = 2.5? should i just change the scale i'm working at so that everything is between 0 and 1? i'm sure there's a more elegant way to do this - one where ball speed is independent of frame rate. just not sure what that is. any thoughts?

edit: yeah, i definitely have to try a new method. the current one is causing some slowdown (and it's not because i'm updating the whole screen all at once, because i'm not...)
 
phew - gfoot, your code is over my head at the moment. however, i get what you're saying...get the tangent or normal to the curve and compute the bounce direction based on the current velocity and normal's "velocity". right? :)

but at the moment i have no code for generating any sort of curves in place. i just finished code for controlling the speed of the ball in either dimension and making sure the ball doesn't go out of bounds. however, i have a problem with my ball speed code and would appreciate some insight...right now i have:


- x & y velocity parameters are passed to ball class. aka how many pixels to move for the next frame
- if the value is between 0 and 1, it gets stored and added until > 1, at which point ball moves 1 pixel (.25 = 1 pixel every 4 frames)
- if wall is hit, velocity gets reversed
- appropriate things get cleared/drawn: "thus evening came, and morning followed: the next frame."

problem is this: what to do with a velocity of, say, x = 2.5? should i just change the scale i'm working at so that everything is between 0 and 1? i'm sure there's a more elegant way to do this - one where ball speed is independent of frame rate. just not sure what that is. any thoughts?

edit: yeah, i definitely have to try a new method. the current one is causing some slowdown (and it's not because i'm updating the whole screen all at once, because i'm not...)

I have a very simple set of sprite classes in C++ (probably too simple to be very useful, but very easy to program for). Anyway, these keep x and y world positions as floats and velocities are kept as floats. So I just add velocities to positions (x+=vX; y+=vY). When it comes to putting the sprites out on screen, it's just a case of converting the coordinates to int. My sprite classes keep track of how often to apply the movement, so you can say "move (0.5f, 1.2f) every 30 milliseconds" or whatever. With hindsight, I probably wouldn't have done it that way, but it is easy to use.
 
Last edited by a moderator:
What's wrong with a velocity of 2.5? You'll move more than one pixel at a time, but you can still detect when the ball should bounce etc. To some extent it's easier if it doesn't move more than one pixel max in each direction, but it's not much of a problem.

If you're having speed problems, you need to figure out what is causing them to work out how to solve them. I presume you're waiting for a vblank between frames? If not, and you're just running flat out, then the perceived speed of the ball will vary a lot depending on the speed of your code. Simply waiting for the vblank can help a lot. If your code sometimes takes too long and isn't ready in time for the next vblank, you'll end up waiting for the one after that and everything will run at half the speed. There are a few different ways to deal with this - mostly based around detecting when this has happened, and running the logic update twice without bothering to vsync&render in between, to catch up.

Some people prefer to work out exactly how much time has passed since they last updated the objects, and scale the update accordingly (i.e. multiply by the time delta when adding on the velocities). I'm not a fan of this method, I prefer rigid timeslices, but as I said, some people like it this way, and it does completely detach the game speed from the frame rate.
 
thanks for the quick replies. gfoot, the problem i'm having with 2.5 is that when i go to actually "move" the object, i need to enter a number of pixels. e.g. if i try to move 0.5 pixels every frame it will not move at all. i had come up with a solution to that but then realized it was incomplete.

i'm going to have to keep trying to come up with a solution that is more elegant...i was imagining something along the lines of what evening2005 just posted. the point being that i can have a high framerate but be able to move the ball at speeds that are not just multiples of it.

i can't believe i'm having this much trouble with moving a friggin' ball. thanks for the responses, guys. i realize this should be in "i need help" but hopefully it's not a huge deal.
 
thanks for the quick replies. gfoot, the problem i'm having with 2.5 is that when i go to actually "move" the object, i need to enter a number of pixels. e.g. if i try to move 0.5 pixels every frame it will not move at all. i had come up with a solution to that but then realized it was incomplete.

There are a few solutions to it, both involving support for fractional pixel movement. You can either go with floating point or with fixed point calculations.

Floating point is basically what you're doing now, but instead have (x, y) and (vx, vy) be floats. They'll need to be converted to integers whenever you draw them, though.

Using floating point values usually implies a bit of a performance hit: floating point calculations are slower than integer calculations (so x += vx will be more expensive if x and vx are floats), and you'll need to do a float->int conversion each frame.

Now, this may be perfectly acceptable for your case; if there's not a whole many of objects moving around on screen, you will barely notice the hit, and the processor probably still has lots of CPU cycles to burn per frame. In addition, the method is fairly intuitive, so you could very well go with it.

The alternative is using fixed point. Here's a short explanation for the people who've never heard of it before. It may appear to be more complicated, because this time the numbers involved will be in a different representation than the decimal one we're all used to, but in essence it's also very simple and it's faster than floating point calculations.

With fixed point arithmetic, we'll treat a 32-bit or 16-bit integer like it contains both an integer ("whole number") and a fractional part. You can choose the size of the integer, and the bit sizes of the different parts based on how big you need your numbers to be, and how precise you need to fractions to be, but fixed point integers will typically look like this:

Code:
+-----------+------------+
|     I     |      F     |
+-----------+------------+
   16 bits      16 bits
    8 bits       8 bits

In this diagram, the top part I of your integer will contain the integer part of the number, and the lower part F will contain the fractional part of the integer.

For example, using one 16-bit integer word, you could encode the number 2.5 as 2 in the I part, and 128 in the F part.

Why 128? Because the F part can contain 256 different numbers (0-255). Think of "256" as "1". 128 is exactly half of this: 2 * 0.5 = 1, and 2 * 128 = 256. The math works out.

In effect, the number you'll get is 640:
Code:
+-----------+------------+
|        2  |        128 |
+-----------+------------+
         2                  * 256 = 512
                     128    *   1 = 128
                          -------------- +
                                    640

What good is such a number? Well, it turns out you can actually do arithmetic with these numbers.

For example, if we need to calculate 2.5 + 2.5, we can just add our fixed point representation of 2.5 (640) to itself, giving: 640 + 640 = 1280.

And what do you know? Our fixed point representation of 5.0, is 5 * 256 + 0 = also 1280!

The number scheme is consistent: we just have scaled up all numbers by a factor of 256 (or even 32768 if you use a 32-bit word to store your numbers).

This is Good News(tm), because:
  • Addition is cheap! It's just integer addition, every processor can do that with its eyes closed.
  • Remember that we also still need to convert these fixed point numbers to "regular integers", to be fed into drawing routines as screen coordinates. It turns out that is very cheap as well: we simply need to take the top part (I) of the fixed point number, and we're done! That can be done with division by 256: 1280 / 256 = 5. Division is not very cheap, but we can take another operation that is cheap instead, and is exactly equivalent: bit shifting. By shifting our fixed point integer 8 bits to the right, the fractional part "falls off", and we're left with only the integer part. In C, you'd write that as:
    Code:
    displayx = fixedx >> 8;
Fixed point numbers do not have as large a range as floating point numbers, though. Floating point numbers can easily contain numbers like a gajillion trillion, fixed point numbers cannot, so you'll need to be aware of the highest number you'll want to store, and choose your fixed point accordingly.

I hope this helps without confusing :).
 
Last edited by a moderator:
yes, you're right rix. i had read about fixed point numbers but have yet to actually use them...i think what i am going to do is start with floating points to save myself some time and then once that works and i have collision detection going, i will switch to fixed points.

i just ordered my gp2x, finally, so hopefully that will give me some motivation. or, more likely, i will just spend my time playing genesis games...
 
If you're finding this thread interesting and useful try getting a copy of "Tips and Tricks of the Windows Game Programming Gurus" by Andre LaMothe. I know it has the W word in the title, but it's got some really useful info for someone just getting into game programming. Plus it focuses mostly on 2d stuff which is rare to find these days but handy for the gp2x.

edit: You can get it here for £8.90: http://www.amazon.co.uk/exec/obidos/tg/det...9185783-2779610
 
Back
Top