using System;
using FRB;
using FRB.GUI;
using FRB.Text;
using FRB.Particle;
using FRB.Collections;
using FRB.MSG;
using Microsoft.DirectX.DirectInput;
namespace GameName
{
/// <summary>
/// Summary description for GameData.
/// </summary>
public class GameData
{
#region reference to engine managers and data
public GameForm form;
public GuiData guiData;
public InputManager inpMan;
public SpriteManager sprMan;
public TextManager textMan;
public GuiManager guiMan;
public Camera camera;
public Cursor cursor;
public Random random;
#endregion
// declare variables of class scope here
SpriteArray asteroids;
Sprite player;
// we can increase or decrease this as we like
float asteroidCreationFrequency;
// we need this to measure the frequency
long lastTimeAsteroidWasCreated;
public void Initialize(GameForm form)
{
#region initialize engine managers and data
this.form = form;
guiData = new GuiData();
sprMan = GameForm.sprMan;
inpMan = GameForm.inpMan;
textMan = GameForm.textMan;
guiMan = GameForm.guiMan;
camera = GameForm.camera;
cursor = GameForm.cursor;
random = GameForm.random;
#endregion
// this code is called only once when the program is executed
// these arrays will act as "category" for our asteroids
asteroids = new SpriteArray();
// create the player.
player = sprMan.AddSprite("redball.bmp");
// distinguish the player by changing his color
player.tintBlue = 255;
player.tintGreen = 255;
player.colorOperation = Microsoft.DirectX.Direct3D.TextureOperation.Add;
// finally, move the player down a bit
player.y = -10;
asteroidCreationFrequency = 2f; // one asteroid every 2 seconds
}
public void Activity()
{
// this code will be called once per frame.
// arrows move player around, space will fire
if(inpMan.KeyDown(Key.LeftArrow)) // left key will dominate if both left and right are down
player.xVelocity = -20;
else if(inpMan.KeyDown(Key.RightArrow))
player.xVelocity = 20;
else
player.xVelocity = 0;
if(inpMan.KeyPress(Key.Space))
FireBullet(); // put in a separate method for organization
if(TimeManager.SecondsSince(lastTimeAsteroidWasCreated) > asteroidCreationFrequency)
{
CreateAsteroid(); // again, in a separate method for organization
lastTimeAsteroidWasCreated = TimeManager.currentTick;
}
}
public void AfterFrameActivity()
{
// usually, the only code that goes here is text printing with the TextManager
textMan.BeginDrawing();
// this will verify that all of our Sprites are being created and we don't have any leaks
textMan.Draw(sprMan.numOfRegularSprites.ToString());
}
public void FireBullet()
{
// create the bullet
Sprite bullet = sprMan.AddSprite("redball.bmp");
// scale it
bullet.sclX = .2f;
bullet.sclY = .7f;
// position it
bullet.x = player.x;
bullet.y = player.y;
// make it move upward
bullet.yVelocity = 25;
// give it custom behavior
bullet.customFunctions += new customFunction(BulletBehavior);
}
public void CreateAsteroid()
{
// create the asteroid
Sprite asteroid = sprMan.AddSprite("redball.bmp");
// color it
asteroid.colorOperation = Microsoft.DirectX.Direct3D.TextureOperation.Modulate;
asteroid.tintRed = 100;
asteroid.tintGreen = 255;
// find the borders of the screen at z = 0 where the asteroid will be created
float leftBorder = -1 * camera.xEdge * (- camera.z)/100.0f;
float topBorder = camera.yEdge * (- camera.z)/ 100.0f;
// position the asteroid on a random X position and just above the screen.
asteroid.x = leftBorder + (float)random.NextDouble()* 2 * -leftBorder;
asteroid.y = topBorder + asteroid.sclY;
// make the asteroid fall
asteroid.yVelocity = -15;
// add the behavior so that it is removed from the screen when it moves too far down
asteroid.customFunctions += new customFunction(AsteroidBehavior);
// finally throw the asteroid in the asteroids SpriteArray for collision in the BulletBehavior
asteroids.Add(asteroid);
}
public void BulletBehavior(Sprite bullet, SpriteManager sprMan)
{
// a few ways we could do collision. Here's the most "low-level" way of doing it
/* Usually when writing for loops that can remove an element from an Array, you want to loop backwards.
* In this case, if an asteroid is destroyed, then we exit out of the method so we don't have to worry about
* looping backwards.
*/
for(int i = 0; i < asteroids.Count; i++)
{
if( Collisions.rectCollision( bullet, asteroids[i]))
{
/*
* Remember, when we added our Sprite to the asteroids array, we used
* the Add method which establishes a two-way relationship between the Sprite and the
* containing SpriteArray. That's why we simply can call sprMan.RemoveSprite and
* the asteroid will be removed from its SpriteArrays.
* How convenient!
*/
sprMan.RemoveSprite(bullet);
sprMan.RemoveSprite(asteroids[i]);
return;
}
}
/* we also want to check if the bullet is above the screen and remove it if so.
*/
if( camera.IsYInView( bullet.y - bullet.sclY, bullet.z) == false)
{
// the bottom of the bullet is not in the screen. Since bullets always move up, we can remove it
sprMan.RemoveSprite(bullet);
}
}
public void AsteroidBehavior(Sprite asteroid, SpriteManager sprMan)
{
if(asteroid.y < 0 && // need to make sure the asteroid is below the camera since it starts out of the screen
camera.IsYInView( asteroid.y + asteroid.sclY, asteroid.z) == false)
{
// the asteroid is below the bottom of the screen. Remove it
sprMan.RemoveSprite(asteroid);
}
}
}
}