Выбрать главу

To make things easier to understand in regards to the x position, I'll write out a quick example. Say our distance is –30.0f and the current level is 1: object[num].x=((-30.0f-15.0f)/2.0f)-(5*1)-float(rand()%(5*1));

object[num].x=(-45.0f/2.0f)-5-float(rand()%5);

object[num].x=(-22.5f)-5-{lets say 3.0f};

object[num].x=(-22.5f)-5-{3.0f};

object[num].x=-27.5f-{3.0f};

object[num].x=-30.5f;

Now keeping in mind that we move 10 units into the screen before we draw our objects, and the distance in the example above is –30.0f. it's safe to say our actual distance into the screen will be –40.0f. Using the perspective code in the NeHeGL.cpp file, it's safe to assume that if the distance is –40.0f, the far left edge of the screen will be –20.0f and the far right will be +20.0f. In the code above our x value is –22.5f (which would be JUST off the left side of the screen). We then subtract 5 and our random value of 3 which guarantees the object will start off the screen (at –30.5f) which means the object would have to move roughly 8 units to the right before it even appeared on the screen.

GLvoid InitObject(int num) // Initialize An Object

{

 object[num].rot=1; // Clockwise Rotation

 object[num].frame=0; // Reset The Explosion Frame To Zero

 object[num].hit=FALSE; // Reset Object Has Been Hit Status To False

 object[num].texid=rand()%5; // Assign A New Texture

 object[num].distance=-(float(rand()%4001)/100.0f); // Random Distance

 object[num].y=-1.5f+(float(rand()%451)/100.0f); // Random Y Position

 // Random Starting X Position Based On Distance Of Object And Random Amount For A Delay (Positive Value)

 object[num].x = ((object[num].distance-15.0f)/2.0f) - (5*level)-float(rand()%(5*level));

 object[num].dir=(rand()%2); // Pick A Random Direction

Now we check to see which direction the object is going to be travelling. The code below checks to see if the object is moving left. If it is, we have to change the rotation so that the object is spinning counter clockwise. We do this by changing the value of rot to 2.

Our x value by default is going to be a negative number. However, the right side of the screen would be a positive value. So the last thing we do is negate the current x value. In english, we make the x value a positive value instead of a negative value.

 if (object[num].dir==0) // Is Random Direction Right

 {

  object[num].rot=2; // Counter Clockwise Rotation

  object[num].x=-object[num].x; // Start On The Left Side (Negative Value)

 }

Now we check the texid to find out what object the computer has randomly picked. If texid is equal to 0, the computer has picked the Blueface object. The blueface guys always roll across the ground. To make sure they start off at ground level, we manually set the y value to –2.0f.

 if (object[num].texid==0) // Blue Face

  object[num].y=-2.0f; // Always Rolling On The Ground

Next we check to see if texid is 1. If so, the computer has selected the Bucket. The bucket doesn't travel from left to right, it falls from the sky. The first thing we have to do is set dir to 3. This tells the computer that our bucket is falling or moving down.

Our initial code assumes the object will be travelling from left to right. Because the bucket is falling down, we have to give it a new random x value. If we didn't, the bucket would never be visible. It would fall either far off the left side of the screen or far off the right side of the screen. To assign a new value we randomly choose a value based on the distance into the screen. Instead of subtracting 15, we only subtract 10. This gives us a little less range, and keeps the object ON the screen instead of off the side of the screen. Assuming our distance was –30.0f, we would end up with a random value from 0.0f to 40.0f. If you're asking yourself, why from 0.0f to 40.0f? Shouldn't it be from 0.0f to –40.0f? The answer is easy. The rand() function always returns a positive number. So whatever number we get back will be a positive value. Anyways… back to the story. So we have a positive number from 0.0f to 40.0f. We then add the distance (a negative value) minus 10.0f divided by 2. As an example… assuming the random value returned is say 15 and the distance is –30.0f:

 object[num].x = float(rand()%int(-30.0f-10.0f))+((-30.0f-10.0f)/2.0f);

 object[num].x = float(rand()%int(-40.0f)+(-40.0f)/2.0f);

 object[num].x = float(15 {assuming 15 was returned))+(-20.0f);

 object[num].x = 15.0f-20.0f;

 object[num].x = -5.0f;

The last thing we have to do is set the y value. We want the bucket to drop from the sky. We don't want it falling through the clouds though. So we set the y value to 4.5f. Just a little below the clouds.

 if (object[num].texid==1) // Bucket

 {

  object[num].dir=3; // Falling Down

  object[num].x = float(rand()%int(object[num].distance-10.0f)) + ((object[num].distance-10.0f)/2.0f);

  object[num].y=4.5f; // Random X, Start At Top Of The Screen

 }

We want the target to pop out of the ground and up into the air. We check to make sure the object is indeed a target (texid is 2). If so, we set the direction (dir) to 2 (up). We use the exact same code as above to get a random x location.

We don't want the target to start above ground. So we set it's initial y value to –3.0f (under the ground). We then subtract a random value from 0.0f to 5 multiplied by the current level. We do this so that the target doesn't INSTANTLY appear. On higher levels we want a delay before the target appears. Without a delay, the targets would pop out one after another, giving you very little time to hit them.

 if (object[num].texid==2) // Target

 {

  object[num].dir=2; // Start Off Flying Up

  object[num].x = float(rand()%int(object[num].distance-10.0f)) + ((object[num].distance-10.0f)/2.0f);

  object[num].y=-3.0f-float(rand()%(5*level)); // Random X, Start Under Ground + Random Value

 }

All of the other objects travel from left to right, so there is no need to assign any values to the remaining objects. They should work just fine with the random values they were assigned.

Now for the fun stuff! "For the alpha blending technique to work correctly, the transparent primitives must be drawn in back to front order and must not intersect" . When drawing alpha blended objects, it is very important that objects in the distance are drawn first, and objects up close are drawn last.

The reason is simple… The Z buffer prevents OpenGL from drawing pixels that are behind things that have already been drawn. So what ends up happening is objects drawn behind transparent objects do not show up. What you end up seeing is a square shape around overlapping objects… Not pretty!

We already know the depth of each object. So after initializing a new object, we can get around this problem by sorting the objects using the qsort function (quick sort). By sorting the objects, we can be sure that the first object drawn is the object furthest away. That way when we draw the objects, starting at the first object, the objects in the distance will be drawn first. Objects that are closer (drawn later) will see the previously drawn objects behind them, and will blend properly!

As noted in the line comments I found this code in the MSDN after searching the net for hours looking for a solution. It works good and allows you to sort entire structures. qsort takes 4 parameters. The first parameter points to the object array (the array to be sorted). The second parameter is the number of arrays we want to sort… of course we want to sort through all the object currently being displayed (which is level). The third parameter specifies the size of our objects structure and the fourth parameter points to our Compare() function.