Download presentation
Presentation is loading. Please wait.
1
Collision Detection
2
Collision Detection Concept
When two fireflies collide we tag them for removal and add an explosion to the blasts list. The position and velocity of the explosion is set to the average of the two colliding flies. fireflies list blasts graphical display Blast objects are removed from the blasts list when their animation sequence is completed.
3
Managing Generic Lists
A generic list can hold any type of object, so they are especially well suited for holding structured data types. In Object Oriented Programming we can define a structured data type as an instance class. The class has the additional advantage of holding methods and properties related to the class. In this application we will create a class for the firefly and a class for the blast (explosion). Each firefly will have its own position and velocity. To add more natural appearance to their flight we can randomize the rate of the wing flapping animation for each fly and add a random element to their flight. Warning! MS Visual Studio .NET has a quirky random number generator. When a new Random object is created it's initial seed is determined by the clock time, which means that if multiple instances of a Random object are created in a short time (within a few milliseconds of each other) they will have the same initial seed and will therefore may generate the same pseudo-random sequence.
4
firefly Class public class firefly { public Vector2 Pos; public Vector2 Vel; public int MaxX; public int MaxY; public Rectangle Rect = new Rectangle(); public int AnimCount; public int AnimTimer; public int Time; public int TotCount; public bool Hit; Random rand = new Random(); public firefly(int maxX, int maxY, int totcount, int sheetwidth, int sheetheight, int animtimer, int seed) Random rnd = new Random(seed); MaxX = maxX; MaxY = maxY; Pos.X = rnd.Next(maxX); Pos.Y = rnd.Next(maxY); Vel.X = rnd.Next(10) - 5; Vel.Y = rnd.Next(10) - 5; Rect.X = 0; Rect.Y = 0; Rect.Width = sheetwidth / totcount; Rect.Height = sheetheight; AnimTimer = animtimer; AnimCount = 0; TotCount = totcount; Time = 0; Hit = false; } OK, just so you know, this is a stripped-down version of an instance class which would distress any OOP purist. In this course we use OOP to program, we DO NOT program to use OOP. Which means we will readily ignore any OOP protocol and we will break an OOP rule that interferes with our primary goal to build an efficiently running and fun game project. Hopping off the soapbox, the constructor for firefly creates a random object which needs its a unique seed. We will use a random number generator in the main program to provide this seed.
5
Move( ) Method for firefly Class
public void Move(int deltime) { Time += deltime; Pos.X += Vel.X; if (Pos.X > MaxX) Pos.X = 0; if (Pos.X < 0) Pos.X = MaxX; Pos.Y += Vel.Y; if (Pos.Y > MaxY) Pos.Y = 0; if (Pos.Y < 0) Pos.Y = MaxY; if (rand.Next(1000) > 990) Vel.X += rand.Next(3) - 1; if (rand.Next(1000) > 990) Vel.Y += rand.Next(3) - 1; if (Vel.X > 5) Vel.X = 5; if (Vel.X <-5) Vel.X = -5; if (Vel.Y > 5) Vel.Y = 5; if (Vel.Y <-5) Vel.Y = -5; if (Time >= AnimTimer) AnimCount = (AnimCount + 1) % TotCount; Time = 0; } Rect.X = AnimCount * Rect.Width; The Move( ) method updates the position of the firefly and increments the AnimCount (frame # being displayed from the firefly spritesheet. Position (Pos) is updated using the velocity (Vel) and velocity is randomly updated with a 10/1000 probability. Magnitude of velocity is limited to 5 units. AnimCount is updated each time accumulated Time exceeds the randomly set number of milliseconds per frame, AnimTimer. The location of Rect is the region of the spritesheet being displayed for the current frame of the animation. flies.png
6
blast Class public Vector2 Pos; public Vector2 Vel; public Rectangle Rect = new Rectangle(); public int AnimCount; public bool Done; public int AnimTimer; int TotCount; public int Width; public int Height; public int Time; int rownum; int colnum; public blast(Vector2 pos, Vector2 vel1, Vector2 vel2, int totcount, int width, int height, int animtimer) { Pos = pos; Vel.X = (vel1.X + vel2.X) / 2; Vel.Y = (vel1.Y + vel2.Y) / 2; AnimCount = 0; Rect.X = 0; Rect.Y = 0; Rect.Width = width; Rect.Height = height; Width = width; Height = height; TotCount = totcount; AnimTimer = animtimer; rownum = 0; colnum = 0; Done = false; } When two fireflies collide they are tagged for removal and an explosion (an instance the the blast class) is created. The blast will exist for 16 display frames as the 16 frames of the explosion sequence is used to animate the blast. At the end of the animation, the completed instance of blast is tagged for removal. An interesting feature of a blast is that its velocity is set to the average of the velocities of the two colliding fireflies. This gives a more realistic appearance than a static explosion sequence. In this demo we set the rate of animation to 60 milliseconds per frame (AnimTimer = 60).
7
Move( ) Method for blast Class
The individual sprites blits are 64x64 pixels. The rownum and colnum are in the range 0 through and specify the sprite frame 0 through 15. When all frames have been displayed the Boolean field Done is set to TRUE. 256 x 256 pixels public void Move(int deltime) { Time += deltime; Pos.X += Vel.X; Pos.Y += Vel.Y; if (Time >= AnimTimer) AnimCount += 1; Time = 0; } colnum = AnimCount % 4; rownum = AnimCount / 4; Rect.X = colnum * Width; Rect.Y = rownum * Height; if (AnimCount >= TotCount) Done = true; explosion.bmp
8
Main Program Atomic Fireflies Collision Detection Demo
GraphicsDeviceManager graphics; List<firefly> flies = new List<firefly>(); List<blast> blasts = new List<blast>(); SpriteBatch spriteBatch; SoundEffect[] explosion = new SoundEffect[4]; Vector2 spos; Vector2 bpos; Texture2D bkg; Texture2D flysprite; Texture2D expsprite; Rectangle rect = new Rectangle(); KeyboardState kbstate; SpriteFont font; Vector2 txtpos = new Vector2(10, 10); Random rnd = new Random(); int minDist = 10; protected override void Initialize() { base.Initialize(); spos.X = 26; spos.Y = 25; bpos.X = 32; bpos.Y = 32; graphics.IsFullScreen = true; graphics.ApplyChanges(); } Generic lists are created for firefly and blast objects. Four different explosion sounds will be called randomly for each collision. The evening sky background, the firefly sprite sheet and the explosion sprite sheet are loaded as Texture2D data types. An instance of the Random number generator rnd is created to be used to generated unique seeds for the generation of Random generators in the firefly class. This application runs in fullscreen mode comment out the call to graphics.ApplyChanges( ) to convert this application to Windows UI mode.
9
Atomic Fireflies LoadContent( ) Method
protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); explosion[0] = Content.Load<SoundEffect>("explosion-01"); explosion[1] = Content.Load<SoundEffect>("explosion-02"); explosion[2] = Content.Load<SoundEffect>("explosion-03"); explosion[3] = Content.Load<SoundEffect>("explosion-04"); bkg = Content.Load<Texture2D>("bkg"); flysprite = Content.Load<Texture2D>("flies"); expsprite = Content.Load<Texture2D>("explosion"); graphics.PreferredBackBufferWidth = bkg.Width; graphics.PreferredBackBufferHeight = bkg.Height; font = Content.Load<SpriteFont>("SpriteFont1"); rect.X = 0; rect.Y = 0; rect.Width = bkg.Width; rect.Height = bkg.Height; graphics.ApplyChanges(); for (int i = 0; i < 10; i++) flies.Add(new firefly(bkg.Width, bkg.Height, 4, 208, 50, rnd.Next(60)+20, rnd.Next(100000))); } To start the demo 10 fireflies are instantiated and added to the flies list. Note the use of rnd.Next(100000) to generate a different seed for each instance of firefly. Also the AnimTimer is set to a random range of values between 20 and 79 milliseconds.
10
Collision Detection Method
This method demonstrates the versatility of the generic list. Although we do not have to managed the placement of items in a generic list when new items are added and/or old items are removed, we can control the order of access of individual elements in a generic list by index value. The nested for loops compare the locations of every pair of fireflies in the list. When two files are found at or near (within 10 pixels) the same location they are tagged for removal from the list, a new blast object is added to the blasts list and an explosion sound is played. When the number of items to be compared becomes very large we will need to partition the list of items into bins and compare only those items in the same or neighboring bins. For 2D games, a two-dimensional array will be used to partition the objects by their index values. public void collision() { for(int i=0;i<flies.Count-1;i++) for (int j = i + 1; j < flies.Count; j++) if ((Math.Abs(flies[i].Pos.X - flies[j].Pos.X) + Math.Abs(flies[i].Pos.Y - flies[j].Pos.Y)) < minDist) blasts.Add(new blast(flies[i].Pos,flies[i].Vel,flies[j].Vel,16,64,64,60)); flies[i].Hit = true; flies[j].Hit = true; explosion[rnd.Next(4)].Play(); }
11
Atomic Fireflies Update( ) Method
protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); kbstate = Keyboard.GetState(); if (kbstate.IsKeyDown(Keys.Left) && kbstate.IsKeyDown(Keys.Right)) if (kbstate.IsKeyDown(Keys.Right)) flies.Add(new firefly(bkg.Width, bkg.Height, 4, 208, 50, rnd.Next(20) + 40, rnd.Next(100000))); if (kbstate.IsKeyDown(Keys.Left) && flies.Count > 0) flies[flies.Count-1].Hit = true; collision(); foreach (firefly fly in flies) fly.Move(gameTime.ElapsedGameTime.Milliseconds); foreach (blast pow in blasts) pow.Move(gameTime.ElapsedGameTime.Milliseconds); flies.RemoveAll(delegate(firefly fly) return fly.Hit; }); blasts.RemoveAll(delegate(blast pow) return pow.Done; base.Update(gameTime); } Fireflies can be removed or added to the flies list by pressing the Left-Arrow and Right-Arrow keys. The Move( ) methods for each firefly and each blast are called to update the position and animation frame for each object. At the end of Update( ) flies that have been involved in a collision and blasts that have completed their animation sequence are removed from their respective lists using delegate functions as shown.
12
Atomic Fireflies Draw( ) Method
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.White); spriteBatch.Begin(); spriteBatch.Draw(bkg, rect, Color.White); foreach (firefly fly in flies) spriteBatch.Draw(flysprite, fly.Pos, fly.Rect, Color.White, 0, spos, (float)0.5, 0, 0); foreach (blast pow in blasts) spriteBatch.Draw(expsprite, pow.Pos, pow.Rect, Color.White, 0, bpos,1, 0, 0); spriteBatch.DrawString(font, Convert.ToString(flies.Count), txtpos, Color.White); spriteBatch.End(); base.Draw(gameTime); } For each frame the Draw( ) method draws the background images followed by the fireflies and finally the active blasts being displayed. The fireflies.zip file contains the complete project
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.