Saturday, July 21, 2012

4: Creating and Drawing Bullets

       Hello gamers and welcome back to my new blog post. As of 7/20/12, I recently got bullets working in the game engine with the help from a great tutorial I found online called Going Beyond Tutorial 4. In this blog post I am going to show some behind-the-scenes on what we have so far. Remember, this is still a work-in progress and does not represent final footage. I will tweak the bullet class over time. The bullets in the engine travel in the direction the player if facing. Right now I am working on bullet collision with the player and the spider. I created a class called Settings where I keep all the things for the game that remain constant. Inside the settings class I then created two variables; one to store the number of bullets and another to store the speed the bullet is traveling.


int NumBullets = 30;                                                     // Number of Bullets   
public const float BulletSpeed = 100.0f;                        // Speed of the bullet traveling

The Bullet class will flag the bullet as inactive once it drifts off the view.

public void Update(float delta)
{
    position += direction * speed *
                Settings.BulletSpeed * delta;
    if (position.X > Settings.PlayfieldSizeX ||
        position.X < - Settings.PlayfieldSizeX ||
        position.Y >  Settings.PlayfieldSizeY ||
        position.Y < - Settings.PlayfieldSizeY)
        isActive = false;
}

Inside the Game class, I declared my bullet model and created a bullet list.

        Model bullet;

        Matrix[] bulletTransforms;
        Bullet[] bulletList = new Bullet[Settings.NumBullets];


In the Load Content Method:

bullet = Content.Load<Model>("Models/Bullets/bullet");
bulletTransforms = SetupEffectDefaults(bullet);




In the Update Method:

for (int i = 0; i < GameConstants.NumBullets; i++)
            {
                if (bulletList[i].isActive)
                {
                    bulletList[i].Update(timeDelta);
                }
            }


In the Draw Method:

          for (int i = 0; i < Settings.NumBullets; i++)
                {
                    if (bulletList[i].isActive)
                    {
                        Matrix bulletTransform =
                          Matrix.CreateTranslation(bulletList[i].position);
                        DrawBullet(bullet, bulletTransform, bulletTransforms);
                    }
                }

public void DrawBullet(Model bullet, Matrix world, Matrix[] absoluteBoneTransforms)
        {
            bullet.CopyAbsoluteBoneTransformsTo(absoluteBoneTransforms);

            //Draw the model, a model can have multiple meshes, so loop
            foreach (ModelMesh mesh in bullet.Meshes)
            {
                //This is where the mesh orientation is set
                foreach (BasicEffect effect in mesh.Effects)
                {
                    //effect.SetBoneTransforms(bones);
                    effect.EnableDefaultLighting();
                    effect.SpecularColor = new Vector3(0.25f);
                    effect.SpecularPower = 7;

                    effect.World = absoluteBoneTransforms[mesh.ParentBone.Index] * world;

                    // Use the matrices provided by the first person camera
                    effect.View = camera.View;
                    effect.Projection = camera.Projection;
                }
                //Draw the mesh, will use the effects set above.
                mesh.Draw();
            }
        }

In the handle Input Method:

            lastKeyboardState = currentKeyboardState;
            lastGamePadState = currentGamePadState;

            currentKeyboardState = Keyboard.GetState();
            currentGamePadState = GamePad.GetState(PlayerIndex.One);

            if ((currentGamePadState.Triggers.Right > 0f))
            {
                //(volume, pitch, panning)
                fire.Play(1, 1, 0);

             
GamePad.SetVibration(PlayerIndex.One, 0.5f, 0.49f); // Makes player one's gamepad vibrate. It's left motor is at 50%, the right motor is at 49%
             
GamePad.SetVibration(PlayerIndex.One, 0.5f, 0.5f);  // the default vibration
             

             
                //add another bullet.  Find an inactive bullet slot and use it
                //if all bullets slots are used, ignore the user input
                for (int i = 0; i < Settings.NumBullets; i++)
                {
                    if (!bulletList[i].isActive)
                    {
                        bulletList[i].direction = player.Direction;
                        bulletList[i].speed = GameConstants.BulletSpeed;
                        bulletList[i].position = player.Position +
                  (200 * bulletList[i].direction);
                        bulletList[i].isActive = true;
                     
                        break; //exit the loop  
                    }
                }
             


// We translate the gun slightly to make it kickback to give the recoil effect.

                if (weaponOffset.Z <= 1)
                {
                    weaponOffset.Z += 0.2f;

                }
                else
                    if (weaponOffset.Z > 0)
                    {
                        weaponOffset.Z -= 0.9f;
                    }

         
            }
            else
            {
                fire.Play(0f, 0f, 0f);
                GamePad.SetVibration(PlayerIndex.One, 0.0f, 0.0f); // no vibration
             
             
            }

RESULTS:


This picture above is what I have so far. I will tweak it some so the the bullets will fire at an angle out of the muzzle of the gun. I will probably create a bullet offset vector to help this problem. Then I will work on creating a ray tracer to give off bullet trails. Afterwards, I will add a smoke effect for when the player shoots and a muzzle flash.