Upload
annabel-gallagher
View
213
Download
0
Embed Size (px)
Citation preview
AI & 2D Development
COSC 315Fall 2014
Bridget M. Blodgett
Artificial Intelligence
• Why the Turing Test is BS• What is the goal of including AI in games?• Although genuine AI would be nice we need to
start small• Making sprites appear randomly is a good first
step towards a more natural AI
Random
• XNA has a built in Random number function– It isn’t great but it works for what we need to do
• It is a good idea to create a single random variable and then call it for all your randomization needs
• If you make multiple variables and call them too quickly you could end up making numbers off the same seed– This defeats the purpose of randomness
Making Random Variables
• The first step is to create some placeholder variables to hold your randomly generated number and initialize it in your game1 class constructorpublic Random rnd{get; private set;}rnd = new Random();
• We also need some class variables to define the frequency of enemy spawnsint enemySpawnMinMilliseconds = 1000;int enemySpawnMaxmillisends = 2000;int enemyMinSpeed = 2;int enemyMaxSpeed = 6;
Using SpriteManager
• Remove the code that makes the stationary sprites from LoadContent
• The method should only have the player variable now• Make a class variable called:– int nextSpawnTime = 0;
• Make a new method in SpriteManagerprivate void ResetSpawnTime() {
nextSpawnTime = ((Game1)Game).rnd.Next(enemySpawnMinMilliseconds, enemySpawnMaxMilliseconds);
}
ResetSpawnTimer()
• Now call your new method in Initialize()• This will set up the spawner but adding code
to the Update method will get it runningnextSpawnTime -= gameTime.ElapsedGameTime.Milliseconds;if(nextSpawnTime < 0) {
SpawnEnemy();ResetSpawnTime();
}
• Right now this makes a call to a function that doesn’t exist but that will be added next
Spawn Enemy
• There are several things that need to be done: – The enemy needs a starting position, starting
speed, added to the spriteListprivate void SpawnEnemy(){
Vector2 speed = Vector2.Zero;Vector2 position = Vector2.Zero;Point frameSize = new Point(75,75);
}
• After declaring these variables you need to write code to set them
switch (((Game1)Game).rnd.Next(4)){case 0:
position = new Vector2(-frameSize.X, ((Game1)Game).rnd.Next(0,Game.GraphicsDevice.PresentationParameters.BackBufferHeight – frameSize.Y));
speed = new Vector2(((Game1)Game).rnd(Next(enemyMinSpeed, enemyMaxSpeed), 0);break;
case 1:position = new Vector2( Game.GraphicsDevice.PresentationParameters.BackBufferWidth, ((Game1)Game).rnd.Next(0,Game.GraphicsDevice.PresentationParameters.BackBufferHeight – frameSize.Y));
speed = new Vector2(-((Game1)Game).rnd(Next(enemyMinSpeed, enemyMaxSpeed), 0);break;
case 2:position = new Vector2(((Game1)Game).rnd.Next(0,Game.GraphicsDevice.PresentationParameters.BackBufferWidth – frameSize.X), Game.GraphicsDevice.PresentationParameters.BackBufferHeight);speed = new Vector2(0, -((Game1)Game).rnd(Next(enemyMinSpeed, enemyMaxSpeed));break;
case 3:position = new Vector2(((Game1)Game).rnd.Next(0,Game.GraphicsDevice.PresentationParameters.BackBufferWidth – frameSize.X), -frameSize.Y);speed = new Vector2(0,((Game1)Game).rnd(Next(enemyMinSpeed, enemyMaxSpeed));break;
}
spriteList.Add(new AutomatedSprite(Game.Content.Load<Texture2D>(@”images\skullball”), position, new Point(75,75), 10, new Point(0,0), new Point (6,8), speed, “skullcollision”));
} //this closes the method!
Irrelevant Objects
• Right now if a sprite passes outside the boundary they just keep going
• This means that the game will get slower the longer it’s played– Why?
• There are a number of different solutions to this issue
Boundary Rectangles
• Just like for collisions we can use a rectangle to determine when an object goes outside the window bounds
• In the sprite class add the following methodpublic bool IsOutOfBounds(Rectangle clientRect) {
if(position.X < -frameSize.X || position.X > clientRect.Width || position.Y < -frameSize.Y || position.Y > clientRect.Height) {
return true;}
return false;}
• Now you need to fix update to check the sprites each call
for (int I = 0; I < spriteList.Count; ++i){Sprite s = spriteList[i];s.Update(gameTime, Game.Window.ClientBounds);
if (s.collisionRect.Intersects(player.collisionRect)) {
spriteList.RemoveAt(i);--i;
}if (s.IsOutOfBounds(Game.Window.ClientBounds)) {
spriteList.RemoveAt(i);--i;
}}
Player Aware Sprites
• So our enemies are still pretty basic and don’t really react to the player
• Using a simple algorithm that determines the player’s position and moves the sprites accordingly you can make two new types of enemies: chasers and evaders
• Both of these require making a small modification to the Sprite base class to accept the player’s location