View difference between Paste ID: tjjnhwtU and mgPmAwRF
SHOW: | | - or go back to the newest paste.
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();
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-
                if (!this.sprites.Contains(s) && Globals.isCollide(this.areaRect, s.collisionRect))
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
}