Author: conkerjo
(2009/07/08 19:40) Over 2 years ago
86
<ItemGroup>
87
<Compile Include="ExtensionMethods.cs" />
88
<Compile Include="Game.cs" />
89
<Compile Include="GameClasses\Behaviors\Attack.cs" />
90
<Compile Include="GameClasses\Behaviors\Decorators\TimerBehavior.cs" />
<Compile Include="GameClasses\Behaviors\DieBehavior.cs" />
91
92
<Compile Include="GameClasses\Behaviors\Conditions\EnemyNearby.cs" />
93
<Compile Include="GameClasses\Behaviors\RootSoldierBehavior.cs" />
94
<Compile Include="GameClasses\Critter.cs" />
95
<Compile Include="GameClasses\GameConsts.cs" />
<Compile Include="GameClasses\GameActor.cs" />
96
97
<Compile Include="GameClasses\Soldier.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
98
99
<Compile Include="Screens\Demos\Demo7.cs" />
100
<Compile Include="Screens\Demos\Demo6.cs" />
<Compile Include="Screens\Demos\Demo5.cs" />
101
<Compile Include="Screens\Demos\Demo4.cs" />
102
<Compile Include="Screens\Demos\Demo3.cs" />
103
6
7
namespace AIDemos.GameClasses.Behaviors
8
{
9
[Brains.Framework.Designer.Behavior("DieBehavior")]
public class DieBehavior:BehaviorTask
10
11
public DieBehavior()
12
22
public class Demo1 : DemoGameScreen
23
24
private GridCell _endNode;
25
private AIEngine _engine;
26
private MouseState _currentMouse;
27
private MouseState _lastMouse;
28
29
public Demo1()
public Demo1():base("Demo 1 - Basic Pathfinding",
30
"Click a valid grid cell to spawn a basic actor to pathfind to the destination\n" +
31
"Red Cross : Blocked Cell\n" +
32
"Empty Tile : Traversable Cell\n" +
33
"Greed Circle: Destination Cell")
34
TransitionOnTime = TimeSpan.FromSeconds(1.5);
35
TransitionOffTime = TimeSpan.FromSeconds(0.5);
36
Title = "Demo 1 - Basic Pathfinding";
Description = "Click a valid grid cell to spawn a basic actor to pathfind to the destination\n" +
37
"Greed Circle: Destination Cell";
38
}
39
40
public override void LoadContent()
...
42
base.LoadContent();
41
43
44
LoadAI();
45
//primitiveBatch.CameraPosition = new Vector2(-(_engine.World.Map.Cluster[0].Width / 2), -(_engine.World.Map.Cluster[0].Height / 2));
46
((DrawableWorld)_engine.World).Font = gameFont;
47
((DrawableWorld)_engine.World).Batch = ScreenManager.SpriteBatch;
48
49
primitiveBatch.CameraPosition = new Vector2(
CenterCamOnMap();
50
-ScreenManager.GraphicsDevice.Viewport.Width / 2 +
51
_engine.World.Map.ClusterGrid.Grids[0].Width / 2,
52
-ScreenManager.GraphicsDevice.Viewport.Height / 2 +
53
_engine.World.Map.ClusterGrid.Grids[0].Height / 2);
54
55
56
ScreenManager.Game.ResetElapsedTime();
58
59
private void LoadAI()
60
61
_engine = new AIEngine();
62
_engine.CreateWorld(new DrawableWorld());
63
_engine.World.LoadMapDataFromTexture(
64
content.Load<Texture2D>("DemoTextures/MAPDemo1"),
124
if (cell != null)
115
125
116
126
GameActor actor = new GameActor(cell.Position, 5);
117
127
actor.Locomotion = new Brains.Framework.Locomotion.LocomtionSteering();
118
actor.Locomotion = new Brains.Framework.Locomotion.LocomotionController();
128
actor.Locomotion.MaxSpeed = 50;
119
129
actor.Locomotion.MaxRotation = MathHelper.TwoPi;
120
130
121
public class Demo2 : DemoGameScreen
AIEngine _engine;
public Demo2()
public Demo2():base("Demo 2 - Patrol","")
Title = "Demo 2 - Patrol";
Description = "An Agent is added to the world and set to patrol an area.";
57
content.Load<Texture2D>("DemoTextures/MAPDemo2"),
public class Demo3 : DemoGameScreen
public Demo3()
public Demo3():base("Demo 3 - Custom Behaviors","")
Title = "Demo 3 - Custom Behaviors";
Description = "Custom Behaviors";
content.Load<Texture2D>("DemoTextures/MAPDemo3"),
21
public class Demo4 : DemoGameScreen
public Demo4()
public Demo4():base("Demo 4 - Steering Motion Controller","")
Title = "Demo 4 - Steering Motion Controller";
Description = "";
content.Load<Texture2D>("DemoTextures/MAPDemoBlank8"),
public class Demo5 : DemoGameScreen
public Demo5()
public Demo5():base("Demo 5 - A Bigger World","")
Title = "Demo 5 - A Bigger World";
((DrawableWorld)_engine.World).Font= gameFont;
8,
4,
32,
typeof(DrawableGrid));
GridCell fromcell=_engine.World.Map.AllCells.First<GridCell>(
//GridCell fromcell=_engine.World.Map.AllCells.First<GridCell>(
a => a.Labels[AIConsts.COLORR]==0&&
// a => a.Labels[AIConsts.COLORR]==0&&
a.Labels[AIConsts.COLORG]==255 &&
// a.Labels[AIConsts.COLORG]==255 &&
a.Labels[AIConsts.COLORB]==0);
// a.Labels[AIConsts.COLORB]==0);
65
GridCell tocell = _engine.World.Map.AllCells.First<GridCell>(
//GridCell tocell = _engine.World.Map.AllCells.First<GridCell>(
66
a => a.Labels[AIConsts.COLORR] == 255 &&
// a => a.Labels[AIConsts.COLORR] == 255 &&
67
a.Labels[AIConsts.COLORG] == 0 &&
// a.Labels[AIConsts.COLORG] == 0 &&
68
a.Labels[AIConsts.COLORB] == 0);
// a.Labels[AIConsts.COLORB] == 0);
69
GameActor actor = new GameActor(fromcell.Position, 5);
//GameActor actor = new GameActor(fromcell.Position, 5);
70
//actor.Locomotion = new Brains.Framework.Locomotion.LocomtionSteering();
71
//actor.Locomotion.MaxSpeed = 70;
72
//actor.Locomotion.MaxRotation = MathHelper.TwoPi;
73
74
_engine.World.AddActor(actor);
//_engine.World.AddActor(actor);
75
SequenceBehavior _sequence = new SequenceBehavior();
//SequenceBehavior _sequence = new SequenceBehavior();
76
77
78
DrawableBehaviorGoTo _goto = new DrawableBehaviorGoTo();
//DrawableBehaviorGoTo _goto = new DrawableBehaviorGoTo();
79
_goto.StartNode = fromcell;
//_goto.StartNode = fromcell;
80
_goto.EndNode = tocell;
//_goto.EndNode = tocell;
81
_sequence.SubBehaviors.Add(_goto);
//_sequence.SubBehaviors.Add(_goto);
82
_sequence.SubBehaviors.Add(new DieBehavior());
//_sequence.SubBehaviors.Add(new DieBehavior());
83
actor.RootBehavior = _sequence;
//actor.RootBehavior = _sequence;
84
85
class CellComparer:IComparer
158
Color.Black, 0, 0);
151
159
152
160
SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
153
161
154
162
spriteBatch.Begin();
155
163
156
164
base.Draw(gameTime);
157
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Brains.Framework;
namespace AIDemos.Screens.Demos
13
17
18
protected SpriteFont gameFont;
19
protected SpriteFont titleFont;
20
protected AIEngine _engine;
public string Title { get; set; }
public string Description{ get; set; }
public DemoGameScreen()
public DemoGameScreen(string title,string description)
Title = title;
Description = description;
protected void CenterCamOnMap()
if (content == null)
gameFont = content.Load<SpriteFont>("gamefont");
titleFont= content.Load<SpriteFont>("titlefont");
primitiveBatch = new PrimitiveBatch(ScreenManager.GraphicsDevice);
public override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
playGameMenuEntry = new MenuEntry("Demo4 - Steering Motion Controller");
playGameMenuEntry.Selected += PlayGameMenuEntrySelected;
MenuEntries.Add(playGameMenuEntry);
playGameMenuEntry = new MenuEntry("Demo5 - A Bigger World");
playGameMenuEntry = new MenuEntry("Demo6 - Combining Behaviors");
playGameMenuEntry = new MenuEntry("Demo7 - Group Movement");
MenuEntry optionsMenuEntry = new MenuEntry("Options");
MenuEntry exitMenuEntry = new MenuEntry("Exit");
LoadingScreen.Load(ScreenManager, true, e.PlayerIndex,
new Demo5());
break;
104
105
case "Demo6 - Combining Behaviors":
106
107
new Demo6());
108
109
case "Demo7 - Group Movement":
110
111
new Demo7());
112
113
114
if (behavior == null)
return;
foreach (var item in behavior.SubBehaviors)
if (behavior is ISubBehaviorHolder)
ISubBehaviorHolder subs = (ISubBehaviorHolder)behavior;
foreach (var item in subs.SubBehaviors)
if (item.State == BehaviorState.Running && item is IRender)
((IRender)item).Render(batch);
DrawBehavior(item, batch);
if (behavior is IRender)
((IRender)behavior).Render(batch);
if (CellsIAmIn.Count > 0)
Vector2 cellsize = new Vector2(ParentWorld.Map.ClusterGrid.Grids[0].CellSize);
batch.DrawBox(CellsIAmIn[0].Position - (cellsize / 2),
CellsIAmIn[0].Position + (cellsize / 2), Color.Blue);
3
using System.Linq;
4
using System.Text;
5
using Brains.Framework.Behaviors.PathFinding;
using Brains.Framework.Behaviors;
namespace AIRendering
public void Render(PrimitiveBatch batch)
14
if (SubBehaviors[CurrentSubBehavior] is IRender)
15
if (CurrentSubBehavior > 0)
16
((IRender)SubBehaviors[CurrentSubBehavior]).Render(batch);
for (int i = 0; i < SubBehaviors[CurrentSubBehavior].SubBehaviors.Count; i++)
if (SubBehaviors[CurrentSubBehavior].SubBehaviors[i] is FollowPathBehavior)
DrawableBehaviorGoTo.DrawFollowPath(SubBehaviors[CurrentSubBehavior].SubBehaviors[i] as FollowPathBehavior,
batch);
ISubBehaviorHolder subs = (ISubBehaviorHolder)SubBehaviors[CurrentSubBehavior];
if (subs != null)
for (int i = 0; i < subs.SubBehaviors.Count; i++)
if (subs.SubBehaviors[i] is FollowPathBehavior)
DrawableBehaviorGoTo.DrawFollowPath(subs.SubBehaviors[i] as FollowPathBehavior,
public virtual void Render(PrimitiveBatch batch)
//for (int y = 0; y < Rows; y++)
position,
position + new Vector2(0, item.Height),
Color.Yellow);
Color pathColor;
Color bisectorsColor;
foreach (var path in item.PredeterminedPaths)
for (int index = 0; index < path.Nodes.Count; index++)
pathColor = Color.Gold;
bisectorsColor = Color.Honeydew;
if (index < path.Nodes.Count - 1)
Vector2 pos1;
pos1 = item.GetCell(path.Nodes[index].X, path.Nodes[index].Y).Position;
Vector2 pos2 = item.GetCell(path.Nodes[index + 1].X, path.Nodes[index + 1].Y).Position;
batch.DrawLine(
pos1,
pos2,
pathColor
);
path.Nodes[index].nodePosition,
path.Nodes[index + 1].nodePosition,
path.Nodes[index].biNormalStart,
path.Nodes[index].biNormalEnd,
bisectorsColor
foreach (DrawableActor item1 in Actors)
private void DrawCell(PrimitiveBatch batch, QuadTreePositionItem<GridCell> item)
protected virtual void DrawCell(PrimitiveBatch batch, QuadTreePositionItem<GridCell> item)
batch.DrawBox(item.Rect.TopLeft, item.Rect.BottomRight, Color.White);
Vector2 firstLine = item.Rect.TopLeft + new Vector2(3, 3);
item.Rect.BottomLeft + new Vector2(24, -24),
Color.Green);
131
foreach (var item1 in Map.ClusterGrid.Entrances)
132
133
134
item1.CellA.Position,
135
item1.CellB.Position,
136
Color.White);
137
138
batch.DrawCircle(
139
item1.CellA.Position,5,Color.Blue);
140
141
item1.CellB.Position, 5, Color.Blue);
142
143
/*for (int i = 0; i < item.Parent.Type; i++)
144
145
146
firstLine.X += 6;
149
}*/
150
//string clearance = item.Parent.Labels[AIConsts.CLEARANCEVALUE].ToString();
if (Batch != null)
//Batch.DrawString(
// Font,
// clearance,
// (item.Position - batch.CameraPosition) / batch.Zoom,
// Color.White,
// 0,
// new Vector2(8,8),
// 1,
// SpriteEffects.None,
// 0);
if (item.Parent.Labels[AIConsts.ISVALIDCLUSTEREDGE] == 1)
batch.DrawCircle(item.Parent.Position, 5, Color.Green);
Vector2 half = new Vector2(item.Parent.Parent.CellSize / 2);
item.Rect.TopLeft+new Vector2(24),
item.Rect.BottomRight - new Vector2(24),
// new Vector2(8, 8),
165
item.Rect.TopRight - new Vector2(24, -24),
166
if (item.Parent.Type == 0)
167
122
168
<userSettings>
<Designer.Properties.Settings>
<setting name="Behaviors" serializeAs="String">
<value>C:\Users\rik\Documents\Visual Studio 2008\Projects\AITester\AITester\bin\x86\Debug\AITester.exe</value>
<value>C:\Work\XNA\BRAINS\src\AIDemos\bin\x86\Debug\AIDemos.exe</value>
</setting>
</Designer.Properties.Settings>
</userSettings>
<Reference Include="System.Xml" />
</ItemGroup>
<Compile Include="Classes\BehaviorTreeViewer.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Classes\BehaviorTreeViewer.Designer.cs">
<DependentUpon>BehaviorTreeViewer.cs</DependentUpon>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
<Compile Include="Program.cs" />
<EmbeddedResource Include="Classes\BehaviorTreeViewer.resx">
</EmbeddedResource>
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
<Name>AIRendering</Name>
</ProjectReference>
<Folder Include="Classes\" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
LoadAIBehaviorData();
string assemblyPath;
private void LoadAIBehaviorData()
_assemblies = new List<Assembly>();
string path = Properties.Settings.Default.Behaviors;
assemblyPath = Path.GetDirectoryName(path);
File.Copy(
//File.Copy(
path,
// path,
Application.StartupPath +"\\"+ Path.GetFileName(path),true);
// Application.StartupPath +"\\"+ Path.GetFileName(path),true);
LoadAssembly(Application.StartupPath + "\\" + "AIFramework.dll");
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
LoadAssembly(Application.StartupPath + "\\" + Path.GetFileName(path));
LoadAssembly(Application.StartupPath + "\\" + "Brains.Framework.dll");
LoadAssembly(path);
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
Console.Write("");
return null;
private void LoadAssembly(string file)
try
((BehaviorNode)treeView1.SelectedNode.Tag).SubBehaviors.Add(_node);
treeView1.SelectedNode.Nodes.Add(_newTreeNode);
treeView1.SelectedNode.Expand();
behaviorTreeViewer1.Invalidate();
123
_rootNode = new BehaviorNode();
_rootNode.Name = "Behavior";
_rootNode.AddParameter("RootType", "");
_rootNode.BehaviorName = "Root";
TreeNode _rootBehaviorNode = new TreeNode(_rootNode.Name);
_rootBehaviorNode.Tag = _rootNode;
treeView1.Nodes.Add(_rootBehaviorNode);
behaviorTreeViewer1.rootBehavior = _rootNode;
147
148
TreeNode _no = new TreeNode(name);
BehaviorNode _n = new BehaviorNode();
_n.Name = name;
if(type!=null)
_n.BehaviorName = type.Name;
_n.Type =type;
_no.Tag = _n;
return _no;
227
238
228
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
239
229
240
230
TreeNode node = treeView1.SelectedNode;
241
231
splitContainer1.Panel2.Controls.Clear();
242
propertyGrid1.SelectedObject = treeView1.SelectedNode.Tag;
232
BehaviorNode _node=node.Tag as BehaviorNode;
243
//TreeNode node = treeView1.SelectedNode;
233
Point _controlPosition = new Point(15, 25);
244
//splitContainer1.Panel2.Controls.Clear();
234
int gap = 25;
245
//BehaviorNode _node=node.Tag as BehaviorNode;
235
foreach (var item in _node.Parameters)
246
//Point _controlPosition = new Point(15, 25);
236
247
//int gap = 25;
237
Label label = new Label();
248
//foreach (var item in _node.Parameters)
label.AutoSize = true;
249
//{
label.Text = item.Name;
250
// Label label = new Label();
label.Location = _controlPosition;
251
// label.AutoSize = true;
252
// label.Text = item.Name;
253
// label.Location = _controlPosition;
254
splitContainer1.Panel2.Controls.Add(label);
255
// splitContainer1.Panel2.Controls.Add(label);
Control ctrl = CreateParameterControl(item);
256
// Control ctrl = CreateParameterControl(item);
ctrl.Location = new Point(_controlPosition.X + 60, _controlPosition.Y-2);
257
// ctrl.Location = new Point(_controlPosition.X + 60, _controlPosition.Y-2);
splitContainer1.Panel2.Controls.Add(ctrl);
258
// splitContainer1.Panel2.Controls.Add(ctrl);
_controlPosition.Y += gap;
259
// _controlPosition.Y += gap;
260
261
262
//}
263
264
private Control CreateParameterControl(Parameter item)
265
275
((Parameter)((Control)sender).Tag).Value = ((TextBox)sender).Text;
276
277
278
279
private void propertyGrid1_Click(object sender, EventArgs e)
280
281
282
283
284
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
285
286
RefreshTreeNode();
287
288
289
private void RefreshTreeNode()
290
291
if (((BehaviorNode)treeView1.SelectedNode.Tag).BehaviorName != null)
292
treeView1.SelectedNode.Text = ((BehaviorNode)treeView1.SelectedNode.Tag).BehaviorName;
293
else if (((BehaviorNode)treeView1.SelectedNode.Tag).Type != null)
294
treeView1.SelectedNode.Text = ((BehaviorNode)treeView1.SelectedNode.Tag).Type.Name;
295
else
296
treeView1.SelectedNode.Text = "Root";
297
298
266
299
this.compositeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.actionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.conditionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.splitContainer2 = new System.Windows.Forms.SplitContainer();
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.behaviorTreeViewer1 = new Designer.Classes.BehaviorTreeViewer();
this.toolStrip1.SuspendLayout();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.contextMenuStrip1.SuspendLayout();
this.splitContainer2.Panel1.SuspendLayout();
this.splitContainer2.Panel2.SuspendLayout();
this.splitContainer2.SuspendLayout();
this.SuspendLayout();
//
// toolStrip1
// splitContainer1.Panel1
this.splitContainer1.Panel1.Controls.Add(this.treeView1);
this.splitContainer1.Panel1.Controls.Add(this.splitContainer2);
// splitContainer1.Panel2
this.splitContainer1.Panel2.Controls.Add(this.behaviorTreeViewer1);
this.splitContainer1.Size = new System.Drawing.Size(706, 539);
this.splitContainer1.SplitterDistance = 235;
this.splitContainer1.TabIndex = 2;
this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeView1.Location = new System.Drawing.Point(0, 0);
this.treeView1.Name = "treeView1";
this.treeView1.Size = new System.Drawing.Size(235, 539);
this.treeView1.Size = new System.Drawing.Size(235, 303);
this.treeView1.TabIndex = 0;
this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
this.treeView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseDown);
// compositeToolStripMenuItem
this.compositeToolStripMenuItem.Name = "compositeToolStripMenuItem";
this.compositeToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.compositeToolStripMenuItem.Size = new System.Drawing.Size(132, 22);
this.compositeToolStripMenuItem.Text = "Composite";
// actionsToolStripMenuItem
this.actionsToolStripMenuItem.Name = "actionsToolStripMenuItem";
this.actionsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.actionsToolStripMenuItem.Size = new System.Drawing.Size(132, 22);
this.actionsToolStripMenuItem.Text = "Actions";
this.actionsToolStripMenuItem.Click += new System.EventHandler(this.actionsToolStripMenuItem_Click);
// conditionToolStripMenuItem
this.conditionToolStripMenuItem.Name = "conditionToolStripMenuItem";
this.conditionToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.conditionToolStripMenuItem.Size = new System.Drawing.Size(132, 22);
this.conditionToolStripMenuItem.Text = "Conditions";
this.conditionToolStripMenuItem.Click += new System.EventHandler(this.conditionToolStripMenuItem_Click);
// splitContainer2
this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer2.Location = new System.Drawing.Point(0, 0);
this.splitContainer2.Name = "splitContainer2";
this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal;
// splitContainer2.Panel1
this.splitContainer2.Panel1.Controls.Add(this.treeView1);
169
// splitContainer2.Panel2
170
171
this.splitContainer2.Panel2.Controls.Add(this.propertyGrid1);
172
this.splitContainer2.Size = new System.Drawing.Size(235, 539);
173
this.splitContainer2.SplitterDistance = 303;
174
this.splitContainer2.TabIndex = 1;
175
176
// propertyGrid1
177
178
this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
179
this.propertyGrid1.Location = new System.Drawing.Point(0, 0);
180
this.propertyGrid1.Name = "propertyGrid1";
181
this.propertyGrid1.Size = new System.Drawing.Size(235, 232);
182
this.propertyGrid1.TabIndex = 1;
183
this.propertyGrid1.Click += new System.EventHandler(this.propertyGrid1_Click);
184
this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged);
185
186
// behaviorTreeViewer1
187
188
this.behaviorTreeViewer1.Dock = System.Windows.Forms.DockStyle.Fill;
189
this.behaviorTreeViewer1.Location = new System.Drawing.Point(0, 0);
190
this.behaviorTreeViewer1.Name = "behaviorTreeViewer1";
191
this.behaviorTreeViewer1.Size = new System.Drawing.Size(467, 539);
192
this.behaviorTreeViewer1.TabIndex = 0;
193
// Form1
194
195
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
196
this.toolStrip1.ResumeLayout(false);
203
this.toolStrip1.PerformLayout();
204
this.splitContainer1.Panel1.ResumeLayout(false);
205
206
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
207
this.contextMenuStrip1.ResumeLayout(false);
208
209
this.splitContainer2.Panel1.ResumeLayout(false);
210
this.splitContainer2.Panel2.ResumeLayout(false);
211
this.splitContainer2.ResumeLayout(false);
this.ResumeLayout(false);
212
this.PerformLayout();
213
214
private System.Windows.Forms.ToolStripButton toolStripButton2;
226
private System.Windows.Forms.ToolStripButton toolStripButton3;
private System.Windows.Forms.ToolStripMenuItem conditionToolStripMenuItem;
private Designer.Classes.BehaviorTreeViewer behaviorTreeViewer1;
private System.Windows.Forms.SplitContainer splitContainer2;
private System.Windows.Forms.PropertyGrid propertyGrid1;
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("C:\\Users\\rik\\Documents\\Visual Studio 2008\\Projects\\AITester\\AITester\\bin\\x86\\Debu" +
[global::System.Configuration.DefaultSettingValueAttribute("C:\\Work\\XNA\\BRAINS\\src\\AIDemos\\bin\\x86\\Debug\\AIDemos.exe")]
"g\\AITester.exe")]
public string Behaviors {
get {
return ((string)(this["Behaviors"]));
<Profiles />
<Settings>
<Setting Name="Behaviors" Type="System.String" Scope="User">
<Value Profile="(Default)">C:\Users\rik\Documents\Visual Studio 2008\Projects\AITester\AITester\bin\x86\Debug\AITester.exe</Value>
<Value Profile="(Default)">C:\Work\XNA\BRAINS\src\AIDemos\bin\x86\Debug\AIDemos.exe</Value>
</Setting>
</Settings>
</SettingsFile>
public Dictionary<uint, int> Labels;
/// <summary>
/// Gets the cells the agent is in
/// </summary>
/// The position of the Actor
public Vector2 Position { get; set; }
/// Gets or sets the previous position of the agent
AddFeeler(.5f, -.5f, Radius + 32);
Name = CreateUniqueName();
Labels = new Dictionary<uint, int>();
private string CreateUniqueName()
Feelers.Add(new Feeler(new Vector2(x, y),length,this));
public virtual void UpdatePerception(GameTime gameTime)
//Tag nearby
/// Update the agent every frame.
// - for each component calculate row and col
202
Vector2 vDistanceFromMapCenter = this.Position;
Grid map = ParentWorld.Map.ClusterGrid.Grids[0];
Grid map = ParentWorld.Map.ClusterGrid.GetGridAtPosition(Position);
if (map == null)
197
float _hstep = (map.Width/ ((float)map.Cols));
198
float _vstep = (map.Height/ ((float)map.Rows));
199
float xComponent = (vDistanceFromMapCenter.X / _hstep) ;
200
float yComponent = (vDistanceFromMapCenter.Y / _vstep);
201
xComponent = xComponent - 0.5f;
// xComponent = xComponent - 0.5f;
yComponent = yComponent - 0.5f;
//yComponent = yComponent - 0.5f;
215
//debugX = (int)xComponent;
216
//debugY = (int)yComponent;
217
/// Loads a Behavior from a file
BehaviorNode _rootNode = (BehaviorNode)_ser.Deserialize(_reader);
_reader.Close();
BehaviorBase _behavior = CreateBehaviorInstance(_rootNode.Parameters[0].Value);
CompositeBehavior _behavior = CreateBehaviorInstance(_rootNode.Parameters[0].Value);
SetupBehavior(_behavior, _rootNode);
RootBehavior = _behavior;
prop.SetValue(behavior, param.Value, null);
parentBehavior.SubBehaviors.Add(behavior);
if(parentBehavior is ISubBehaviorHolder)
((ISubBehaviorHolder)parentBehavior).SubBehaviors.Add(behavior);
267
268
SetupBehavior(behavior, item);
269
270
271
272
private BehaviorBase CreateBehaviorInstance(string typeName)
private CompositeBehavior CreateBehaviorInstance(string typeName)
273
274
foreach (var item in ParentWorld.Engine.Assemblies)
BehaviorBase behavior =(BehaviorBase)item.CreateInstance(typeName);
CompositeBehavior behavior =(CompositeBehavior)item.CreateInstance(typeName);
if (behavior != null)
return behavior;
public virtual byte TypeToCost(int type)
/// Gets the cost of a grid cell type for use with pathfinding.
/// <param name="type">The Type value from a GridCell</param>
300
/// <returns>The cost of the cell</returns>
301
/// <remarks>Override this method for greater flexibility in pathfinding</remarks>
302
public virtual byte GetCostOfCellType(int type)
303
if (type == 0)
304
return 99;
305
306
return (byte)type;
307
308
309
310
public void SetLabel(uint labelid, int labelvalue)
311
312
if (!Labels.Keys.Contains(labelid))
313
Labels.Add(labelid, labelvalue);
314
315
Labels[labelid] = labelvalue;
316
317
318
public int GetLabel(uint labelid)
319
320
321
return 0;
322
323
return Labels[labelid];
324
325
326
<Compile Include="AIEngine.cs" />
<Compile Include="Behaviors\ConditionBehavior.cs" />
<Compile Include="Behaviors\DecoratorBehavior.cs" />
<Compile Include="Behaviors\GoToBehavior.cs" />
<Compile Include="Behaviors\ISubBehaviorHolder.cs" />
<Compile Include="Behaviors\ParallelBehavior.cs" />
<Compile Include="Behaviors\PathFinding\CyclicPathBehavior.cs" />
<Compile Include="Behaviors\PathFinding\FindPathBehavior.cs" />
<Compile Include="Behaviors\PathFinding\FollowPathBehavior.cs" />
<Compile Include="Grouping\Group.cs" />
<Compile Include="Utility\AIConsts.cs" />
<Compile Include="Map\Cluster.cs" />
<Compile Include="Designer\BehaviorNode.cs" />
<Compile Include="Behaviors\BehaviorBase.cs" />
<Compile Include="Behaviors\CompositeBehavior.cs" />
<Compile Include="Behaviors\BehaviorList.cs" />
<Compile Include="Behaviors\BehaviorTask.cs" />
<Compile Include="Behaviors\TaskBehavior.cs" />
<Compile Include="Behaviors\IConditionBehavior.cs" />
<Compile Include="Behaviors\SelectorBehavior.cs" />
<Compile Include="Behaviors\RandomBehavior.cs" />
Parameter p = new Parameter(name, value);
Parameters.Add(p);
public string BehaviorName { get; set; }
public class Parameter
using Brains.Framework.Utility;
using Brains.Grouping;
namespace Brains.Framework.Locomotion
private static Random rand = new Random();
private Vector2 _wanderTarget;
public const float WanderRadius = 1.2f;
public const float WanderRadius = 20;
public const float WanderDistance = 2.0f;
public const float WanderDistance = 30;
public const float WanderJitter = 80;
public enum Deceleration
Flee= 0x00004,
Arrive= 0x00008,
Wander = 0x00010,
//Cohesion= 0x00020,
Cohesion= 0x00020,
//Seperation= 0x00040,
Seperation= 0x00040,
//Alignment = 0x00080,
Alignment = 0x00080,
//ObstacleAvoidance= 0x00100,
//WallAvoidance = 0x00200,
//FollowPath = 0x00400,
TurnOff(BehaviorType.Wander);
public void TurnOnSeperation()
TurnOn(BehaviorType.Seperation);
public void TurnOffSeperation()
TurnOff(BehaviorType.Seperation);
public void TurnOnCohesion()
TurnOn(BehaviorType.Cohesion);
public void TurnOffCohesion()
TurnOff(BehaviorType.Cohesion);
public void TurnOnAlignment()
TurnOn(BehaviorType.Alignment);
public void TurnOffAlignment()
TurnOff(BehaviorType.Alignment);
public void TurnOnOffsetPursuit(Vector2 seek)
private float ObstacleAvoidanceWeight=10;
private Vector2 SteeringForce = Vector2.Zero;
private Vector2 Heading;
private float MaxForce = 4;
private float MaxForce = 2;
private Vector2 Velocity;
private BehaviorType _behaviorFlags;
public float SeekWeight = 1;
public float ArriveWeight= 1;
public float WanderWeight= 1;
public float SeperationWeight= 2;
public float AlignmentWeight= 1;
public float CohesionWeight = 1;
public Vector2 SeekPos { get; set; }
public Deceleration DecelerationSpeed { get; set; }
public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
timeElapsed = gameTime.GetElapsed();
SteeringUpdate(gameTime.GetElapsed());
private void SteeringUpdate(float elapsed)
Vector2 OldPos = Owner.Position;
SetHeading(Vector2.Normalize(Velocity));
Owner.Position += Velocity * elapsed;
Owner.Orientation = Heading;// (float)Math.Atan2(Heading.Y, Heading.X);
if(Heading!=Vector2.Zero)
private void SetHeading(Vector2 new_heading)
private Vector2 CalculatePrioritized()
Vector2 force = Vector2.Zero;
if (On(BehaviorType.Seperation))
force = Separation() * SeperationWeight;
if (!AccumulateForce(ref _steeringForce, force)) return _steeringForce;
if (On(BehaviorType.Alignment))
force = Alignment() * AlignmentWeight;
if (On(BehaviorType.Cohesion))
force = Cohesion() * CohesionWeight;
if (On(BehaviorType.Seek))
force = Seek(SeekPos);
return _steeringForce;
private Vector2 Cohesion()
if (Owner.GetLabel(AIConsts.ISGROUPMEMBER) == 0)
return Vector2.Zero;
Group g = Owner.ParentWorld.GetGroup(Owner.GetLabel(AIConsts.GROUPID));
//first find the center of mass of all the agents
Vector2 CenterOfMass=Vector2.Zero;
Vector2 SteeringForce=Vector2.Zero;
int NeighborCount = 0;
//iterate through the neighbors and sum up all the position vectors
for (int a = 0; a < g.Agents.Count; ++a)
//make sure *this* agent isn't included in the calculations and that
//the agent being examined is a neighbor
if ((g.Agents[a] != Owner))// && neighbors[a]->IsTagged())
CenterOfMass += g.Agents[a].Position;
++NeighborCount;
if (NeighborCount > 0)
//the center of mass is the average of the sum of positions
CenterOfMass /= (float)NeighborCount;
//now seek toward that position
SteeringForce = Seek(CenterOfMass);
return SteeringForce;
private Vector2 Alignment()
327
328
329
330
331
332
333
//used to record the average heading of the neighbors
334
Vector2 AverageHeading = Vector2.Zero;
335
336
//used to count the number of vehicles in the neighborhood
337
338
339
//iterate through all the tagged vehicles and sum their heading vectors
340
341
342
343
//the agent being examined is close enough
344
if ((g.Agents[a] != Owner))// && g.Agents[a]->IsTagged)
345
346
AverageHeading += g.Agents[a].Orientation;
347
348
349
350
351
352
//if the neighborhood contained one or more vehicles, average their
353
//heading vectors.
354
355
356
AverageHeading /= (float)NeighborCount;
357
AverageHeading -= Owner.Orientation;
358
359
360
return AverageHeading;
361
362
363
364
private Vector2 Separation()
365
366
367
368
369
370
Vector2 SteeringForce = Vector2.Zero;
371
372
373
374
//make sure this agent isn't included in the calculations and that
375
//the agent being examined is close enough.
376
if ((g.Agents[a] != Owner)) // && g.Agents[a]->IsTagged())
377
378
Vector2 ToAgent = Owner.Position - g.Agents[a].Position;
379
if (ToAgent == Vector2.Zero)
380
continue;
381
//scale the force inversely proportional to the agent's distance
382
//from its neighbor.
383
SteeringForce +=Vector2.Normalize(ToAgent) / ToAgent.Length();
384
385
386
387
388
389
390
391
392
private bool AccumulateForce(ref Vector2 sf, Vector2 ForceToAdd)
393
464
public Vector2 Wander()
465
466
double JitterThisTimeSlice = WanderJitter * timeElapsed;
467
float JitterThisTimeSlice = WanderJitter * timeElapsed;
468
//first, add a small random vector to the target's position (RandomClamped
469
//returns a value between -1 and 1)
470
_wanderTarget+= new Vector2(RandomClamped() * WanderJitter,
471
_wanderTarget += new Vector2(RandomClamped() * JitterThisTimeSlice,
RandomClamped() * WanderJitter);
472
RandomClamped() * JitterThisTimeSlice);
473
if (_wanderTarget != Vector2.Zero) //reproject this new vector back on to a unit circle
474
_wanderTarget.Normalize();
475
float RandomClamped()
533
534
return rand.Next() - rand.Next();
535
536
537
538
539
using Brains.Framework.PathFinding;
namespace Brains.Framework.Map
public class Cluster
private int _rows;
private int _cols;
private List<Grid> _grids;
//HACK: should support different sized grids
get { return Grids[0].Cols * Cols; }
public int TotalRows
public int GetGridIndex(int x, int y)
return y * Cols + x;
public Grid GetGrid(int x, int y)
return Grids[GetGridIndex(x, y)];
internal void AddEntrance(GridCell cellA, GridCell cellB)
if (!EntranceExists(cellA, cellB))
Entrances.Add(new Entrance(cellA, cellB));
private bool EntranceExists(GridCell cellA, GridCell cellB)
for (int i = 0; i < Entrances.Count; i++)
Entrance ent = Entrances[i];
if (ent.CellA == cellA && ent.CellB == cellB)
return true;
return false;
public List<Entrance> Entrances = new List<Entrance>();
public class Entrance
public GridCell CellA { get; set; }
public GridCell CellB { get; set; }
public Entrance(GridCell a, GridCell b)
CellA = a;
CellB = b;
using Microsoft.Xna.Framework.Graphics;
public class Grid
public List<PreStoredPath> PredeterminedPaths = new List<PreStoredPath>();
private List<GridCell> _cells;
public Vector2 Center
get { return Position; }
get { return Position+(Size/2); }
/// Type value of the Grid Cell.
/// <remarks>1 = Empty, 0 = Blocked</remarks>
public int Type { get { return _type; } set { _type = value; } }
public int Type
get { return _type; }
set
_type = value;
Labels[AIConsts.BLOCKED_TILE] = _type == 0 ? 1 : 0;
/// The Parent Grid
Labels.Add(AIConsts.ISVALIDCLUSTEREDGE, 0);
Labels.Add(AIConsts.BLOCKED_TILE, 0);
Labels.Add(AIConsts.RESERVED, 0);
Labels.Add(AIConsts.CLEARANCEVALUE,0);
Labels.Add(AIConsts.COLORR, 0);
Labels.Add(AIConsts.COLORG, 0);
for (int h = 0; h < _map.Rows; h++)
_grid[w, h] = _agent.TypeToCost(_map.GetCell(w, h).Type);
if (_agent == null)
if (_map.GetCell(w, h).Type == 0)
_grid[w, h] = 99;
_grid[w, h] = _map.GetCell(w, h).Type;
_grid[w, h] = _agent.GetCostOfCellType(_map.GetCell(w, h).Type);
float Heuristic = 0;
//Three different types of Heuristic calculation
if(HType==HeuristicType.Euclidean)
//if(HType==HeuristicType.Euclidean)
Heuristic = (int)(_heuristicEstimateValue * (Math.Sqrt(Math.Pow((_node.X - _endNode.X), 2) + Math.Pow((_node.Y - _endNode.Y), 2))));
// Heuristic = (int)(_heuristicEstimateValue * (Math.Sqrt(Math.Pow((_node.X - _endNode.X), 2) + Math.Pow((_node.Y - _endNode.Y), 2))));
else if(HType==HeuristicType.Manhattan)
//else //if(HType==HeuristicType.Manhattan)
Heuristic = _heuristicEstimateValue * (Math.Abs(_endNode.X - _node.X) + Math.Abs(_endNode.Y - _node.Y));
else if(HType==HeuristicType.Diagonal)
//else if(HType==HeuristicType.Diagonal)
Heuristic = _heuristicEstimateValue * Math.Max(Math.Abs(_node.X - _endNode.X), Math.Abs(_node.X- _endNode.Y));
// Heuristic = _heuristicEstimateValue * Math.Max(Math.Abs(_node.X - _endNode.X), Math.Abs(_node.X- _endNode.Y));
_node.H = (int)Heuristic;
public static class AIConsts
public const uint BLOCKED_TILE = 0;
public const int ISVALIDCLUSTEREDGE = 1;
public const int RESERVED = 1;
public const int CLEARANCEVALUE = 2;
public const int COLORR = 3;
public const int COLORG = 4;
public const int COLORB = 5;
public const int COLORA = 6;
public const int ISGROUPMEMBER = 7;
public const int GROUPID= 8;
using Brains.Framework.QuadTree;
using Brains.Framework.Map;
namespace Brains.Framework
private List<Agent> _agentsToRemove = new List<Agent>();
private Texture2D _mapTexture;
private WorldMap _map;
//Public properties
public List<Agent> Actors = new List<Agent>();
public Dictionary<int,Group> Groups { get; set; }
/// Gets the world map
public WorldMap Map { get { return _map; } }
public World()
Groups = new Dictionary<int, Group>();
//Public Methods
foreach (var item in Actors)
item.UpdatePerception(gameTime);
item.Update(gameTime);
if (_agentsToRemove.Count > 0)
SetupMap(width, height, cellsize, width / cellsize, height / cellsize,typeof(Grid));
protected static sbyte[,] direction = new sbyte[4, 2]
{ 0,-1} ,
{ 1, 0},
{ 0, 1},
{-1, 0}
};
/// This method will create a game Map of the defined size and automatically cluster the map into grids
public void AnotateMap()
List<QuadTreePositionItem<GridCell>> list = new List<QuadTreePositionItem<GridCell>>();
219
for (int x = 0; x < cols; x++)
220
221
222
SetHorizontalEntrancesOnGrid(x, y);
//Check right edge
223
SetVerticalEntrancesOnGrid(x, y);
if (cluster.Grids.Count > index + 1)
224
////Check right edge
225
//if (cluster.Grids.Count > index + 1)
for (int row = 0; row < cluster.Grids[index].Rows; row++)
// for (int row = 0; row < cluster.Grids[index].Rows; row++)
GridCell leftcell = cluster.Grids[index].GetCell(
// {
cluster.Grids[index].Cols - 1,
// GridCell leftcell = cluster.Grids[index].GetCell(
row);
// cluster.Grids[index].Cols - 1,
GridCell rightcell = cluster.Grids[index + 1].GetCell(
// row);
0,
// GridCell rightcell = cluster.Grids[index + 1].GetCell(
if (leftcell.Type != AIConsts.BLOCKED_TILE &&
// if (leftcell.Type != AIConsts.BLOCKED_TILE &&
rightcell.Type != AIConsts.BLOCKED_TILE)
// rightcell.Type != AIConsts.BLOCKED_TILE)
leftcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
// //leftcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
rightcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
// //rightcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
218
// }
//check left edge
////check left edge
if (index > 1)
//if (index > 1)
GridCell leftcell = cluster.Grids[index - 1].GetCell(
// GridCell leftcell = cluster.Grids[index - 1].GetCell(
cluster.Grids[index - 1].Cols - 1,
// cluster.Grids[index - 1].Cols - 1,
GridCell rightcell = cluster.Grids[index].GetCell(
// GridCell rightcell = cluster.Grids[index].GetCell(
//check bottom edge
////check bottom edge
if (index + cols < cluster.Grids.Count)
//if (index + cols < cluster.Grids.Count)
for (int col = 0; col < cluster.Grids[index].Cols; col++)
// for (int col = 0; col < cluster.Grids[index].Cols; col++)
GridCell topcell = cluster.Grids[index].GetCell(
// GridCell topcell = cluster.Grids[index].GetCell(
col,
// col,
cluster.Grids[index].Rows - 1);
// cluster.Grids[index].Rows - 1);
GridCell bottomcell = cluster.Grids[index + cols].GetCell(
// GridCell bottomcell = cluster.Grids[index + cols].GetCell(
0);
if (topcell.Type != AIConsts.BLOCKED_TILE &&
// if (topcell.Type != AIConsts.BLOCKED_TILE &&
bottomcell.Type != AIConsts.BLOCKED_TILE)
// bottomcell.Type != AIConsts.BLOCKED_TILE)
bottomcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
// // bottomcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
topcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
// // topcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
//Check Top
////Check Top
if (index - cols > 0)
//if (index - cols > 0)
GridCell topcell = cluster.Grids[index - cols].GetCell(
// GridCell topcell = cluster.Grids[index - cols].GetCell(
cluster.Grids[index - cols].Rows - 1);
// cluster.Grids[index - cols].Rows - 1);
GridCell bottomcell = cluster.Grids[index].GetCell(
// GridCell bottomcell = cluster.Grids[index].GetCell(
// //bottomcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
// //topcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;
index++;
//Precalculate paths for each grid transition
int gridIndex = 0;
foreach (var item in Map.ClusterGrid.Grids)
int y = (gridIndex - (gridIndex % Map.ClusterGrid.Cols)) / Map.ClusterGrid.Cols;
int x = gridIndex % Map.ClusterGrid.Cols;
//North To East
if (y > 0 && x < Map.ClusterGrid.Cols - 1)
PredeterminePaths(item,x, y - 1, x + 1, y);
//East To South
if (x < Map.ClusterGrid.Cols - 1 && y<Map.ClusterGrid.Rows-1)
PredeterminePaths(item, x + 1, y, x, y + 1);
//South To West
if (y < Map.ClusterGrid.Rows - 1 && x > 0)
PredeterminePaths(item, x, y + 1, x - 1, y);
//West To Nort
if (x>0 && y>0)
PredeterminePaths(item, x - 1, y, x, y - 1);
//West To East
if (x > 0 && x < Map.ClusterGrid.Cols-1)
PredeterminePaths(item, x - 1, y, x + 1, y);
//North To South
if (y > 0 && y < Map.ClusterGrid.Rows- 1)
PredeterminePaths(item, x, y - 1, x, y + 1);
gridIndex++;
//Cluster cl = Map.ClusterGrid;
//int index1 = 0;
//foreach (var item in Map.ClusterGrid.Grids)
// int y = (index1 - (index1 % cl.Cols)) / cl.Cols;
// int x = index1 % cl.Cols;
// //Top To Right
// if (y > 0 && x < cl.Cols - 1)
// int indexF = (y-1) * cl.Cols + x ;
// int indexT = y * cl.Cols + (x+1);
// GridCell from;
// GridCell to;
// from = GetFreeCellAt(item, Direction.up);
// to = GetFreeCellAt(item, Direction.rigth);
// if(from!=null&& to!=null)
// CalculatePath(from, to,indexF,indexT);
// //Right To Bottom
// if (y < cl.Rows - 1 && x < cl.Cols - 1)
// int indexF = y * cl.Cols + (x + 1);
// int indexT = (y + 1) * cl.Cols + x;
// from = GetFreeCellAt(item, Direction.rigth);
// to = GetFreeCellAt(item, Direction.down);
// if (from != null && to != null)
// CalculatePath(from, to, indexF, indexT);
// //Bottom To Left
// if (y < cl.Rows - 1 && x > 0)
394
395
// int indexF = (y + 1) * cl.Cols + x;
396
// int indexT = y * cl.Cols + (x - 1);
397
398
399
400
// from = GetFreeCellAt(item, Direction.down);
401
// to = GetFreeCellAt(item, Direction.left);
402
403
404
405
// //Left To Top
406
// if (y > 0 && x > 0)
407
408
// int indexF = y * cl.Cols + (x-1);
409
// int indexT = (y-1) * cl.Cols + x;
410
411
412
413
// from = GetFreeCellAt(item, Direction.left);
414
// to = GetFreeCellAt(item, Direction.up);
415
416
417
418
// //Top to bottom
419
// if (y > 0 && y < cl.Rows - 1)
420
421
// int indexF = (y - 1) * cl.Cols + x;
422
423
424
425
426
427
428
429
430
431
// //Left To Right
432
// if (x > 0 && x < cl.Cols - 1)
433
434
// int indexF = y * cl.Cols + (x - 1);
435
// int indexT = y * cl.Cols + (x + 1);
436
437
438
439
440
441
442
443
444
445
// index1++;
446
447
448
449
private void PredeterminePaths(Grid grid,int x1,int y1,int x2,int y2)
450
451
452
int indexF = Map.ClusterGrid.GetGridIndex(x1, y1);
453
int indexT = Map.ClusterGrid.GetGridIndex(x2, y2);
454
455
Grid gridA = Map.ClusterGrid.GetGrid(x1, y1);
456
GridCell cellA= GetValidCellFromEntrance(gridA,grid);
457
458
Grid gridB= Map.ClusterGrid.GetGrid(x2, y2);
459
GridCell cellB = GetValidCellFromEntrance(gridB, grid);
460
461
if (cellB != null && cellA != null)
462
463
CalculatePath(
grid.GetCell(cellA.X,cellA.Y),
grid.GetCell(cellB.X, cellB.Y),
indexF,
indexT);
private GridCell GetValidCellFromEntrance(Grid fromGrid,Grid toGrid)
foreach (var entrance in Map.ClusterGrid.Entrances)
if (entrance.CellA.Parent == fromGrid && entrance.CellB.Parent==toGrid)
476
return entrance.CellB;
477
if (entrance.CellB.Parent == fromGrid && entrance.CellA.Parent == toGrid)
478
return entrance.CellA;
479
480
481
482
483
private void SetVerticalEntrancesOnGrid(int x, int y)
484
485
bool checkEast = false;
486
bool checkWest = false;
487
488
Grid thisGrid = Map.ClusterGrid.GetGrid(x, y);
489
490
if (x > 0)
491
checkWest= true;
492
493
if (x < Map.ClusterGrid.Cols- 1)
494
checkEast = true;
495
496
if (checkEast)
497
498
Grid eastGrid = Map.ClusterGrid.GetGrid(x+1, y);
499
SetVertEntranceBetweenGrids(thisGrid, eastGrid);
500
501
if (checkWest)
502
503
Grid westGrid= Map.ClusterGrid.GetGrid(x-1, y);
504
SetVertEntranceBetweenGrids(thisGrid, westGrid);
505
506
507
508
private void SetVertEntranceBetweenGrids(Grid gridA, Grid gridB)
509
510
int yIndexa = 0;
511
int yIndexb = gridA.Cols- 1;
512
if (gridB.Position.X > gridA.Position.X)
513
514
yIndexa = yIndexb;
515
yIndexb = 0;
516
517
//Start near the middle
518
int startRow = gridA.Rows/ 2;
519
//Currently supports 1 transition per set of grids
520
bool continueChecking = true;
521
//Loop to end ignoring the corner cell
522
for (int i = startRow; i < gridA.Rows - 1; i++)
523
524
525
GridCell _edgeCell = gridA.GetCell(yIndexa,i);
526
GridCell _adjacentCell = gridB.GetCell(yIndexb,i);
527
if (_edgeCell.Labels[AIConsts.BLOCKED_TILE] == 0 &&
528
_adjacentCell.Labels[AIConsts.BLOCKED_TILE] == 0)
529
530
Map.ClusterGrid.AddEntrance(_edgeCell, _adjacentCell);
531
continueChecking = false;
532
if (continueChecking)
//Loop to beginning column ignoring the corner cell
for (int i = startRow; i > 0; i--)
540
GridCell _edgeCell = gridA.GetCell(yIndexa, i);
541
GridCell _adjacentCell = gridB.GetCell(yIndexb, i);
542
if (_edgeCell.Labels[AIConsts.BLOCKED_TILE] == 0 && _adjacentCell.Labels[AIConsts.BLOCKED_TILE] == 0)
543
544
545
546
547
548
549
550
551
552
553
private void SetHorizontalEntrancesOnGrid(int x, int y)
554
555
bool checkNorth = false;
556
bool checkSouth = false;
557
558
Grid thisGrid = Map.ClusterGrid.GetGrid(x,y);
559
560
if (y > 0)
561
checkNorth = true;
562
563
if (y < Map.ClusterGrid.Rows-1)
564
checkSouth= true;
565
566
if (checkNorth)
567
568
Grid northGrid = Map.ClusterGrid.GetGrid(x, y - 1);
569
SetHorizEntranceBetweenGrids(thisGrid, northGrid);
570
571
if (checkSouth)
572
573
Grid southGrid = Map.ClusterGrid.GetGrid(x, y + 1);
574
SetHorizEntranceBetweenGrids(thisGrid, southGrid);
575
576
577
578
579
580
private void SetHorizEntranceBetweenGrids(Grid gridA, Grid gridB)
581
582
583
int yIndexb = gridA.Rows - 1;
584
if (gridB.Position.Y > gridA.Position.Y)
585
586
587
588
589
590
int startCol = gridA.Cols / 2;
591
592
593
594
for (int i = startCol; i < gridA.Cols - 1; i++)
595
596
597
GridCell _edgeCell = gridA.GetCell(i, yIndexa);
598
GridCell _adjacentCell = gridB.GetCell(i, yIndexb);
599
600
601
602
603
604
605
606
607
608
609
610
for (int i = startCol; i > 0; i--)
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
private void CalculatePath(GridCell from, GridCell to,int gridfrom,int gridto)
627
628
PathFinding.PathFinder _f = new Brains.Framework.PathFinding.PathFinder();
629
_f.Grid = from.Parent;
630
_f.StartNode = from;
631
_f.EndNode = to;
632
_f.Reset();
633
634
while (_f.State == Brains.Framework.PathFinding.PathFinderState.Working)
635
636
_f.Iterate();
637
638
if (_f.State == Brains.Framework.PathFinding.PathFinderState.Finished)
639
640
// copying nodes
641
PreStoredPath _path = new PreStoredPath();
642
_path.Nodes = new List<StoredPathNode>();
643
644
int counter = 0;
645
//for (int index = pathFinder.closeList.Count - 1; index >= 0; index--)
646
for (int index = 0; index <= _f.closeList.Count - 1; index++)
647
648
StoredPathNode newNode = new StoredPathNode();
649
Grid grid = from.Parent;
650
GridCell _node = grid.GetCell(_f.closeList[index].X,
651
_f.closeList[index].Y);
652
newNode.nodePosition.X = grid.GetCell(_f.closeList[index].X,
653
_f.closeList[index].Y).Position.X;
654
newNode.nodePosition.Y = grid.GetCell(_f.closeList[index].X,
655
_f.closeList[index].Y).Position.Y;
656
newNode.X = _f.closeList[index].X;
657
newNode.Y = _f.closeList[index].Y;
658
659
660
_path.FromGrid =gridfrom;
661
_path.ToGrid = gridto;
662
//pathNodes[counter] = newNode;
663
_path.Nodes.Add(newNode);
664
counter++;
665
666
667
668
from.Parent.PredeterminedPaths.Add(_path);
669
670
if (_f.State == Brains.Framework.PathFinding.PathFinderState.Failed)
671
672
Console.WriteLine("");
673
674
675
676
677
/// Adds the specified Actor to the Actors collection
678
679
/// <param name="cols">The number of cols to split the map into</param>
710
/// <param name="rows">The number of rows to split the map into</param>
711
/// <param name="gridType">The type of grid to create</param>
712
public void LoadMapDataFromTexture(Texture2D texture, int cols, int rows, int cellSize, Type gridType)
713
public void LoadMapDataFromTexture(Texture2D texture, int clusterColumnSplit, int clusterRowSplit, int cellSize, Type gridType)
714
_mapTexture = texture;
715
716
Vector2 position = new Vector2();
717
int clusterCols = texture.Width / cols;
718
int clusterCols = texture.Width / clusterColumnSplit;
int clusterRows = texture.Height / rows;
719
int clusterRows = texture.Height / clusterRowSplit;
720
SetupMap(
721
texture.Width * cellSize,
722
gridType);
727
728
int index = 0;
729
for (int y = 0; y < rows; y++)
730
for (int y = 0; y < clusterRowSplit; y++)
731
732
for (int x = 0; x < clusterColumnSplit; x++)
733
Grid item = Map.ClusterGrid.Grids[index];
734
735
794
_agentsToRemove.Add(agent);
795
796
797
798
public void AddGroup(Group group)
799
800
Groups.Add(group.GroupID, group);
801
802
public Group GetGroup(int id)
803
804
return Groups[id];
805
806
807
{{[Brains.Framework.Designer.Behavior("DieBehavior")]{{{{private AIEngine _engine;public Demo1():base("Demo 1 - Basic Pathfinding","Click a valid grid cell to spawn a basic actor to pathfind to the destination\n" +"Red Cross : Blocked Cell\n" +"Empty Tile : Traversable Cell\n" +"Greed Circle: Destination Cell"){{Title = "Demo 1 - Basic Pathfinding";Description = "Click a valid grid cell to spawn a basic actor to pathfind to the destination\n" +"Red Cross : Blocked Cell\n" +"Empty Tile : Traversable Cell\n" +"Greed Circle: Destination Cell";//primitiveBatch.CameraPosition = new Vector2(-(_engine.World.Map.Cluster[0].Width / 2), -(_engine.World.Map.Cluster[0].Height / 2));((DrawableWorld)_engine.World).Font = gameFont;((DrawableWorld)_engine.World).Batch = ScreenManager.SpriteBatch;primitiveBatch.CameraPosition = new Vector2(CenterCamOnMap();-ScreenManager.GraphicsDevice.Viewport.Width / 2 +_engine.World.Map.ClusterGrid.Grids[0].Width / 2,-ScreenManager.GraphicsDevice.Viewport.Height / 2 +_engine.World.Map.ClusterGrid.Grids[0].Height / 2);{{_engine = new AIEngine();content.Load<Texture2D>("DemoTextures/MAPDemo1"),content.Load<Texture2D>("DemoTextures/MAPDemo1"),{{actor.Locomotion = new Brains.Framework.Locomotion.LocomtionSteering();actor.Locomotion = new Brains.Framework.Locomotion.LocomotionController();{{{{AIEngine _engine;public Demo2():base("Demo 2 - Patrol",""){{Title = "Demo 2 - Patrol";Description = "An Agent is added to the world and set to patrol an area.";//primitiveBatch.CameraPosition = new Vector2(-(_engine.World.Map.Cluster[0].Width / 2), -(_engine.World.Map.Cluster[0].Height / 2));CenterCamOnMap();((DrawableWorld)_engine.World).Font = gameFont;((DrawableWorld)_engine.World).Batch = ScreenManager.SpriteBatch;primitiveBatch.CameraPosition = new Vector2(-ScreenManager.GraphicsDevice.Viewport.Width / 2 +_engine.World.Map.ClusterGrid.Grids[0].Width / 2,-ScreenManager.GraphicsDevice.Viewport.Height / 2 +_engine.World.Map.ClusterGrid.Grids[0].Height / 2);{{_engine = new AIEngine();content.Load<Texture2D>("DemoTextures/MAPDemo2"),content.Load<Texture2D>("DemoTextures/MAPDemo2"),{{{{AIEngine _engine;public Demo3():base("Demo 3 - Custom Behaviors",""){{TransitionOffTime = TimeSpan.FromSeconds(0.5);Title = "Demo 3 - Custom Behaviors";Description = "Custom Behaviors";//primitiveBatch.CameraPosition = new Vector2(-(_engine.World.Map.Cluster[0].Width / 2), -(_engine.World.Map.Cluster[0].Height / 2));((DrawableWorld)_engine.World).Font = gameFont;((DrawableWorld)_engine.World).Batch = ScreenManager.SpriteBatch;CenterCamOnMap();{{_engine = new AIEngine();content.Load<Texture2D>("DemoTextures/MAPDemo3"),content.Load<Texture2D>("DemoTextures/MAPDemo3"),{{{{AIEngine _engine;public Demo4():base("Demo 4 - Steering Motion Controller",""){{Title = "Demo 4 - Steering Motion Controller";Description = "";//primitiveBatch.CameraPosition = new Vector2(-(_engine.World.Map.Cluster[0].Width / 2), -(_engine.World.Map.Cluster[0].Height / 2));((DrawableWorld)_engine.World).Font = gameFont;((DrawableWorld)_engine.World).Batch = ScreenManager.SpriteBatch;primitiveBatch.CameraPosition = new Vector2(CenterCamOnMap();-ScreenManager.GraphicsDevice.Viewport.Width / 2 +_engine.World.Map.ClusterGrid.Grids[0].Width / 2,-ScreenManager.GraphicsDevice.Viewport.Height / 2 +_engine.World.Map.ClusterGrid.Grids[0].Height / 2);{{_engine = new AIEngine();content.Load<Texture2D>("DemoTextures/MAPDemoBlank8"),content.Load<Texture2D>("DemoTextures/MAPDemoBlank8"),{{{{AIEngine _engine;public Demo5():base("Demo 5 - A Bigger World",""){{Title = "Demo 5 - A Bigger World";Description = "An Agent is added to the world and set to patrol an area.";//primitiveBatch.CameraPosition = new Vector2(-(_engine.World.Map.Cluster[0].Width / 2), -(_engine.World.Map.Cluster[0].Height / 2));((DrawableWorld)_engine.World).Font = gameFont;((DrawableWorld)_engine.World).Batch = ScreenManager.SpriteBatch;CenterCamOnMap();((DrawableWorld)_engine.World).Batch = ScreenManager.SpriteBatch;((DrawableWorld)_engine.World).Font= gameFont;{{_engine = new AIEngine();content.Load<Texture2D>("DemoTextures/MAPDemo3"),content.Load<Texture2D>("DemoTextures/MAPDemo3"),8,4,8,4,//GridCell fromcell=_engine.World.Map.AllCells.First<GridCell>(// a => a.Labels[AIConsts.COLORR]==0&&// a.Labels[AIConsts.COLORG]==255 &&// a.Labels[AIConsts.COLORB]==0);//GridCell tocell = _engine.World.Map.AllCells.First<GridCell>(// a => a.Labels[AIConsts.COLORR] == 255 &&// a.Labels[AIConsts.COLORG] == 0 &&// a.Labels[AIConsts.COLORB] == 0);//GameActor actor = new GameActor(fromcell.Position, 5);//actor.Locomotion = new Brains.Framework.Locomotion.LocomtionSteering();actor.Locomotion.MaxSpeed = 50;//actor.Locomotion.MaxSpeed = 70;//actor.Locomotion.MaxRotation = MathHelper.TwoPi;//_engine.World.AddActor(actor);//SequenceBehavior _sequence = new SequenceBehavior();//DrawableBehaviorGoTo _goto = new DrawableBehaviorGoTo();//_goto.StartNode = fromcell;//_goto.EndNode = tocell;//_sequence.SubBehaviors.Add(_goto);//_sequence.SubBehaviors.Add(new DieBehavior());//actor.RootBehavior = _sequence;{{public string Title { get; set; }public string Title { get; set; }public string Description{ get; set; }public string Description{ get; set; }public DemoGameScreen(string title,string description){{{{{gameFont = content.Load<SpriteFont>("gamefont");gameFont = content.Load<SpriteFont>("gamefont");titleFont= content.Load<SpriteFont>("titlefont");titleFont= content.Load<SpriteFont>("titlefont");playGameMenuEntry = new MenuEntry("Demo4 - Steering Motion Controller");playGameMenuEntry = new MenuEntry("Demo4 - Steering Motion Controller");playGameMenuEntry = new MenuEntry("Demo5 - A Bigger World");playGameMenuEntry = new MenuEntry("Demo6 - Combining Behaviors");playGameMenuEntry = new MenuEntry("Demo7 - Group Movement");MenuEntry optionsMenuEntry = new MenuEntry("Options");MenuEntry optionsMenuEntry = new MenuEntry("Options");MenuEntry exitMenuEntry = new MenuEntry("Exit");MenuEntry exitMenuEntry = new MenuEntry("Exit");{{foreach (var item in behavior.SubBehaviors)if (behavior is ISubBehaviorHolder){{{if (item.State == BehaviorState.Running && item is IRender)((IRender)item).Render(batch);DrawBehavior(item, batch);}{{{{{if (SubBehaviors[CurrentSubBehavior] is IRender)if (CurrentSubBehavior > 0){{((IRender)SubBehaviors[CurrentSubBehavior]).Render(batch);if (SubBehaviors[CurrentSubBehavior] is IRender)}for (int i = 0; i < SubBehaviors[CurrentSubBehavior].SubBehaviors.Count; i++){if (SubBehaviors[CurrentSubBehavior].SubBehaviors[i] is FollowPathBehavior){{DrawableBehaviorGoTo.DrawFollowPath(SubBehaviors[CurrentSubBehavior].SubBehaviors[i] as FollowPathBehavior,((IRender)SubBehaviors[CurrentSubBehavior]).Render(batch);batch);{{{public virtual void Render(PrimitiveBatch batch){{{{{{{{private void DrawCell(PrimitiveBatch batch, QuadTreePositionItem<GridCell> item)protected virtual void DrawCell(PrimitiveBatch batch, QuadTreePositionItem<GridCell> item){{{{{//string clearance = item.Parent.Labels[AIConsts.CLEARANCEVALUE].ToString();if (Batch != null)//Batch.DrawString(// Font,// clearance,// (item.Position - batch.CameraPosition) / batch.Zoom,// Color.White,// 0,// new Vector2(8,8),// 1,// SpriteEffects.None,// 0);if (item.Parent.Labels[AIConsts.ISVALIDCLUSTEREDGE] == 1){{batch.DrawCircle(item.Parent.Position, 5, Color.Green);//string clearance = item.Parent.Labels[AIConsts.CLEARANCEVALUE].ToString();Vector2 half = new Vector2(item.Parent.Parent.CellSize / 2);//Batch.DrawString(batch.DrawLine(// Font,item.Rect.TopLeft+new Vector2(24),// clearance,item.Rect.BottomRight - new Vector2(24),// (item.Position - batch.CameraPosition) / batch.Zoom,Color.Green);// Color.White,// 0,// new Vector2(8, 8),// 1,// SpriteEffects.None,// 0);batch.DrawLine(item.Rect.TopRight - new Vector2(24, -24),item.Rect.BottomLeft + new Vector2(24, -24),Color.Green);{{<value>C:\Users\rik\Documents\Visual Studio 2008\Projects\AITester\AITester\bin\x86\Debug\AITester.exe</value><value>C:\Work\XNA\BRAINS\src\AIDemos\bin\x86\Debug\AIDemos.exe</value><ItemGroup><Folder Include="Classes\" /></ItemGroup>string assemblyPath;{{assemblyPath = Path.GetDirectoryName(path);//File.Copy(// path,// Application.StartupPath +"\\"+ Path.GetFileName(path),true);LoadAssembly(Application.StartupPath + "\\" + "AIFramework.dll");AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);LoadAssembly(Application.StartupPath + "\\" + Path.GetFileName(path));LoadAssembly(Application.StartupPath + "\\" + "Brains.Framework.dll");LoadAssembly(path);{Console.Write("");{{_rootNode.AddParameter("RootType", "");_rootNode.AddParameter("RootType", "");{{TreeNode node = treeView1.SelectedNode;splitContainer1.Panel2.Controls.Clear();propertyGrid1.SelectedObject = treeView1.SelectedNode.Tag;BehaviorNode _node=node.Tag as BehaviorNode;//TreeNode node = treeView1.SelectedNode;Point _controlPosition = new Point(15, 25);//splitContainer1.Panel2.Controls.Clear();int gap = 25;//BehaviorNode _node=node.Tag as BehaviorNode;foreach (var item in _node.Parameters)//Point _controlPosition = new Point(15, 25);{//int gap = 25;Label label = new Label();//foreach (var item in _node.Parameters)label.AutoSize = true;//{label.Text = item.Name;// Label label = new Label();label.Location = _controlPosition;// label.AutoSize = true;// label.Text = item.Name;// label.Location = _controlPosition;// splitContainer1.Panel2.Controls.Add(label);// Control ctrl = CreateParameterControl(item);// ctrl.Location = new Point(_controlPosition.X + 60, _controlPosition.Y-2);// splitContainer1.Panel2.Controls.Add(ctrl);// _controlPosition.Y += gap;//}{{{{{this.splitContainer1.Panel1.Controls.Add(this.treeView1);this.splitContainer1.Panel1.Controls.Add(this.splitContainer2);//// splitContainer1.Panel2//this.splitContainer1.Panel2.Controls.Add(this.behaviorTreeViewer1);this.treeView1.Size = new System.Drawing.Size(235, 539);this.treeView1.Size = new System.Drawing.Size(235, 303);this.compositeToolStripMenuItem.Size = new System.Drawing.Size(152, 22);this.compositeToolStripMenuItem.Size = new System.Drawing.Size(132, 22);this.actionsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);this.actionsToolStripMenuItem.Size = new System.Drawing.Size(132, 22);this.conditionToolStripMenuItem.Size = new System.Drawing.Size(152, 22);this.conditionToolStripMenuItem.Size = new System.Drawing.Size(132, 22);[global::System.Configuration.DefaultSettingValueAttribute("C:\\Users\\rik\\Documents\\Visual Studio 2008\\Projects\\AITester\\AITester\\bin\\x86\\Debu" +[global::System.Configuration.DefaultSettingValueAttribute("C:\\Work\\XNA\\BRAINS\\src\\AIDemos\\bin\\x86\\Debug\\AIDemos.exe")]"g\\AITester.exe")]public string Behaviors {public string Behaviors {get {get {<Value Profile="(Default)">C:\Users\rik\Documents\Visual Studio 2008\Projects\AITester\AITester\bin\x86\Debug\AITester.exe</Value><Value Profile="(Default)">C:\Work\XNA\BRAINS\src\AIDemos\bin\x86\Debug\AIDemos.exe</Value>public Vector2 Position { get; set; }public Vector2 Position { get; set; }{Grid map = ParentWorld.Map.ClusterGrid.Grids[0];Grid map = ParentWorld.Map.ClusterGrid.GetGridAtPosition(Position);if (map == null)return;// xComponent = xComponent - 0.5f;//yComponent = yComponent - 0.5f;Console.Write("");Console.Write("");BehaviorBase _behavior = CreateBehaviorInstance(_rootNode.Parameters[0].Value);CompositeBehavior _behavior = CreateBehaviorInstance(_rootNode.Parameters[0].Value);parentBehavior.SubBehaviors.Add(behavior);if(parentBehavior is ISubBehaviorHolder)((ISubBehaviorHolder)parentBehavior).SubBehaviors.Add(behavior);private BehaviorBase CreateBehaviorInstance(string typeName)private CompositeBehavior CreateBehaviorInstance(string typeName){{{{BehaviorBase behavior =(BehaviorBase)item.CreateInstance(typeName);CompositeBehavior behavior =(CompositeBehavior)item.CreateInstance(typeName);public virtual byte TypeToCost(int type)/// <summary>/// Gets the cost of a grid cell type for use with pathfinding./// </summary>/// <param name="type">The Type value from a GridCell</param>/// <returns>The cost of the cell</returns>/// <remarks>Override this method for greater flexibility in pathfinding</remarks>public virtual byte GetCostOfCellType(int type){{{{<Compile Include="Behaviors\BehaviorBase.cs" /><Compile Include="Behaviors\CompositeBehavior.cs" /><Compile Include="Behaviors\BehaviorTask.cs" /><Compile Include="Behaviors\TaskBehavior.cs" />public string BehaviorName { get; set; }{{public const float WanderRadius = 1.2f;public const float WanderRadius = 20;public const float WanderDistance = 2.0f;public const float WanderDistance = 30;//Cohesion= 0x00020,//Seperation= 0x00040,//Alignment = 0x00080,{{public void TurnOnSeperation(){TurnOn(BehaviorType.Seperation);}public void TurnOffSeperation(){TurnOff(BehaviorType.Seperation);}public void TurnOnCohesion(){TurnOn(BehaviorType.Cohesion);}public void TurnOffCohesion(){TurnOff(BehaviorType.Cohesion);}public void TurnOnAlignment(){TurnOn(BehaviorType.Alignment);}public void TurnOffAlignment(){TurnOff(BehaviorType.Alignment);}{{private float MaxForce = 4;private float MaxForce = 2;public Vector2 SeekPos { get; set; }public Vector2 SeekPos { get; set; }public Deceleration DecelerationSpeed { get; set; }public Deceleration DecelerationSpeed { get; set; }{{{{Owner.Orientation = Heading;// (float)Math.Atan2(Heading.Y, Heading.X);if(Heading!=Vector2.Zero)Owner.Orientation = Heading;// (float)Math.Atan2(Heading.Y, Heading.X);{{{{{{{{{{{{{{{{{{{{double JitterThisTimeSlice = WanderJitter * timeElapsed;float JitterThisTimeSlice = WanderJitter * timeElapsed;_wanderTarget+= new Vector2(RandomClamped() * WanderJitter,_wanderTarget += new Vector2(RandomClamped() * JitterThisTimeSlice,RandomClamped() * WanderJitter);RandomClamped() * JitterThisTimeSlice);{{}{{{{get { return Grids[0].Cols * Cols; }get { return Grids[0].Cols * Cols; }{{public int GetGridIndex(int x, int y){return y * Cols + x;}public Grid GetGrid(int x, int y){return Grids[GetGridIndex(x, y)];}internal void AddEntrance(GridCell cellA, GridCell cellB){if (!EntranceExists(cellA, cellB))Entrances.Add(new Entrance(cellA, cellB));}private bool EntranceExists(GridCell cellA, GridCell cellB){for (int i = 0; i < Entrances.Count; i++){Entrance ent = Entrances[i];if (ent.CellA == cellA && ent.CellB == cellB)return true;}return false;}public List<Entrance> Entrances = new List<Entrance>();{public GridCell CellA { get; set; }public GridCell CellB { get; set; }{{{{{{{get { return Position; }get { return Position+(Size/2); }public int Type { get { return _type; } set { _type = value; } }{get { return _type; }set{_type = value;Labels[AIConsts.BLOCKED_TILE] = _type == 0 ? 1 : 0;}}{{Labels.Add(AIConsts.ISVALIDCLUSTEREDGE, 0);Labels.Add(AIConsts.BLOCKED_TILE, 0);Labels.Add(AIConsts.RESERVED, 0);{{{{_grid[w, h] = _agent.TypeToCost(_map.GetCell(w, h).Type);if (_agent == null){if (_map.GetCell(w, h).Type == 0)_grid[w, h] = 99;else_grid[w, h] = _map.GetCell(w, h).Type;}else_grid[w, h] = _agent.GetCostOfCellType(_map.GetCell(w, h).Type);//if(HType==HeuristicType.Euclidean)// Heuristic = (int)(_heuristicEstimateValue * (Math.Sqrt(Math.Pow((_node.X - _endNode.X), 2) + Math.Pow((_node.Y - _endNode.Y), 2))));else if(HType==HeuristicType.Manhattan)//else //if(HType==HeuristicType.Manhattan)//else if(HType==HeuristicType.Diagonal)// Heuristic = _heuristicEstimateValue * Math.Max(Math.Abs(_node.X - _endNode.X), Math.Abs(_node.X- _endNode.Y));{{public const int ISVALIDCLUSTEREDGE = 1;public const int RESERVED = 1;{{public Dictionary<int,Group> Groups { get; set; }public WorldMap Map { get { return _map; } }public WorldMap Map { get { return _map; } }{{{{{{{{{{ 0,-1} ,{ 1, 0},{ 0, 1},{-1, 0}{{{{{{SetHorizontalEntrancesOnGrid(x, y);//Check right edgeSetVerticalEntrancesOnGrid(x, y);if (cluster.Grids.Count > index + 1)////Check right edge{//if (cluster.Grids.Count > index + 1)for (int row = 0; row < cluster.Grids[index].Rows; row++)//{{// for (int row = 0; row < cluster.Grids[index].Rows; row++)GridCell leftcell = cluster.Grids[index].GetCell(// {cluster.Grids[index].Cols - 1,// GridCell leftcell = cluster.Grids[index].GetCell(row);// cluster.Grids[index].Cols - 1,GridCell rightcell = cluster.Grids[index + 1].GetCell(// row);0,// GridCell rightcell = cluster.Grids[index + 1].GetCell(row);// 0,// row);// if (leftcell.Type != AIConsts.BLOCKED_TILE &&// rightcell.Type != AIConsts.BLOCKED_TILE){// {leftcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// //leftcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;rightcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// //rightcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// }// }//}////check left edge//if (index > 1){//{// for (int row = 0; row < cluster.Grids[index].Rows; row++){// {// GridCell leftcell = cluster.Grids[index - 1].GetCell(// cluster.Grids[index - 1].Cols - 1,// row);// GridCell rightcell = cluster.Grids[index].GetCell(// 0,// row);// if (leftcell.Type != AIConsts.BLOCKED_TILE &&// rightcell.Type != AIConsts.BLOCKED_TILE){// {leftcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// //leftcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;rightcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// //rightcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// }// }//}////check bottom edge//if (index + cols < cluster.Grids.Count){//{// for (int col = 0; col < cluster.Grids[index].Cols; col++){// {// GridCell topcell = cluster.Grids[index].GetCell(// col,// cluster.Grids[index].Rows - 1);// GridCell bottomcell = cluster.Grids[index + cols].GetCell(// col,// 0);// if (topcell.Type != AIConsts.BLOCKED_TILE &&// bottomcell.Type != AIConsts.BLOCKED_TILE){// {bottomcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// // bottomcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;topcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// // topcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// }// }//}////Check Top//if (index - cols > 0){//{// for (int col = 0; col < cluster.Grids[index].Cols; col++){// {// GridCell topcell = cluster.Grids[index - cols].GetCell(// col,// cluster.Grids[index - cols].Rows - 1);// GridCell bottomcell = cluster.Grids[index].GetCell(// col,// 0);// if (topcell.Type != AIConsts.BLOCKED_TILE &&// bottomcell.Type != AIConsts.BLOCKED_TILE){// {bottomcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// //bottomcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;topcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// //topcell.Labels[AIConsts.ISVALIDCLUSTEREDGE] = 1;// }// }//}{{{{{{{//{// {// {// {// {// {// {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{Console.WriteLine("");public void LoadMapDataFromTexture(Texture2D texture, int cols, int rows, int cellSize, Type gridType)public void LoadMapDataFromTexture(Texture2D texture, int clusterColumnSplit, int clusterRowSplit, int cellSize, Type gridType){{int clusterCols = texture.Width / cols;int clusterCols = texture.Width / clusterColumnSplit;int clusterRows = texture.Height / rows;int clusterRows = texture.Height / clusterRowSplit;for (int y = 0; y < rows; y++)for (int y = 0; y < clusterRowSplit; y++){{for (int x = 0; x < cols; x++)for (int x = 0; x < clusterColumnSplit; x++){{{{{{