<< Chapter < Page Chapter >> Page >

Complete program listing

Complete listings of the program files discussed in this module are provided in Listing 14 and Listing 15 below.

Listing 14 . The Sprite class for the project named XNA0130Proj.

/*Project XNA0130Proj * This file defines a Sprite class from which a Sprite* object can be instantiated. This version supports * collision detection based on intersecting rectangles.*******************************************************/ using System;using System.Collections.Generic; using Microsoft.Xna.Framework;using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics;namespace XNA0130Proj { class Sprite {private Texture2D image; private Vector2 position = new Vector2(0,0);private Vector2 direction = new Vector2(0,0); private Point windowSize;private Random random; double elapsedTime;//in milliseconds//The following value is the inverse of speed in // moves/msec expressed in msec/move.double elapsedTimeTarget; //-------------------------------------------------////Image property accessor - new to this version. public Texture2D Image {get { return image;}//end get }//end Image property accessor//-------------------------------------------------// //Position property accessorpublic Vector2 Position { get {return position; }set { position = value;}//end set }//end Position property accessor//-------------------------------------------------// //WindowSize property accessorpublic Point WindowSize { set {windowSize = value; }//end set}//end WindowSize property accessor //-------------------------------------------------////Direction property accessor public Vector2 Direction {get { return direction;} set {direction = value; }//end set}//end Direction property accessor //-------------------------------------------------////Speed property accessor. The set side should be // called with speed in moves/msec. The get side// returns speed moves/msec. public double Speed {get { //Convert from elapsed time in msec/move to// speed in moves/msec. return elapsedTimeTarget/1000;} set {//Convert from speed in moves/msec to // elapsed time in msec/move.elapsedTimeTarget = 1000/value; }//end set}//end Speed property accessor //-------------------------------------------------////This constructor loads an image for the sprite // when it is instantiated. Therefore, it requires// an asset name for the image and a reference to a // ContentManager object.//Requires a reference to a Random object. Should // use the same Random object for all sprites to// avoid getting the same sequence for different // sprites.public Sprite(String assetName, ContentManager contentManager,Random random) { image = contentManager.Load<Texture2D>(assetName); image.Name = assetName;//new to this versionthis.random = random; }//end constructor//-------------------------------------------------// //This method can be called to load a new image// for the sprite. public void SetImage(String assetName,ContentManager contentManager) { image = contentManager.Load<Texture2D>(assetName); image.Name = assetName;//new to this version}//end SetImage //-------------------------------------------------////This method causes the sprite to move in the // direction of the direction vector if the elapsed// time since the last move exceeds the elapsed // time target based on the specified speed.public void Move(GameTime gameTime) { //Accumulate elapsed time since the last move.elapsedTime += gameTime.ElapsedGameTime.Milliseconds;if(elapsedTime>elapsedTimeTarget){ //It's time to make a move. Set the elapsed// time to a value that will attempt to produce // the specified speed on the average.elapsedTime -= elapsedTimeTarget; //Add the direction vector to the position// vector to get a new position vector. position = Vector2.Add(position,direction);//Check for a collision with an edge of the game // window. If the sprite reaches an edge, cause// the sprite to wrap around and reappear at the // other edge, moving at the same speed in a// different direction within the same quadrant // as before.if(position.X<-image.Width){ position.X = windowSize.X;NewDirection(); }//end ifif(position.X>windowSize.X){ position.X = -image.Width/2;NewDirection(); }//end ifif(position.Y<-image.Height) { position.Y = windowSize.Y;NewDirection(); }//end ifif(position.Y>windowSize.Y){ position.Y = -image.Height / 2;NewDirection(); }//end if on position.Y}//end if on elapsed time }//end Move//-------------------------------------------------// //This method determines the length of the current// direction vector along with the signs of the X // and Y components of the current direction vector.// It computes a new direction vector of the same// length with the X and Y components having random // lengths and the same signs.//Note that random.NextDouble returns a // pseudo-random value, uniformly distributed// between 0.0 and 1.0. private void NewDirection() {//Get information about the current direction // vector.double length = Math.Sqrt( direction.X * direction.X +direction.Y * direction.Y); Boolean xNegative = (direction.X<0)?true:false; Boolean yNegative = (direction.Y<0)?true:false; //Compute a new X component as a random portion of// the vector length. direction.X =(float)(length * random.NextDouble()); //Compute a corresponding Y component that will// keep the same vector length. direction.Y = (float)Math.Sqrt(length*length -direction.X*direction.X); //Set the signs on the X and Y components to match// the signs from the original direction vector. if(xNegative)direction.X = -direction.X; if(yNegative)direction.Y = -direction.Y; }//end NewDirection//-------------------------------------------------// public void Draw(SpriteBatch spriteBatch) {//Call the simplest available version of // SpriteBatch.DrawspriteBatch.Draw(image,position,Color.White); }//end Draw method//-------------------------------------------------// //This method is new to this version of the Sprite// class. //Returns the current rectangle occupied by the// sprite. public Rectangle GetRectangle() {return new Rectangle((int)(position.X), (int)(position.Y),image.Width, image.Height);}//end GetRectangle //-------------------------------------------------////This method is new to this version of the Sprite // class.//This method receives a list of Sprite objects as // an incoming parameter. It tests for a collision// with the sprites in the list beginning with the // sprite at the head of the list. If it detects a// collision, it stops testing immediately and // returns a reference to the Sprite object for// which it found the collision. If it doesn't find // a collision with any sprite in the list, it// returns null. //A collision is called if the rectangle containing// this object's image intersects the rectangle // containing a target sprite's image.public Sprite IsCollision(List<Sprite>target) { Rectangle thisRectangle =new Rectangle((int)(position.X), (int)(position.Y),image.Width, image.Height);Rectangle targetRectangle; int cnt = 0;while(cnt<target.Count){ targetRectangle = target[cnt].GetRectangle(); if(thisRectangle.Intersects(targetRectangle)){return target[cnt];}//end if cnt++;}//end while loop return null;//no collision detected}//end IsCollision //-------------------------------------------------//}//end class }//end namespace

Listing 15 . The Game1 class for the project named XNA0130Proj.

/*Project XNA0130Proj * This project demonstrates how to integrate* spiders, and ladybugs in a program using * objects of a Sprite class with collision* detection. * *****************************************************/using System; using System.Collections.Generic;using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics;using XNA0130Proj; namespace XNA0130Proj {public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics;SpriteBatch spriteBatch; //Use the following values to set the size of the// client area of the game window. The actual window // with its frame is somewhat larger depending on// the OS display options. On my machine with its // current display options, these dimensions// produce a 1024x768 game window. int windowWidth = 1017;int windowHeight = 738; //This is the length of the greatest distance in// pixels that any sprite will move in a single // frame of the game loop.double maxVectorLength = 5.0; Sprite spiderWeb;//reference to a background sprite.//References to the spiders are stored in this // List object.List<Sprite>spiders = new List<Sprite>(); int numSpiders = 200;//Number of spiders.//The following value should never exceed 60 moves // per second unless the default frame rate is also// increased to more than 60 frames per second. double maxSpiderSpeed = 30;//moves per second//References to the Ladybugs are stored in this List. List<Sprite>ladybugs = new List<Sprite>(); int numLadybugs = 5;//Max number of ladybugsdouble maxLadybugSpeed = 15; //Random number generator. It is best to use a single// object of the Random class to avoid the // possibility of using different streams that// produce the same sequence of values. //Note that the random.NextDouble() method produces// a pseudo-random value where the sequence of values // is uniformly distributed between 0.0 and 1.0.Random random = new Random(); //-------------------------------------------------//public Game1() {//constructor graphics = new GraphicsDeviceManager(this);Content.RootDirectory = "Content"; //Set the size of the game window.graphics.PreferredBackBufferWidth = windowWidth; graphics.PreferredBackBufferHeight = windowHeight;}//end constructor //-------------------------------------------------//protected override void Initialize() { //No initialization required.base.Initialize(); }//end Initialize//-------------------------------------------------// protected override void LoadContent() {spriteBatch = new SpriteBatch(GraphicsDevice); //Create a sprite for the background image.spiderWeb = new Sprite("spiderwebB",Content,random);spiderWeb.Position = new Vector2(0f,0f); //Instantiate all of the spiders and cause them to// move from left to right, top to // bottom. Pass a reference to the same Random// object to all of the sprites. for(int cnt = 0;cnt<numSpiders;cnt++) { spiders.Add(new Sprite("blackWidowSpider",Content,random)); //Set the position of the current spider at a// random location within the game window. spiders[cnt].Position = new Vector2( (float)(windowWidth * random.NextDouble()),(float)(windowHeight * random.NextDouble())); //Get a direction vector for the current spider.// Make both components positive to cause the // vector to point down and to the right.spiders[cnt].Direction = DirectionVector((float)maxVectorLength, (float)(maxVectorLength * random.NextDouble()),false,//xNeg false);//yNeg//Notify the spider object of the size of the // game window.spiders[cnt].WindowSize =new Point(windowWidth,windowHeight); //Set the speed in moves per second for the// current spider to a random value between // maxSpiderSpeed/2 and maxSpiderSpeed.spiders[cnt].Speed = maxSpiderSpeed / 2+ maxSpiderSpeed * random.NextDouble() / 2; }//end for loop//Use the same process to instantiate all of the // ladybugs and cause them to move from right to// left, bottom to top. for(int cnt = 0;cnt<numLadybugs;cnt++) { ladybugs.Add(new Sprite("ladybug",Content,random)); ladybugs[cnt].Position = new Vector2( (float)(windowWidth * random.NextDouble()),(float)(windowHeight * random.NextDouble())); ladybugs[cnt].Direction = DirectionVector( (float)maxVectorLength,(float)(maxVectorLength * random.NextDouble()), true,//xNegtrue);//yNeg ladybugs[cnt].WindowSize = new Point(windowWidth,windowHeight);ladybugs[cnt].Speed = maxLadybugSpeed / 2+ maxLadybugSpeed * random.NextDouble() / 2; }//end for loop}//end LoadContent //-------------------------------------------------////This method returns a direction vector given the // length of the vector, the length of the// X component, the sign of the X component, and the // sign of the Y component. Set negX and/or negY to// true to cause them to be negative. By adjusting // the signs on the X and Y components, the vector// can be caused to point into any of the four // quadrants.private Vector2 DirectionVector(float vecLen, float xLen,Boolean negX, Boolean negY) {Vector2 result = new Vector2(xLen,0); result.Y = (float)Math.Sqrt(vecLen * vecLen- xLen * xLen); if(negX)result.X = -result.X; if(negY)result.Y = -result.Y; return result;}//end DirectionVector //-------------------------------------------------//protected override void UnloadContent() { //No content unload required.}//end unloadContent //-------------------------------------------------//protected override void Update(GameTime gameTime) { //Tell all the spiders in the list to move.for(int cnt = 0;cnt<spiders.Count;cnt++) { spiders[cnt].Move(gameTime); }//end for loop//Tell all the ladybugs in the list to move. for(int cnt = 0;cnt<ladybugs.Count;cnt++) { ladybugs[cnt].Move(gameTime); }//end for loop//Tell each ladybug to test for a collision with a // spider and to return a reference to the spider// if there is a collision. Return null if there is // no collision.for(int cnt = 0;cnt<ladybugs.Count;cnt++) { //Test for a collision between this ladybug and// all of the spiders in the list of spiders. Sprite target =ladybugs[cnt].IsCollision(spiders);if(target != null) { //There was a collision. Cause the spider to// move 128 pixels to the right. target.Position =new Vector2(target.Position.X + 128, target.Position.Y);//If the collision was with a black widow // spider, cause it to reincarnate into a// green spider. if(target.Image.Name == "blackWidowSpider") {target.SetImage("greenspider",Content); }//If the collision was with a green spider,// cause it to reincarnate into a brown // spider.else if(target.Image.Name == "greenspider") { target.SetImage("brownSpider",Content);}//If the collision was with a brown spider, // it gets eaten. Remove it from the list of// spiders. else if(target.Image.Name == "brownSpider") {spiders.Remove(target); }// end else-if}//end if }//end for loopbase.Update(gameTime); }//end Update method//-------------------------------------------------// protected override void Draw(GameTime gameTime) {spriteBatch.Begin(); spiderWeb.Draw(spriteBatch);//draw background//Draw all spiders. for(int cnt = 0;cnt<spiders.Count;cnt++) { spiders[cnt].Draw(spriteBatch); }//end for loop//Draw all ladybugs. for(int cnt = 0;cnt<ladybugs.Count;cnt++) { ladybugs[cnt].Draw(spriteBatch); }//end for loopspriteBatch.End(); base.Draw(gameTime);}//end Draw method //-------------------------------------------------//}//end class }//end namespace

-end-

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Xna game studio. OpenStax CNX. Feb 28, 2014 Download for free at https://legacy.cnx.org/content/col11634/1.6
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Xna game studio' conversation and receive update notifications?

Ask