]> git.r.bdr.sh - rbdr/super-polarity/blame - SuperPolarity/Actors/MainShip.cs
Update project to work on VS Code mac
[rbdr/super-polarity] / SuperPolarity / Actors / MainShip.cs
CommitLineData
9ad526c0 1using System;
2af83e98
BB
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
38c7d3f9 5using System.Threading;
2af83e98
BB
6using Microsoft.Xna.Framework;
7using Microsoft.Xna.Framework.Content;
8using Microsoft.Xna.Framework.Graphics;
b587e9d8 9using Microsoft.Xna.Framework.Audio;
2af83e98
BB
10
11namespace SuperPolarity
12{
13 class MainShip : Ship
14 {
38c7d3f9
BB
15
16 public static Color BlueColor;
17 public static Color RedColor;
18
38c7d3f9
BB
19 protected bool Shooting;
20 protected int ShotCooldown;
21
74c15570
BB
22 protected float CurrentImmortalTime;
23 protected float MaxImmortalTime;
24 protected bool Flashing;
25
b587e9d8
BB
26 protected SoundEffect PolarityChange;
27 protected SoundEffect ShootSound;
28 protected SoundEffect Hit;
29
9ad526c0
BB
30 // Aura stuff
31 protected Texture2D AuraPoint;
32 protected double AuraRadius;
33 protected double AuraAmplitude;
34 protected double AuraFrequency;
35 protected double AuraSubAmplitude;
36 protected double AuraWaveSize;
37 protected double AuraSubPhase;
38 protected double AuraSubFrequency;
39 public double[] EnemyModifications;
40 public double MaxEnemyModification;
41 public double EnemyModificationSpread;
42
74c15570 43 public MainShip(SuperPolarity newGame) : base(newGame) {}
2af83e98 44
38c7d3f9
BB
45 ~MainShip()
46 {
38c7d3f9
BB
47 }
48
2af83e98
BB
49 public override void Initialize(Texture2D texture, Vector2 position)
50 {
51 base.Initialize(texture, position);
52
9ad526c0 53 MainShip.BlueColor = new Color(71, 182, 226);
d0950076 54 MainShip.RedColor = new Color(235, 160, 185);
b587e9d8 55
9ad526c0
BB
56 AuraPoint = CreateCircle (2);
57
58 AuraRadius = 75;
59 AuraAmplitude = 7;
60 AuraFrequency = 3;
61 AuraSubAmplitude = 7;
62 AuraWaveSize = 3;
63 AuraSubPhase = 0;
64 AuraSubFrequency = 9 * Math.PI / 180;
65 MaxEnemyModification = 20;
66 EnemyModificationSpread = 10;
67 EnemyModifications = new double[360];
68 for ( int i = 0; i < EnemyModifications.Length; i++ ) {
69 EnemyModifications[i] = 0;
70 }
71
b587e9d8
BB
72 PolarityChange = game.Content.Load<SoundEffect>("Sound\\polaritychange");
73 ShootSound = game.Content.Load<SoundEffect>("Sound\\bullet");
74 Hit = game.Content.Load<SoundEffect>("Sound\\hit");
38c7d3f9 75
2af83e98
BB
76 SetPolarity(Polarity.Positive);
77
b587e9d8
BB
78 ActVelocity = 2.5f;
79
38c7d3f9 80 ShotCooldown = 50;
74c15570
BB
81 MaxImmortalTime = 1500;
82
83 BoxDimensions.X = 2;
84 BoxDimensions.Y = 2;
85 BoxDimensions.W = 2;
86 BoxDimensions.Z = 2;
87 InitBox();
2af83e98
BB
88
89 BindInput();
90 }
91
2af83e98
BB
92 void BindInput()
93 {
94 InputController.Bind("moveX", HandleHorizontalMovement);
95 InputController.Bind("moveY", HandleVerticalMovement);
96 InputController.Bind("changePolarity", HandleChangePolarity);
38c7d3f9
BB
97 InputController.Bind("shoot", HandleShot);
98 }
99
100 protected void HandleShot(float value)
101 {
b587e9d8
BB
102
103 Shooting = true;
104 Timer t = new Timer(new TimerCallback(UnlockShot));
105 t.Change(ShotCooldown, Timeout.Infinite);
106
107 if (Children.Count > 10)
108 {
109 return;
110 }
111
74c15570
BB
112 var bullet = ActorFactory.CreateBullet(Position, Angle);
113
114 Children.Add(bullet);
115 bullet.Parent = this;
116
b587e9d8 117 ShootSound.Play();
38c7d3f9
BB
118 }
119
120 protected void UnlockShot(object state)
121 {
122 InputController.Unlock("shoot");
b587e9d8 123 Shooting = false;
2af83e98
BB
124 }
125
126 protected void HandleChangePolarity(float value)
127 {
128 SwitchPolarity();
129 }
130
131 public void HandleHorizontalMovement(float value)
132 {
b587e9d8 133 if (value >= -0.5 && value <= 0.5)
2af83e98 134 {
b587e9d8 135 value = 0;
2af83e98
BB
136 }
137
b587e9d8 138 Velocity.X = value * MaxVelocity;
2af83e98
BB
139 }
140
141 public void HandleVerticalMovement(float value)
142 {
b587e9d8
BB
143 if (value >= -0.5 && value <= 0.5)
144 {
145 value = 0;
146 }
147
148 Velocity.Y = value * MaxVelocity;
2af83e98
BB
149 }
150
151 public override void SwitchPolarity()
152 {
153 base.SwitchPolarity();
b587e9d8 154 PolarityChange.Play();
74c15570 155 game.Player.ResetMultiplier();
2af83e98
BB
156 }
157
158 public override void SetPolarity(Polarity newPolarity)
159 {
9ad526c0 160 base.SetPolarity(newPolarity);;
2af83e98 161 }
9ad526c0 162
2af83e98
BB
163 public override void Update(GameTime gameTime)
164 {
165 base.Update(gameTime);
2af83e98 166 ConstrainToEdges();
74c15570 167 UpdateImmortality(gameTime);
38c7d3f9
BB
168 }
169
9ad526c0
BB
170 public void ResetEnemyModification() {
171 for ( int i = 0; i < EnemyModifications.Length; i++ ) {
172 EnemyModifications[i] = 0;
173 }
174 }
175
74c15570
BB
176 public void UpdateImmortality(GameTime gameTime)
177 {
178 if (Immortal)
179 {
180 CurrentImmortalTime += gameTime.ElapsedGameTime.Milliseconds;
181
182 if (Flashing)
183 {
184 Color = new Color(255, 255, 255, 128);
185 }
186 else
187 {
188 Color = Color.White;
189 }
190
191 Flashing = !Flashing;
192
193 if (CurrentImmortalTime > MaxImmortalTime)
194 {
195 Immortal = false;
196 Color = Color.White;
197 }
198 }
199 }
200
38c7d3f9
BB
201 public override void Move(GameTime gameTime)
202 {
b587e9d8
BB
203 var VelocityLimit = MaxVelocity;
204 var SavedVelocity = new Vector2(Velocity.X, Velocity.Y);
38c7d3f9
BB
205
206 if (Shooting)
207 {
b587e9d8
BB
208 VelocityLimit = ActVelocity;
209 }
38c7d3f9 210
b587e9d8
BB
211 if (SavedVelocity.X > VelocityLimit)
212 {
213 SavedVelocity.X = VelocityLimit;
214 }
38c7d3f9 215
b587e9d8
BB
216 if (SavedVelocity.X < -VelocityLimit)
217 {
218 SavedVelocity.X = -VelocityLimit;
219 }
38c7d3f9 220
b587e9d8
BB
221 if (SavedVelocity.Y > VelocityLimit)
222 {
223 SavedVelocity.Y = VelocityLimit;
224 }
225
226 if (SavedVelocity.Y < -VelocityLimit)
227 {
228 SavedVelocity.Y = -VelocityLimit;
38c7d3f9 229 }
b587e9d8
BB
230
231 Position.X = Position.X + SavedVelocity.X;
232 Position.Y = Position.Y + SavedVelocity.Y;
2af83e98
BB
233 }
234
235 public override void Magnetize(Ship ship, float distance, float angle)
236 {
237 }
238
239 protected void ConstrainToEdges()
240 {
241 if (Position.X < 0)
242 {
243 Position.X = 0;
244
245 if (Velocity.X < 0)
246 {
247 Velocity.X = 0;
248 }
249 }
250 if (Position.X > game.GraphicsDevice.Viewport.Width)
251 {
252 Position.X = game.GraphicsDevice.Viewport.Width;
253
254 if (Velocity.X > 0)
255 {
256 Velocity.X = 0;
257 }
258 }
259 if (Position.Y < 0)
260 {
261 Position.Y = 0;
262
263 if (Velocity.Y < 0)
264 {
265 Velocity.Y = 0;
266 }
267 }
268 if (Position.Y > game.GraphicsDevice.Viewport.Height)
269 {
270 Position.Y = game.GraphicsDevice.Viewport.Height;
271
272 if (Velocity.Y < 0)
273 {
274 Velocity.Y = 0;
275 }
276 }
277 }
278
9ad526c0
BB
279 public void UpdateEnemyModification(Ship enemy) {
280
281 var dx = enemy.Position.X - Position.X;
282 var dy = enemy.Position.Y - Position.Y;
283 var angleInDegrees = ((360 + Math.Round (Math.Atan2 (dy, dx) * 180 / Math.PI)) % 360);
284
285 for (var i = -EnemyModificationSpread; i < EnemyModificationSpread; i++) {
286 var strength = MaxEnemyModification - Math.Abs (i * MaxEnemyModification / EnemyModificationSpread);
287
288 var index = (int)((360 + angleInDegrees + i) % 360);
289
290 if (enemy.CurrentPolarity == CurrentPolarity) {
291 EnemyModifications[index] -= strength;
292 } else {
293 EnemyModifications[index] += strength;
294 }
295
296 if (EnemyModifications[index] > MaxEnemyModification) {
297 EnemyModifications[index] = MaxEnemyModification;
298 }
299
300 if (EnemyModifications[index] < -MaxEnemyModification) {
301 EnemyModifications[index] = -MaxEnemyModification;
302 }
303 }
304 }
305
306 public override void Draw(SpriteBatch spriteBatch)
2af83e98 307 {
9ad526c0 308 DrawCircle (spriteBatch);
2af83e98 309 base.Draw(spriteBatch);
9ad526c0
BB
310 //spriteBatch.Draw(BoxTexture, Box, new Color(255, 0, 255, 25));
311 }
312
313 protected void DrawCircle(SpriteBatch spriteBatch) {
314
315 var j = AuraWaveSize;
316 var subWaveRadius = 0.0;
317 var randomPosition = 0.0;
318
319 for (var i = 0; i < 360; i++) {
320 var angle = i * Math.PI / 180;
321
322 if (j == AuraWaveSize) {
323 subWaveRadius = AuraSubAmplitude * Math.Sin (randomPosition + AuraSubPhase);
324 randomPosition -= (2 * Math.PI / 8);
325 j = 0;
326 }
327 j++;
328
329 var radius = EnemyModifications[i] + subWaveRadius + AuraRadius + AuraAmplitude * Math.Sin (i / AuraFrequency);
330 var x = Position.X + radius * Math.Cos (angle);
331 var y = Position.Y + radius * Math.Sin (angle);
332
333 x = Math.Round (x);
334 y = Math.Round (y);
335 var pointPosition = new Vector2 ((float)x, (float)y);
336
337 if (CurrentPolarity == Polarity.Positive) {
338 spriteBatch.Draw (AuraPoint, pointPosition, RedColor);
339 } else {
340 spriteBatch.Draw (AuraPoint, pointPosition, BlueColor);
341 }
342 }
343
344 AuraSubPhase += AuraSubFrequency;
345
346 /* var r = 50;
347 var wave = 5;
348 var frequency = 1.4;
349 var randomFactor = 5;
350 var randomAreaSize = 4;
351
352 var j = AuraWaveSize;
353 var rand = 0;
354 var randomPosition = 0;
355
356 AuraSubPhase = 0;
357
358 for (var i = 0; i < 360; i++) {
359 var rad = Math.radians(i);
360 if (j == AuraWaveSize) {
361 //rand = Math.random() * 2 * AuraSubAmplitude - AuraSubAmplitude;
362 rand = AuraSubAmplitude * Math.sin(AuraSubPhase + offset);
363 AuraSubPhase -= (2 * Math.PI / 8);
364 j = 0;
2af83e98 365 }
9ad526c0
BB
366 j++;
367 var radius = polarityModifications[i] + rand + AuraRadius + AuraAmplitude * Math.sin(i / AuraFrequency);
368 var x = Position.x + radius * Math.cos(rad);
369 var y = Position.y + radius * Math.sin(rad);
370 x = Math.round(x);
371 y = Math.round(y);
372
373 draw
374 //console.log(i, rad, x, y, dataStart);
375 });
376
377 ctx.putImageData(imgData, 0, 0);*/
378 }
379
380 protected Texture2D CreateCircle(int radius)
381 {
382 int outerRadius = radius * 2 + 2;
383 Texture2D texture = new Texture2D (game.GraphicsDevice, outerRadius, outerRadius);
384
385 Color[] data = new Color[outerRadius * outerRadius];
386
387 for (int i = 0; i < data.Length; i++) {
388 data [i] = Color.Transparent;
389 }
390
391 double angleStep = 1f / radius;
392
393 for (double angle = 0; angle < Math.PI * 2; angle += angleStep)
394 {
395 int x = (int)Math.Round (radius + radius * Math.Cos (angle));
396 int y = (int)Math.Round (radius + radius + Math.Sin (angle));
397
398 data [y * outerRadius + x + 1] = Color.White;
399 }
400
401 texture.SetData (data);
402 return texture;
403 }
74c15570
BB
404
405 public override void Collide(Actor other, Rectangle collision)
406 {
05e4b948 407 if (other.GetType().IsAssignableFrom(typeof(StandardShip)) &&
74c15570
BB
408 !Immortal)
409 {
410 Die();
411 }
412 }
413
414 protected override void Die()
415 {
416 game.Player.Lives = game.Player.Lives - 1;
417 game.Player.ResetMultiplier();
418 if (game.Player.Lives < 0)
419 {
420 Dying = true;
b587e9d8 421 game.GameOver();
74c15570
BB
422 }
423 else {
b587e9d8 424 Hit.Play();
74c15570
BB
425 Immortal = true;
426 CurrentImmortalTime = 0;
427 }
428 }
b587e9d8
BB
429
430 public override void CleanUp()
431 {
432 base.CleanUp();
b587e9d8
BB
433 InputController.Unbind("moveX", HandleHorizontalMovement);
434 InputController.Unbind("moveY", HandleVerticalMovement);
435 InputController.Unbind("changePolarity", HandleChangePolarity);
436 InputController.Unbind("shoot", HandleShot);
437 }
2af83e98
BB
438 }
439}