]>
Commit | Line | Data |
---|---|---|
9ad526c0 | 1 | using System; |
2af83e98 BB |
2 | using System.Collections.Generic; |
3 | using System.Linq; | |
4 | using System.Text; | |
38c7d3f9 | 5 | using System.Threading; |
2af83e98 BB |
6 | using Microsoft.Xna.Framework; |
7 | using Microsoft.Xna.Framework.Content; | |
8 | using Microsoft.Xna.Framework.Graphics; | |
b587e9d8 | 9 | using Microsoft.Xna.Framework.Audio; |
2af83e98 BB |
10 | |
11 | namespace 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 | } |