]>
Commit | Line | Data |
---|---|---|
1 | using System; | |
2 | using System.Collections.Generic; | |
3 | using System.Linq; | |
4 | using System.Text; | |
5 | using System.Threading; | |
6 | using Microsoft.Xna.Framework; | |
7 | using Microsoft.Xna.Framework.Content; | |
8 | using Microsoft.Xna.Framework.Graphics; | |
9 | using Microsoft.Xna.Framework.Audio; | |
10 | ||
11 | namespace SuperPolarity | |
12 | { | |
13 | class MainShip : Ship | |
14 | { | |
15 | ||
16 | public static Color BlueColor; | |
17 | public static Color RedColor; | |
18 | ||
19 | protected bool Shooting; | |
20 | protected int ShotCooldown; | |
21 | ||
22 | protected float CurrentImmortalTime; | |
23 | protected float MaxImmortalTime; | |
24 | protected bool Flashing; | |
25 | ||
26 | protected SoundEffect PolarityChange; | |
27 | protected SoundEffect ShootSound; | |
28 | protected SoundEffect Hit; | |
29 | ||
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 | ||
43 | public MainShip(SuperPolarity newGame) : base(newGame) {} | |
44 | ||
45 | ~MainShip() | |
46 | { | |
47 | } | |
48 | ||
49 | public override void Initialize(Texture2D texture, Vector2 position) | |
50 | { | |
51 | base.Initialize(texture, position); | |
52 | ||
53 | MainShip.BlueColor = new Color(71, 182, 226); | |
54 | MainShip.RedColor = new Color(235, 160, 185); | |
55 | ||
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 | ||
72 | PolarityChange = game.Content.Load<SoundEffect>("Sound\\polaritychange"); | |
73 | ShootSound = game.Content.Load<SoundEffect>("Sound\\bullet"); | |
74 | Hit = game.Content.Load<SoundEffect>("Sound\\hit"); | |
75 | ||
76 | SetPolarity(Polarity.Positive); | |
77 | ||
78 | ActVelocity = 2.5f; | |
79 | ||
80 | ShotCooldown = 50; | |
81 | MaxImmortalTime = 1500; | |
82 | ||
83 | BoxDimensions.X = 2; | |
84 | BoxDimensions.Y = 2; | |
85 | BoxDimensions.W = 2; | |
86 | BoxDimensions.Z = 2; | |
87 | InitBox(); | |
88 | ||
89 | BindInput(); | |
90 | } | |
91 | ||
92 | void BindInput() | |
93 | { | |
94 | InputController.Bind("moveX", HandleHorizontalMovement); | |
95 | InputController.Bind("moveY", HandleVerticalMovement); | |
96 | InputController.Bind("changePolarity", HandleChangePolarity); | |
97 | InputController.Bind("shoot", HandleShot); | |
98 | } | |
99 | ||
100 | protected void HandleShot(float value) | |
101 | { | |
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 | ||
112 | var bullet = ActorFactory.CreateBullet(Position, Angle); | |
113 | ||
114 | Children.Add(bullet); | |
115 | bullet.Parent = this; | |
116 | ||
117 | ShootSound.Play(); | |
118 | } | |
119 | ||
120 | protected void UnlockShot(object state) | |
121 | { | |
122 | InputController.Unlock("shoot"); | |
123 | Shooting = false; | |
124 | } | |
125 | ||
126 | protected void HandleChangePolarity(float value) | |
127 | { | |
128 | SwitchPolarity(); | |
129 | } | |
130 | ||
131 | public void HandleHorizontalMovement(float value) | |
132 | { | |
133 | if (value >= -0.5 && value <= 0.5) | |
134 | { | |
135 | value = 0; | |
136 | } | |
137 | ||
138 | Velocity.X = value * MaxVelocity; | |
139 | } | |
140 | ||
141 | public void HandleVerticalMovement(float value) | |
142 | { | |
143 | if (value >= -0.5 && value <= 0.5) | |
144 | { | |
145 | value = 0; | |
146 | } | |
147 | ||
148 | Velocity.Y = value * MaxVelocity; | |
149 | } | |
150 | ||
151 | public override void SwitchPolarity() | |
152 | { | |
153 | base.SwitchPolarity(); | |
154 | PolarityChange.Play(); | |
155 | game.Player.ResetMultiplier(); | |
156 | } | |
157 | ||
158 | public override void SetPolarity(Polarity newPolarity) | |
159 | { | |
160 | base.SetPolarity(newPolarity);; | |
161 | } | |
162 | ||
163 | public override void Update(GameTime gameTime) | |
164 | { | |
165 | base.Update(gameTime); | |
166 | ConstrainToEdges(); | |
167 | UpdateImmortality(gameTime); | |
168 | } | |
169 | ||
170 | public void ResetEnemyModification() { | |
171 | for ( int i = 0; i < EnemyModifications.Length; i++ ) { | |
172 | EnemyModifications[i] = 0; | |
173 | } | |
174 | } | |
175 | ||
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 | ||
201 | public override void Move(GameTime gameTime) | |
202 | { | |
203 | var VelocityLimit = MaxVelocity; | |
204 | var SavedVelocity = new Vector2(Velocity.X, Velocity.Y); | |
205 | ||
206 | if (Shooting) | |
207 | { | |
208 | VelocityLimit = ActVelocity; | |
209 | } | |
210 | ||
211 | if (SavedVelocity.X > VelocityLimit) | |
212 | { | |
213 | SavedVelocity.X = VelocityLimit; | |
214 | } | |
215 | ||
216 | if (SavedVelocity.X < -VelocityLimit) | |
217 | { | |
218 | SavedVelocity.X = -VelocityLimit; | |
219 | } | |
220 | ||
221 | if (SavedVelocity.Y > VelocityLimit) | |
222 | { | |
223 | SavedVelocity.Y = VelocityLimit; | |
224 | } | |
225 | ||
226 | if (SavedVelocity.Y < -VelocityLimit) | |
227 | { | |
228 | SavedVelocity.Y = -VelocityLimit; | |
229 | } | |
230 | ||
231 | Position.X = Position.X + SavedVelocity.X; | |
232 | Position.Y = Position.Y + SavedVelocity.Y; | |
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 | ||
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) | |
307 | { | |
308 | DrawCircle (spriteBatch); | |
309 | base.Draw(spriteBatch); | |
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; | |
365 | } | |
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 | } | |
404 | ||
405 | public override void Collide(Actor other, Rectangle collision) | |
406 | { | |
407 | if (other.GetType().IsAssignableFrom(typeof(StandardShip)) && | |
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; | |
421 | game.GameOver(); | |
422 | } | |
423 | else { | |
424 | Hit.Play(); | |
425 | Immortal = true; | |
426 | CurrentImmortalTime = 0; | |
427 | } | |
428 | } | |
429 | ||
430 | public override void CleanUp() | |
431 | { | |
432 | base.CleanUp(); | |
433 | InputController.Unbind("moveX", HandleHorizontalMovement); | |
434 | InputController.Unbind("moveY", HandleVerticalMovement); | |
435 | InputController.Unbind("changePolarity", HandleChangePolarity); | |
436 | InputController.Unbind("shoot", HandleShot); | |
437 | } | |
438 | } | |
439 | } |