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:
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.
No comments:
Post a Comment