Advertisement
Guest User

Quadtree 2

a guest
Aug 6th, 2012
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6.  
  7. namespace MassDestructionTop
  8. {
  9.     public class QTreeNode
  10.     {
  11.         QTreeNode[] childNodes = new QTreeNode[4];
  12.         private List<Sprite> sprites = new List<Sprite>();
  13.         private int quad = -1;
  14.         private int generation = 0;
  15.         private QTreeNode parent = null;
  16.         private bool cleanUp = false;
  17.         private Rectangle areaRect;
  18.         private const int maxGen = 2;
  19.         private bool hasChild
  20.         {
  21.             get { return childNodes[0] != null; }
  22.         }
  23.  
  24.         public QTreeNode(int x, int y, int w, int h, QTreeNode parent = null, int generation = 0, int quad = -1)
  25.         {
  26.             areaRect = new Rectangle(x, y, w, h);
  27.  
  28.             this.generation = generation;
  29.             this.parent = parent;
  30.             this.quad = quad;
  31.         }
  32.  
  33.         private void createChildren()
  34.         {
  35.             childNodes[0] = new QTreeNode(0, 0, this.areaRect.Width / 2, this.areaRect.Height / 2, this, this.generation + 1, 1);
  36.             childNodes[1] = new QTreeNode(this.areaRect.Width / 2, 0, this.areaRect.Width, this.areaRect.Height / 2, this, this.generation + 1, 2);
  37.             childNodes[2] = new QTreeNode(this.areaRect.Width / 2, this.areaRect.Height / 2, this.areaRect.Width, this.areaRect.Height, this, this.generation + 1, 3);
  38.             childNodes[3] = new QTreeNode(0, this.areaRect.Height / 2, this.areaRect.Width, this.areaRect.Height, this, this.generation + 1, 4);
  39.  
  40.             List<Sprite> toDestroy = new List<Sprite>();
  41.  
  42.             for (int i = 0; i < 3; ++i)
  43.             {
  44.                 foreach (Sprite s in sprites)
  45.                 {
  46.                     if (Globals.isCollide(s.collisionRect, this.areaRect))
  47.                     {
  48.                         childNodes[i].sprites.Add(s);
  49.                         toDestroy.Add(s);
  50.                     }
  51.                 }
  52.             }
  53.  
  54.             foreach (Sprite s in toDestroy)
  55.             {
  56.                 this.sprites.Remove(s);
  57.             }
  58.         }
  59.  
  60.         public void update()
  61.         {
  62.             nodeSpriteCheck();
  63.             if(sprites.Count == 2)
  64.             {
  65.                 detectCollision();
  66.             }
  67.             else if(sprites.Count > 2 && generation < maxGen)
  68.             {
  69.                 createChildren();
  70.             }
  71.             else if (generation > maxGen)
  72.             {
  73.                 detectCollision();
  74.             }
  75.  
  76.             if (cleanUp)
  77.             {
  78.                 deleteEmptyChildren();
  79.             }
  80.  
  81.             if (generation > maxGen)
  82.             {
  83.                 throw new Exception("Generation Too high");
  84.             }
  85.  
  86.             updateChildren();
  87.  
  88.         }
  89.  
  90.         private void nodeSpriteCheck()
  91.         {
  92.             foreach (Sprite s in Globals.globalAllSprites)
  93.             {
  94.                 if (hasChild)
  95.                 {
  96.                     childNodes[0].childNodeSpriteCheck(s);
  97.                     childNodes[1].childNodeSpriteCheck(s);
  98.                     childNodes[2].childNodeSpriteCheck(s);
  99.                     childNodes[3].childNodeSpriteCheck(s);
  100.                 }
  101.                 else if (!this.sprites.Contains(s) && Globals.isCollide(this.areaRect, s.collisionRect))
  102.                 {
  103.                     this.sprites.Add(s);
  104.                 }
  105.                 else if(this.sprites.Contains(s) && !Globals.isCollide(this.areaRect, s.collisionRect))
  106.                 {
  107.                     this.sprites.Remove(s);
  108.                 }
  109.                 else if (this.sprites.Count == 0)
  110.                 {
  111.                     parent.cleanUp = true;
  112.                 }
  113.             }
  114.            
  115.         }
  116.  
  117.         private void childNodeSpriteCheck(Sprite s)
  118.         {
  119.  
  120.             if (childNodes[0] != null)
  121.             {
  122.                 childNodes[0].nodeSpriteCheck();
  123.                 childNodes[1].nodeSpriteCheck();
  124.                 childNodes[2].nodeSpriteCheck();
  125.                 childNodes[3].nodeSpriteCheck();
  126.             }
  127.         }
  128.  
  129.         private void deleteEmptyChildren()
  130.         {
  131.             if (hasChild)
  132.             {
  133.                 if (childNodes[0].sprites.Count <= 1 && childNodes[1].sprites.Count <= 1 && childNodes[2].sprites.Count <= 1 && childNodes[3].sprites.Count <= 1)
  134.                 {
  135.                     for (int i = 0; i < 4; ++i)
  136.                     {
  137.                         childNodes[i] = null;
  138.                     }
  139.                 }
  140.             }
  141.         }
  142.  
  143.         private bool detectCollision()
  144.         {
  145.             if (sprites[0] == null || sprites[1] == null || !sprites[0].moved || !sprites[1].moved)
  146.             {
  147.                 return false;
  148.             }
  149.             else if (Globals.isCollide(sprites[0].collisionRect, sprites[1].collisionRect))
  150.             {
  151.                 sprites[0].react(sprites[1]);
  152.                 sprites[1].react(sprites[0]);
  153.                 return true;
  154.             }
  155.             else if (!Globals.isCollide(sprites[0].collisionRect, sprites[1].collisionRect))
  156.             {
  157.                 return false;
  158.             }
  159.             else
  160.             {
  161.                 Exception ex = new Exception("QTree Error: Collission Detect failed");
  162.                 throw ex;
  163.             }
  164.         }
  165.  
  166.         private void updateChildren()
  167.         {
  168.             foreach(QTreeNode child in childNodes)
  169.             {
  170.                 if (child != null)
  171.                 {
  172.                     child.update();
  173.                 }
  174.             }
  175.         }
  176.  
  177.     }
  178. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement