this repo has no description
1using System.Drawing;
2using Peridot.Text;
3using System.Numerics;
4using Veldrid.StartupUtilities;
5using Veldrid;
6using Peridot;
7using System.Globalization;
8
9internal class Program
10{
11 public class Unit
12 {
13 public Vector2 Position;
14 public Vector2 Speed;
15 }
16
17 private static Dictionary<Color, List<Unit>> Groups = new();
18 private static Dictionary<(Color, Color), float> Rules = new();
19 private static Random rnd = new();
20 private static Size Bounds;
21 private static readonly float Gold = (MathF.Sqrt(5) + 1f) / 2f;
22
23 private static void Rule(float deltaTime, List<Unit> units1, List<Unit> units2, float g)
24 {
25 units1.AsParallel().ForAll(a =>
26 {
27 var force = new Vector2();
28
29 for (var j = 0; j < units2.Count; j++)
30 {
31 var b = units2[j];
32
33 var diff = a.Position - b.Position;
34 var distance = Vector2.Distance(a.Position, b.Position);
35 if (distance > 0 && distance < 80)
36 {
37 var F = g * (1f / distance);
38 force += diff * F;
39 }
40 }
41
42 a.Speed += force * 0.5f;
43 a.Position += a.Speed;
44
45 var m = 0.5f;
46
47 if (((a.Position.X <= 0 && a.Speed.X < 0) || (a.Position.X >= Bounds.Width && a.Speed.X > 0)))
48 a.Speed.X *= -m;
49 else
50 a.Speed.X *= m;
51
52 if (((a.Position.Y <= 0 && a.Speed.Y < 0) || (a.Position.Y >= Bounds.Height && a.Speed.Y > 0)))
53 a.Speed.Y *= -m;
54 else
55 a.Speed.Y *= m;
56 });
57 }
58
59 private static void AddUnits(int count, Color color)
60 {
61 if (!Groups.TryGetValue(color, out var units))
62 {
63 Groups[color] = units = new();
64 }
65
66 for(var i = 0; i < count; i++)
67 {
68 var x = rnd.Next(0, Bounds.Width);
69 var y = rnd.Next(0, Bounds.Height);
70
71 units.Add(new()
72 {
73 Position = new(x, y)
74 });
75 }
76 }
77
78 private static void Load()
79 {
80 Groups.Clear();
81 AddUnits(500, Color.Yellow);
82 AddUnits(500, Color.Red);
83 AddUnits(500, Color.Green);
84 AddUnits(500, Color.White);
85 AddUnits(500, Color.Purple);
86 }
87
88 private static void Gen()
89 {
90 var colors = new Color[] { Color.Yellow, Color.Red, Color.Green, Color.White, Color.Purple };
91 Rules.Clear();
92 Console.WriteLine();
93 Console.WriteLine();
94 Console.WriteLine();
95 Console.WriteLine("New Rules!");
96 Console.WriteLine();
97 foreach (var color1 in colors)
98 foreach(var color2 in colors)
99 {
100 var rule = rnd.NextSingle() - 0.5f;
101 Rules.Add((color1, color2), rule);
102 Console.WriteLine($"Rules.Add((Color.{color1.Name}, Color.{color2.Name}), {rule.ToString(CultureInfo.InvariantCulture)}f);");
103 }
104 }
105
106 private static void VirusRule()
107 {
108 Rules.Clear();
109 Rules.Add((Color.Yellow, Color.Yellow), 0.16813803f);
110 Rules.Add((Color.Yellow, Color.Red), -0.13937545f);
111 Rules.Add((Color.Yellow, Color.Green), 0.15008587f);
112 Rules.Add((Color.Yellow, Color.White), -0.3598255f);
113 Rules.Add((Color.Red, Color.Yellow), 0.12564862f);
114 Rules.Add((Color.Red, Color.Red), 0.096319795f);
115 Rules.Add((Color.Red, Color.Green), -0.12434393f);
116 Rules.Add((Color.Red, Color.White), -0.23231715f);
117 Rules.Add((Color.Green, Color.Yellow), 0.46440452f);
118 Rules.Add((Color.Green, Color.Red), 0.38713688f);
119 Rules.Add((Color.Green, Color.Green), -0.36697257f);
120 Rules.Add((Color.Green, Color.White), -0.033506453f);
121 Rules.Add((Color.White, Color.Yellow), -0.35188568f);
122 Rules.Add((Color.White, Color.Red), 0.1912772f);
123 Rules.Add((Color.White, Color.Green), 0.3761289f);
124 Rules.Add((Color.White, Color.White), 0.059764445f);
125 }
126
127 private static void Draw(float deltaTime, ISpriteBatch spriteBatch)
128 {
129 foreach(var rule in Rules)
130 {
131 if (!Groups.TryGetValue(rule.Key.Item1, out var units1) ||
132 !Groups.TryGetValue(rule.Key.Item2, out var units2))
133 continue;
134
135 Rule(deltaTime, units1, units2, rule.Value);
136 }
137
138 foreach(var pair in Groups)
139 {
140 foreach(var unit in pair.Value)
141 {
142 var rect = new RectangleF(unit.Position.X, unit.Position.Y, 4, 4);
143
144 var colorF = new ColorF(pair.Key) / 2;
145 var length = unit.Speed.Length();
146 colorF += colorF * length/ (length + 50);
147 colorF.A = 0.5f;
148
149 spriteBatch.DrawRect(rect, colorF, 1);
150 }
151 }
152 }
153
154 private static void Main(string[] args)
155 {
156 var title = "Peridot.Sample2";
157 var wci = new WindowCreateInfo(100, 100, 640, 480, WindowState.Normal, title);
158
159 var window = VeldridStartup.CreateWindow(wci);
160 var gd = VeldridStartup.CreateVulkanGraphicsDevice(
161 new(true,
162 Veldrid.PixelFormat.D32_Float_S8_UInt,
163 false,
164 ResourceBindingModel.Default,
165 true,
166 true),
167 window);
168
169 Bounds = new Size(window.Width, window.Height);
170 window.Resized += () =>
171 {
172 Bounds = new Size(window.Width, window.Height);
173 gd.MainSwapchain.Resize((uint)window.Width, (uint)window.Height);
174 };
175
176 window.KeyDown += (e) =>
177 {
178 if (e.Key == Key.G)
179 Gen();
180 else if (e.Key == Key.V)
181 VirusRule();
182 else if (e.Key == Key.R)
183 Load();
184 };
185
186
187 var peridot = new VPeridot(gd);
188
189 var shaders = peridot.LoadDefaultShaders();
190 var sbd = new SpriteBatchDescriptor(gd.MainSwapchain.Framebuffer.OutputDescription, shaders);
191 var sb = peridot.CreateSpriteBatch(sbd);
192
193 var tr = new TextRenderer(peridot, sb);
194 var cl = gd.ResourceFactory.CreateCommandList();
195 var fence = gd.ResourceFactory.CreateFence(false);
196
197 var time = DateTime.Now;
198
199 Load();
200 var count = 0.0;
201 while (window.Exists)
202 {
203 var now = DateTime.Now;
204 var delta = now - time;
205 var deltaTime = delta.TotalSeconds;
206 time = now;
207 count += deltaTime;
208
209 if (count > 1)
210 {
211 count -= 1;
212 window.Title = title + " " + (1f / deltaTime);
213 }
214
215 window.PumpEvents();
216
217 sb.Begin();
218 sb.ViewMatrix = Matrix4x4.CreateOrthographicOffCenter(0, Bounds.Width, 0, Bounds.Height, 0.01f, -100f);
219
220 Draw((float)deltaTime, sb);
221 sb.End();
222
223 cl.Begin();
224 cl.SetFramebuffer(gd.SwapchainFramebuffer);
225 cl.ClearColorTarget(0, RgbaFloat.Black);
226 cl.ClearDepthStencil(0f);
227 cl.DrawBatch(sb);
228 cl.End();
229
230 fence.Reset();
231 gd.SubmitCommands(cl, fence);
232 gd.WaitForFence(fence);
233 gd.SwapBuffers();
234 }
235 }
236}