source: 2013/27/JaakkoL/RampageRebellion/RampageRebellion/RampageRebellion/RRBegin.cs @ 4503

Revision 4503, 45.8 KB checked in by jaollipa, 8 years ago (diff)

Fixed.

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Diagnostics;
6using Jypeli;
7using Jypeli.Assets;
8using Jypeli.Controls;
9using Jypeli.Effects;
10using Jypeli.Widgets;
11
12/// @author     Jaakko Lipas
13/// @version    Dev - 2.7.2013
14
15/// <summary>
16/// The main class of the game that uses all other classes in the project (except RRMain).
17/// </summary>
18public class RampageRebellion : PhysicsGame
19{
20    RREnemySpawner ES;
21
22    #region Tech Data
23
24    /**
25     * Tags:
26     *
27     *  B = Border
28     *  P = Player
29     *  SE = Consolidated Tag for Small-Class Enemies (small, medium)
30     *  LE = Consolidated Tag for Large-Class Enemies (large, boss)
31     *  EP = Enemy Projectile
32     *  PP = Player Projectile
33     *  LP = Player Laser Blaster Projectile
34     *  BOMB = Player Bomb
35     *  BX = Bomb Explosion
36     *  ------------
37     * Collision Ignore Groups
38     *  1 = Walls
39     *  2 = Players
40     *  3 = Projectiles
41     *  4 = Enemies
42     *  **/
43
44    #endregion
45
46    #region Attributes
47    /// <summary>
48    /// Type of controls. Valid for a keyboard and an Xbox 360 controller.
49    /// </summary>
50    public enum ControllerType { Keyboard, Xbox };
51
52    /// <summary>
53    /// Meter that gauges score.
54    /// </summary>
55    public readonly IntMeter SCOREMETER = new IntMeter(0);
56    /// <summary>
57    /// Meter that gauges the player's current power.
58    /// </summary>
59    public readonly IntMeter POWERMETER = new IntMeter(0);
60    /// <summary>
61    /// Meter that gauges the player's current health.
62    /// </summary>
63    public readonly IntMeter HEALTHMETER = new IntMeter(0);
64    /// <summary>
65    /// The player's speed (X-axis).
66    /// </summary>
67    public readonly Vector PLAYER_SPEED_X = new Vector(750.0 * 1.5, 0.0);
68    /// <summary>
69    /// The player's speed (Y-axis).
70    /// </summary>
71    public readonly Vector PLAYER_SPEED_Y = new Vector(0.0, 750.0 * 1.5);
72    /// <summary>
73    /// Position of the score meter.
74    /// </summary>
75    public readonly Vector SMETER_POSITION = new Vector(320.0, 290.0);
76    /// <summary>
77    /// Position of the power meter.
78    /// </summary>
79    public readonly Vector PMETER_POSITION = new Vector(320.0, 210.0);
80    /// <summary>
81    /// Position of the health meter.
82    /// </summary>
83    public readonly Vector HMETER_POSITION = new Vector(252.0, 150.0);
84
85    /// <summary>
86    /// Position used for the weapon selector position
87    /// </summary>
88    ///
89
90    public readonly Vector WMETER_POSITION = new Vector(400.0, -80.0);
91
92    /// <summary>
93    /// (Base position) for arsenal upgrades
94    /// </summary>
95    ///
96
97    //REMEMBER - Base screen 1024x820
98    public readonly Vector ARSENAL_BASE_POSITION = new Vector(-300, -300);
99
100
101    /// <summary>
102    /// Position used for respawning the player.
103    /// </summary>
104
105    public readonly Vector RESPAWN_POSITION = new Vector(-200.0, -300.0);
106    /// <summary>
107    /// Gravity vector.
108    /// </summary>
109    public readonly Vector GRAVITY = new Vector(0.0, -150.0);
110    /// <summary>
111    /// GameObject array that visualizes the player's current health.
112    /// </summary>
113    public readonly GameObject[] METER_RECTANGLES = new GameObject[PLAYER_HP];
114
115    /// <summary>
116    /// Shot power for the player's weapon.
117    /// </summary>
118    public const int PLAYER_WEAPONPOWER = 120;
119    /// <summary>
120    /// Small enemy health.
121    /// </summary>
122    public const double SMALLENEMY_HP = 50;
123    /// <summary>
124    /// Small enemy score value.
125    /// </summary>
126    public const double SMALLENEMY_SVALUE = 100;
127    /// <summary>
128    /// Small enemy power value.
129    /// </summary>
130    public const double SMALLENEMY_PVALUE = 1;
131    /// <summary>
132    /// Medium enemy health.
133    /// </summary>
134    public const double MEDENEMY_HP = 170;
135    /// <summary>
136    /// Medium enemy score value.
137    /// </summary>
138    public const double MEDENEMY_SVALUE = 400;
139    /// <summary>
140    /// Medium enemy power value.
141    /// </summary>
142    public const double MEDENEMY_PVALUE = 3;
143    /// <summary>
144    /// Big enemy health.
145    /// </summary>
146    public const double BIGENEMY_HP = 300;
147    /// <summary>
148    /// Big enemy score value.
149    /// </summary>
150    public const double BIGENEMY_SVALUE = 1000;
151    /// <summary>
152    /// Big enemy power value.
153    /// </summary>
154    public const double BIGENEMY_PVALUE = 6;
155    /// <summary>
156    /// Boss health.
157    /// </summary>
158    public const double BOSS_HP = 1444;
159    /// <summary>
160    /// Boss score value.
161    /// </summary>
162    public const double BOSS_SVALUE = 10000;
163    /// <summary>
164    /// Boss power value.
165    /// </summary>
166    public const double BOSS_PVALUE = 25;
167    /// <summary>
168    /// Player health. Also used as the value for determining the length of the player's health meter.
169    /// </summary>
170    public const int PLAYER_HP = 40;
171    /// <summary>
172    /// Player score value (the value to be deducted from the current score, if the player dies)
173    /// </summary>
174    public const double PLAYER_SVALUE = 4000;
175    /// <summary>
176    /// Radius of a small enemy.
177    /// </summary>
178    public const double SMALLENEMY_SIZE = 40.0;
179    /// <summary>
180    /// Radius of a medium enemy.
181    /// </summary>
182    public const double MEDENEMY_SIZE = 70.0;
183    /// <summary>
184    /// Radius of a big enemy.
185    /// </summary>
186    public const double BIGENEMY_SIZE = 110.0;
187    /// <summary>
188    /// Radius of a boss enemy.
189    /// </summary>
190    public const double BOSS_SIZE = 222.0;
191    /// <summary>
192    /// Enemy mass.
193    /// </summary>
194    public const double ENEMY_MASS = 600.0;
195    /// <summary>
196    /// Linear damping value for enemies.
197    /// </summary>
198    public const double ENEMY_DAMPING = 0.92;
199    /// <summary>
200    /// Fire rate of the player's weapon.
201    /// </summary>
202    public const double PLAYER_FIRERATE = 12;
203    /// <summary>
204    /// Length of a meter.
205    /// </summary>
206    public const double METER_LENGTH = 200.0;
207    /// <summary>
208    /// Length of a single bar in a health meter. Dependant on attribute METER_LENGTH.
209    /// </summary>
210    public const double HMETER_LENGTH = METER_LENGTH / 28;
211    /// <summary>
212    /// Height of a meter.
213    /// </summary>
214    public const double METER_HEIGHT = 25.0;
215    /// <summary>
216    /// Value to use when executing the tilemap.
217    /// </summary>
218    public const double FIELDEXEC_VALUE = 20.0;
219    /// <summary>
220    /// Interval between enemy spawns (in seconds).
221    /// </summary>
222    public const double SPAWNLOGIC_INTERVAL = 14.0;
223    /// <summary>
224    /// Sets the amount of enemy spawns to execute.
225    /// </summary>
226    public const int SPAWN_AMOUNT = 11;
227    /// <summary>
228    /// General initialization value for int variables.
229    /// </summary>
230    public const int GENERAL_INITVALUE = 0;
231
232    private static RampageRebellion gameObject;
233    private RRShip playerShip;
234    private static Object upgradeLockObject = new Object();
235
236
237    /// <summary>
238    /// Internal variable, whenever the vibration features are enabled
239    /// </summary>
240
241    public bool vibrateEnabled = false;
242
243
244    /// <summary>
245    /// Primary weapon for the player. Fast but not too efficient
246    /// </summary>
247
248    public RRWeapon primaryWeapon;
249
250    /// <summary>
251    /// Secondary weapon. Not too fast to fire or to advance, but is effective
252    /// </summary>
253    ///
254    public RRWeapon secWeapon;
255
256    /// <summary>
257    /// Third weapon. Insensibly inaccurate shooter! >:D
258    /// </summary>
259    ///
260    public RRWeapon triWeapon;
261
262    /// <summary>
263    /// Bomb, that is.
264    /// </summary>
265    ///
266    public RRWeapon bomb;
267
268    /// <summary>
269    /// Player weapon arsenal! >:D
270    /// </summary>
271
272    public volatile RRWeaponArsenal playerWeaponArsenal;
273    public volatile List<IntMeter> pwArsenalUpgrades;
274    public volatile List<Label> pwArsenalLabels;
275    public volatile GameObject pauseMenuDummy;
276    public volatile Image pauseMenu;
277    #endregion
278
279    #region Initialization
280    /// <summary>
281    /// The title screen void that loads the title screen background, which contains control information.
282    /// </summary>
283    ///
284
285    public override void Begin()
286    {
287        gameObject = this;
288
289        SetWindowSize(1024, 820, false);
290        Image MenuBG = LoadImage("Title");
291        Level.Background.Image = MenuBG;
292        Level.BackgroundColor = Color.DarkGray;
293        Camera.ZoomToLevel();
294        Level.Background.ScaleToLevel();
295        ControllerOne.Listen(Button.Start, ButtonState.Pressed, delegate { ControlMethod(); ControllerOne.Disable(Button.Start); }, null);
296        ControllerOne.Listen(Button.Back, ButtonState.Pressed, ConfirmExit, null);
297        Keyboard.Listen(Key.Z, ButtonState.Pressed, delegate { ControlMethod(); Keyboard.Disable(Key.Z); }, null);
298        Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, null);
299
300        //Reset weapon upgrades here. They should not be lost upon accessing the pause menu - only when resetting!
301
302        generateArsenalData();
303    }
304
305    /// <summary>
306    /// Sets visibility for arsenal labels
307    /// </summary>
308    /// <param name="visible"></param>
309
310    private void hideArsenalLabels()
311    {
312        pauseMenuDummy.Image = null;
313        for (int i = 0; i < 4; i++) {
314            pwArsenalLabels[i].Destroy();
315        }
316
317        pwArsenalLabels = null;
318    }
319
320    private void generateArsenalData()
321    {
322        pwArsenalUpgrades = new List<IntMeter>(new IntMeter[] { new IntMeter(0, 0, 3), new IntMeter(0, 0, 3), new IntMeter(0, 0, 3), new IntMeter(0, 0, 3) });
323    }
324
325    private void showArsenalLabels()
326    {
327        pwArsenalLabels = new List<Label>(new Label[] { new Label(METER_LENGTH, METER_HEIGHT), new Label(METER_LENGTH, METER_HEIGHT), new Label(METER_LENGTH, METER_HEIGHT), new Label(METER_LENGTH, METER_HEIGHT) });
328
329        pauseMenuDummy = new GameObject(1600, 1200, Shape.Rectangle);
330        pauseMenuDummy.Position = new Vector(-100.0, 150.0);
331        pauseMenuDummy.Color = new Color(0, 0, 0, 0);
332        pauseMenu = LoadImage("PauseBckg-WUpgrades-NoBckg");
333        pauseMenuDummy.Image = pauseMenu;
334        Add(pauseMenuDummy);
335
336        for (int i = 0; i < 4; i++)
337        {
338            pwArsenalLabels[i].BindTo(pwArsenalUpgrades[i]);
339           
340            pwArsenalLabels[i].Position = new Vector(ARSENAL_BASE_POSITION.X+i*200, ARSENAL_BASE_POSITION.Y);
341            pwArsenalLabels[i].Color = Color.AshGray;
342            pwArsenalLabels[i].TextColor = Color.Black;
343
344            Add(pwArsenalLabels[i]);
345            pwArsenalLabels[i].IsVisible = true;
346        }
347    }
348
349    /// <summary>
350    /// Reads which type of control the player wants to use - Controller or Keyboard - and passes the information to the other control settings.
351    /// </summary>
352    public void ControlMethod()
353    {
354        ClearAll();
355        Image CntrlBG = LoadImage("ControlScreen");
356        Level.Background.Image = CntrlBG;
357        Level.BackgroundColor = Color.DarkGray;
358        Level.Background.ScaleToLevel();
359        ControllerOne.Listen(Button.Start, ButtonState.Pressed, delegate { GameStart(ControllerType.Xbox, true); }, null);
360        ControllerOne.Listen(Button.Y, ButtonState.Pressed, delegate { GameStart(ControllerType.Xbox, false); }, null);
361        Keyboard.Listen(Key.Z, ButtonState.Pressed, delegate { GameStart(ControllerType.Keyboard, true); }, null);
362        Keyboard.Listen(Key.X, ButtonState.Pressed, delegate { GameStart(ControllerType.Keyboard, false); }, null);
363    }
364
365    /// <summary>
366    /// Get game object
367    /// </summary>
368    /// <returns></returns>
369
370    public static RampageRebellion getGame()
371    {
372        return gameObject;
373    }
374
375    /// <summary>
376    /// Loads a color tilemap to generate the field elements using subprograms. Zooms the camera accordingly. Adds menu controls.
377    /// </summary>
378    /// <param name="controllerType">The type of controls being used.</param>
379    public void GameStart(ControllerType controllerType, bool levelsOn)
380    {
381        Camera.ZoomToAllObjects();
382
383        vibrateEnabled = (controllerType == ControllerType.Xbox);
384
385        SCOREMETER.Reset();
386        POWERMETER.Reset();
387        HEALTHMETER.Reset();
388
389        ColorTileMap Field = ColorTileMap.FromLevelAsset("GameTilemap");
390
391        Field.SetTileMethod(new Color(0, 0, 0), CreateBorder);
392        Field.SetTileMethod(new Color(255, 0, 0), CreatePlayer, controllerType);
393        CreateScoreMeter();
394        CreatePowerMeter();
395
396        CreateHealthMeter(GENERAL_INITVALUE);
397        Field.Execute(FIELDEXEC_VALUE, FIELDEXEC_VALUE);
398
399        Image LevelUI = LoadImage("UI");
400        Level.Background.Image = LevelUI;
401
402        // Starts enemy spawning; ES.levels() for the pre-designed levels and ES.arcade() for arcade.
403        if (levelsOn) ES = new RREnemySpawner("levels");
404        else ES = new RREnemySpawner("arcade");
405
406        Gravity = GRAVITY;
407    }
408    #endregion
409
410    #region In-Games
411    /// <summary>
412    /// A pause menu that pops up if the pause button is pressed.
413    /// </summary>
414    /// <param name="controllerType">The type of controls being used.</param>
415    /// <param name="player">The player.</param>
416    /// <param name="primaryWeapon">The player's weapon.</param>
417    public void PauseMenu(PhysicsObject player, ControllerType controllerType, RRWeaponArsenal primaryWeapon)
418    {
419        ClearControls();
420
421        showArsenalLabels();
422
423        MediaPlayer.Pause();
424        Pause();
425        ES.isPaused = true;
426        switch (controllerType)
427        {
428            case ControllerType.Keyboard:
429                Keyboard.Listen(Key.Escape, ButtonState.Pressed, delegate { Pause(); ResetGame(); }, null);
430                Keyboard.Listen(Key.P, ButtonState.Pressed, delegate { Unpause(player, controllerType, primaryWeapon); }, null);
431                //JAKE: Weapon upgrade keys here
432                Keyboard.Listen(Key.Q, ButtonState.Pressed, triggerUpdateKeys, null, 0);
433                Keyboard.Listen(Key.W, ButtonState.Pressed, triggerUpdateKeys, null, 1);
434                Keyboard.Listen(Key.E, ButtonState.Pressed, triggerUpdateKeys, null, 2);
435                Keyboard.Listen(Key.R, ButtonState.Pressed, triggerUpdateKeys, null, 3);
436                break;
437
438            case ControllerType.Xbox:
439                ControllerOne.Listen(Button.Back, ButtonState.Pressed, delegate { Pause(); ResetGame(); }, null);
440                ControllerOne.Listen(Button.Start, ButtonState.Pressed, delegate { Unpause(player, controllerType, primaryWeapon); }, null);
441                break;
442        }
443    }
444
445    /// <summary>
446    /// Unpauses the game and resumes music.
447    /// </summary>
448    /// <param name="controllerType">The type of controls being used.</param>
449    /// <param name="player">The player.</param>
450    /// <param name="primaryWeapon">The player's weapon.</param>
451    public void Unpause(PhysicsObject player, ControllerType controllerType, RRWeaponArsenal primaryWeapon)
452    {
453        ClearControls();
454        MediaPlayer.Resume();
455        Pause();
456
457        hideArsenalLabels();
458
459        CreateControls(player, controllerType, primaryWeapon);
460
461        // Informs RREnemySpawner that the game is paused
462        ES.isPaused = false;
463    }
464
465    /// <summary>
466    /// Clears all game data and resets the game.
467    /// </summary>
468    public void ResetGame()
469    {
470        ClearAll();
471        Begin();
472    }
473
474    /// <summary>
475    /// Void that creates an invisible (fully transparent) border object. The playable field is visually bounded by the background image,
476    /// so there is no need to apply a visible texture or color to the borders.
477    /// </summary>
478    /// <param name="position">Vector location of the object, as specified in GameStart</param>
479    /// <param name="width">Width of the object, as specified in GameStart</param>
480    /// <param name="height">Height of the object, as specified in GameStart</param>
481    public void CreateBorder(Vector position, double width, double height)
482    {
483        PhysicsObject border = PhysicsObject.CreateStaticObject(width, height);
484        border.Position = position;
485        border.Color = new Color(0, 0, 0, 0);
486        border.CollisionIgnoreGroup = 1;
487        border.Tag = "B";
488        Add(border);
489    }
490
491    /// <summary>
492    /// Void that creates the player's collision detector box and sprite, adding controls for them.
493    /// </summary>
494    /// <param name="position">Vector location of the object, as specified in GameStart</param>
495    /// <param name="width">Width of the object, as specified in GameStart</param>
496    /// <param name="height">Height of the object, as specified in GameStart</param>
497    /// <param name="controllerType">The type of controls used</param>
498    ///
499
500    public void vibrateController()
501    {
502        if (((ControllerOne.GetType()) == typeof(GamePad)) && vibrateEnabled)
503        {
504            GamePad gp = ControllerOne as GamePad;
505            gp.Vibrate(0.5, 0.5, 0.0, 0.0, 0.1);
506        }
507    }
508
509    public void collisionHandler(RRShip collider, PhysicsObject collidee)
510    {
511        //System.Diagnostics.Debugger.Log(0, "Info", collider.Tag + "on" + collidee.Tag + "\n");
512        if ((String)collidee.Tag != "Z") vibrateController();
513    }
514
515    public void meterHandlerFunc(RRShip player)
516    {
517
518        for (int i = 0; i < METER_RECTANGLES.Length; i++)
519        {
520            METER_RECTANGLES[i].Color = ((i < player.Health) ? Color.Green : Color.Red);
521        }
522
523        if (player.Health == 0)
524        {
525            onPlayerDeath(player);
526        }
527    }
528
529    public void onPlayerDeath(RRShip player)
530    {
531        if (((ControllerOne.GetType()) == typeof(GamePad)) && vibrateEnabled)
532        {
533            GamePad gp = ControllerOne as GamePad;
534            gp.Vibrate(1, 1, 1, 1, 1);
535        }
536
537        Explosion expl = new Explosion(200);
538        expl.Position = player.Position;
539        Add(expl);
540
541        player.Destroy();
542
543        SCOREMETER.Value -= (int)player.ScoreValue;
544        POWERMETER.Reset();
545        ClearControls();
546
547        Keyboard.Listen(Key.Z, ButtonState.Pressed, delegate
548        {
549            for (int i = 0; i < METER_RECTANGLES.Length; i++)
550            {
551                METER_RECTANGLES[i].Color = Color.Green;
552            }
553            CreatePlayer(RESPAWN_POSITION, 20, 20, ControllerType.Keyboard);
554        }, null);
555        ControllerOne.Listen(Button.A, ButtonState.Pressed, delegate
556        {
557            for (int i = 0; i < METER_RECTANGLES.Length; i++)
558            {
559                METER_RECTANGLES[i].Color = Color.Green;
560            }
561            CreatePlayer(RESPAWN_POSITION, 20, 20, ControllerType.Xbox);
562        }, null);
563    }
564
565    public void resetAllWeapons()
566    {
567        //Cleanup required
568        this.playerShip.Remove(playerWeaponArsenal);
569        playerWeaponArsenal.Destroy();
570
571        GeneratePlayerWeapons(this.playerShip);
572    }
573
574
575    /// <summary>
576    /// Trigger for weapon updates. Triggered in pause menu
577    ///
578    /// DOCUMENTATION:
579    ///
580    /// 1st upgrade level: 2x size bullet
581    /// 2nd upgrade: damage OR fire rate
582    /// 3rd upgrade damage OR fire rate
583    /// 4rd upgrade (bomb only) - free bomb!
584    ///
585    /// FOR JAKE: When adding the 4th weapon - ensure that the bomb remains to be the last of the weapons in WeaponArsenal
586    ///
587    /// </summary>
588    /// <param name="i">Weapon triggering parameters</param>
589
590    //((pwArsenalUpgrades[x] >= 1) ? (2) : (1))
591
592    public void triggerUpdateKeys(int i) {
593        lock (upgradeLockObject)
594        {
595            int upgradeTo = pwArsenalUpgrades[i].Value + 1;
596            int upgradePrice = (int)(Math.Pow(2,upgradeTo)+2); //Prices: 4, 6, 10, 18
597
598            if (upgradeTo > 4) return; //No. No cake for you.
599
600            if ((POWERMETER >= upgradePrice) && (i == (playerWeaponArsenal.Weapons.Count-1)) && (upgradeTo == 4)) {
601                POWERMETER.Value -= upgradePrice; //Special case
602                playerWeaponArsenal.Weapons[i].Ammo.AddValue(1);
603                resetAllWeapons();
604            } else if ((POWERMETER.Value >= upgradePrice) && (upgradeTo < 4))
605            {
606                POWERMETER.Value -= upgradePrice;
607                pwArsenalUpgrades[i].Value++;
608                resetAllWeapons();
609            }
610            else return;
611        }
612    }
613
614    /// <summary>
615    /// Triggers the bomb - aka THE LAST of all weapons, as expected so far!
616    /// </summary>
617
618    public void triggerBomb()
619    {
620        playerWeaponArsenal.singleShoot(playerWeaponArsenal.Weapons.Count - 1);
621    }
622
623
624    public void CreatePlayer(Vector position, double width, double height, ControllerType controllerType)
625    {
626        // Replaced by RRShip
627        /*RRObject player = new RRObject(width, height);
628        player.Tag = "P";
629        player.Shape = Shape.Diamond;
630        player.Health = PLAYER_HP;
631        player.ScoreValue = PLAYER_SVALUE;
632        player.Position = position;
633        player.CanRotate = false;
634        player.Color = Color.Red;
635        player.CollisionIgnoreGroup = 2;
636        Add(player);
637        player.Add(new GameObject(LoadImage("PlayerSprite")));
638        player.IgnoresGravity = true;
639        AddCollisionHandler<RRObject, PhysicsObject>(player, PlayerCollision);*/
640
641        playerShip = new RRShip(this, width, height, PLAYER_HP, PLAYER_SVALUE, position, collisionHandler, meterHandlerFunc);
642        Add(playerShip);
643        HEALTHMETER.Value = PLAYER_HP;
644
645        //Let's generate this first..
646
647        GeneratePlayerWeapons(playerShip);
648
649        CreateControls(playerShip, controllerType, playerWeaponArsenal);
650    }
651
652    /// <summary>
653    /// Generates weapons for the player's use
654    /// </summary>
655    /// <param name="ship"></param>
656
657    private void GeneratePlayerWeapons(RRShip ship)
658    {
659        SoundEffect WeaponFire = LoadSoundEffect("Shot");
660        SoundEffect WeaponFireLarge = LoadSoundEffect("LargeShot");
661
662        // Primary Weapon (Plasma Cannon): all-purpose
663
664        //Upgrade levels. Same for each weapon for now
665        double pwSizeMultiplier = ((pwArsenalUpgrades[0] >= 1) ? (2) : (1));
666        double pwFireBonusMultiplier = 1 + (2 * ((pwArsenalUpgrades[0] >= 3) ? (1) : (0)));
667        double pwDamageBonusMultiplier = 1 + (1.5 * ((pwArsenalUpgrades[0] >= 2) ? (1) : (0)));
668
669        primaryWeapon = new RRWeapon(5, 10, true, PLAYER_WEAPONPOWER, PLAYER_FIRERATE * pwFireBonusMultiplier, new RRProjectileGenerator(14 * pwSizeMultiplier, 14 * pwSizeMultiplier, 0.1, new Color(55, 255, 128, 128), 10 * pwDamageBonusMultiplier));
670        primaryWeapon.Position += new Vector(0, 30);
671        primaryWeapon.projectileGenerator.projectileShape = Shape.Diamond;
672        primaryWeapon.projectileGenerator.defaultCollisionIgnoreGroup = 3;
673        primaryWeapon.projectileGenerator.defaultTag = "PP";
674        primaryWeapon.projectileGenerator.canRotate = false;
675        primaryWeapon.projectileGenerator.shotSound = WeaponFire;
676        primaryWeapon.Color = new Color(0, 0, 0, 0);
677        primaryWeapon.Angle += Angle.FromDegrees(90);
678
679        // Secondary Weapon (Laser Blaster): laser, pierces smaller enemies
680
681        double swSizeMultiplier = ((pwArsenalUpgrades[1] >= 1) ? (2) : (1));
682        double swFireBonusMultiplier = 1 + (2 * ((pwArsenalUpgrades[1] >= 2) ? (1) : (0)));
683        double swDamageBonusMultiplier = 1 + (2.2 * ((pwArsenalUpgrades[1] >= 3) ? (1) : (0)));
684
685        secWeapon = new RRWeapon(5, 10, true, PLAYER_WEAPONPOWER / 2, PLAYER_FIRERATE * 10 * swFireBonusMultiplier, new RRProjectileGenerator(80 * swSizeMultiplier, 3 * swSizeMultiplier, 0.01, new Color(233, 111, 111, 128), 0.85 * swDamageBonusMultiplier));
686        secWeapon.Position += new Vector(0, 60);
687        secWeapon.projectileGenerator.defaultCollisionIgnoreGroup = 3;
688        secWeapon.projectileGenerator.ignoresCollisionResponse = true;
689        secWeapon.projectileGenerator.defaultTag = "LP";
690        secWeapon.projectileGenerator.canRotate = false;
691        secWeapon.projectileGenerator.shotSound = WeaponFire;
692        secWeapon.Color = new Color(0, 0, 0, 0);
693        secWeapon.Angle += Angle.FromDegrees(90);
694
695        // Third Weapon (Minigun): inaccurate but powerful
696
697        double triSizeMultiplier = ((pwArsenalUpgrades[2] >= 1) ? (2) : (1));
698        double triFireBonusMultiplier = 1 + (5.2 * ((pwArsenalUpgrades[2] >= 3) ? (1) : (0)));
699        double triDamageBonusMultiplier = 1 + (4.2 * ((pwArsenalUpgrades[2] >= 2) ? (1) : (0)));
700
701        triWeapon = new RRWeapon(5, 10, true, PLAYER_WEAPONPOWER, PLAYER_FIRERATE * 5 * triFireBonusMultiplier, new RRProjectileGenerator(9 * triSizeMultiplier, 9 * triSizeMultiplier, 0.1, new Color(222, 222, 11, 128), 2.25 * triDamageBonusMultiplier));
702        triWeapon.Position += new Vector(0, 35);
703        triWeapon.projectileGenerator.defaultCollisionIgnoreGroup = 3;
704        triWeapon.projectileGenerator.defaultTag = "PP";
705        triWeapon.projectileGenerator.canRotate = false;
706        triWeapon.projectileGenerator.shotSound = WeaponFire;
707        triWeapon.Color = new Color(0, 0, 0, 0);
708        triWeapon.Angle += Angle.FromDegrees(90);
709        triWeapon.setBaseAngle(triWeapon.Angle);
710        triWeapon.randomizedAngleSlate = 14 + pwArsenalUpgrades[2].Value*10.9;
711
712        // Bomb: special weapon, deals extreme damage and clears all enemy bullets from the screen for its duration. Access the explosion's parameters from BombExplosion, under the region Colliders.
713
714        double bombSizeMultiplier = ((pwArsenalUpgrades[3] >= 1) ? (2) : (1));
715        double bombFireBonusMultiplier = 1 + (1 * ((pwArsenalUpgrades[3] >= 3) ? (1) : (0)));
716        double bombDamageBonusMultiplier = 1 + (3 * ((pwArsenalUpgrades[3] >= 2) ? (1) : (0)));
717
718        bomb = new RRWeapon(30, 30, true, PLAYER_WEAPONPOWER * 2, PLAYER_FIRERATE / 10 * bombFireBonusMultiplier, new RRProjectileGenerator(30 * bombSizeMultiplier, 30 * bombSizeMultiplier, 0.2, new Color(111, 111, 111, 128), 50 * bombDamageBonusMultiplier));
719        bomb.projectileGenerator.projectileShape = Shape.Circle;
720        bomb.projectileGenerator.defaultCollisionIgnoreGroup = 3;
721        bomb.projectileGenerator.defaultTag = "BOMB";
722        bomb.projectileGenerator.canRotate = false;
723        bomb.projectileGenerator.shotSound = WeaponFireLarge;
724        bomb.Color = new Color(0, 0, 0, 0);
725        bomb.Angle += Angle.FromDegrees(90);
726        bomb.countInWeaponArsenal = false;
727
728        this.playerWeaponArsenal = new RRWeaponArsenal(primaryWeapon);
729        //rP = primaryWeapon;
730        this.playerWeaponArsenal.ProjectileCollision = playerCollisionHandler;
731        this.playerWeaponArsenal.addNewWeapon(secWeapon);
732        this.playerWeaponArsenal.addNewWeapon(triWeapon);
733        this.playerWeaponArsenal.addNewWeapon(bomb);
734        ship.Add(playerWeaponArsenal);
735       
736
737        CreateWeaponMeter();
738    }
739
740    public void shiftWeapons()
741    {
742        //Attempt to shift a weapon
743        playerWeaponArsenal.setNextWeapon();
744    }
745
746    /// <summary>
747    /// Creates controls for the player depending on the chosen control method.
748    /// </summary>
749    /// <param name="player">The player to be moved</param>
750    /// <param name="controllerType">The current control type</param>
751    /// <param name="primaryWeapon">The player's weapon</param>
752    private void CreateControls(PhysicsObject player, ControllerType controllerType, RRWeaponArsenal primaryWeapon)
753    {
754        ClearControls();
755        vibrateEnabled = (controllerType == ControllerType.Xbox);
756        switch (controllerType)
757        {
758            case ControllerType.Keyboard:
759                Keyboard.Listen(Key.Up, ButtonState.Down, MovePlayer, null, PLAYER_SPEED_Y, player);
760                Keyboard.Listen(Key.Up, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
761                Keyboard.Listen(Key.Down, ButtonState.Down, MovePlayer, null, -PLAYER_SPEED_Y, player);
762                Keyboard.Listen(Key.Down, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
763                Keyboard.Listen(Key.Left, ButtonState.Down, MovePlayer, null, -PLAYER_SPEED_X, player);
764                Keyboard.Listen(Key.Left, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
765                Keyboard.Listen(Key.Right, ButtonState.Down, MovePlayer, null, PLAYER_SPEED_X, player);
766                Keyboard.Listen(Key.Right, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
767                Keyboard.Listen(Key.P, ButtonState.Pressed, delegate { PauseMenu(player, controllerType, primaryWeapon); }, null);
768                Keyboard.Listen(Key.Z, ButtonState.Down, FireWeapon, null, primaryWeapon);
769                Keyboard.Listen(Key.X, ButtonState.Pressed, triggerBomb, null);
770                Keyboard.Listen(Key.LeftShift, ButtonState.Pressed, shiftWeapons, null);
771
772
773
774                break;
775            case ControllerType.Xbox:
776                ControllerOne.Listen(Button.DPadUp, ButtonState.Down, MovePlayer, null, PLAYER_SPEED_Y, player);
777                ControllerOne.Listen(Button.DPadUp, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
778                ControllerOne.Listen(Button.DPadDown, ButtonState.Down, MovePlayer, null, -PLAYER_SPEED_Y, player);
779                ControllerOne.Listen(Button.DPadDown, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
780                ControllerOne.Listen(Button.DPadLeft, ButtonState.Down, MovePlayer, null, -PLAYER_SPEED_X, player);
781                ControllerOne.Listen(Button.DPadLeft, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
782                ControllerOne.Listen(Button.DPadRight, ButtonState.Down, MovePlayer, null, PLAYER_SPEED_X, player);
783                ControllerOne.Listen(Button.DPadRight, ButtonState.Released, MovePlayer, null, Vector.Zero, player);
784                ControllerOne.ListenAnalog(AnalogControl.LeftStick, 0.1, movePlayerAnalog, null, player);
785                ControllerOne.Listen(Button.Start, ButtonState.Pressed, delegate { PauseMenu(player, controllerType, primaryWeapon); }, null);
786                ControllerOne.Listen(Button.RightTrigger, ButtonState.Down, FireWeapon, null, primaryWeapon);
787                ControllerOne.Listen(Button.Y, ButtonState.Pressed, shiftWeapons, null);
788                break;
789            default:
790                break;
791        }
792    }
793
794    public void movePlayerAnalog(AnalogState al, PhysicsObject player)
795    {
796        double xPos = al.StateVector.X;
797        double yPos = al.StateVector.Y;
798        Vector pPushVector = new Vector((xPos) * PLAYER_SPEED_X.X, (yPos) * PLAYER_SPEED_Y.Y);
799        player.Push(pPushVector);
800
801        double maxVibration = 0.15;
802        double maxBias = 0.5;
803
804        double prcBias = (0.5 * Math.Abs((xPos + yPos / 2))) +
805                         (0.5 * Math.Max(0, Math.Min(1, (1 - Math.Abs((player.Velocity.Magnitude / 100))))));
806
807        //Bias the control
808        double rightControllerVibr = ((maxVibration / 2) - ((maxVibration / 2 * maxBias) * xPos)) * prcBias;
809        double leftControllerVibr = ((maxVibration / 2) + ((maxVibration / 2 * maxBias) * xPos)) * prcBias;
810
811        if (((ControllerOne.GetType()) == typeof(GamePad)) && vibrateEnabled)
812        {
813            GamePad gp = ControllerOne as GamePad;
814            gp.Vibrate(leftControllerVibr, rightControllerVibr, 0, 0, 0.1);
815        }
816
817        //player.Velocity = pPushVector;
818    }
819
820    /// <summary>
821    /// Fires the primary weapon of the player.
822    /// </summary>
823    /// <param name="weapon">The weapon to be fired</param>
824    public void FireWeapon(RRWeaponArsenal weapon)
825    {
826        //TODO - Clean up FireWeapon, and the superflous "weapon" clause.
827        PhysicsObject projectile = playerWeaponArsenal.Shoot();
828    }
829
830    /// <summary>
831    /// Applies the force vector specified in the controls to the player object.
832    /// </summary>
833    /// <param name="force">The force vector to be applied, specified in a previous Listen method</param>
834    /// <param name="player">The player that the force vector is to be applied to, specified in a previous Listen method</param>
835    public void MovePlayer(Vector force, PhysicsObject player)
836    {
837        player.Push(force);
838        //player.Velocity = force;
839    }
840
841
842    public void CreateWeaponMeter()
843    {
844        Label weaponMeter = new Label(METER_LENGTH, METER_HEIGHT);
845        weaponMeter.Position = WMETER_POSITION;
846        weaponMeter.Color = Color.Azure;
847        weaponMeter.BindTo(playerWeaponArsenal.currentWeaponIndexMeter);
848        Add(weaponMeter);
849    }
850
851    /// <summary>
852    /// Creates a score meter on the screen. Value represented by the attribute SCOREMETER.
853    /// </summary>
854    public void CreateScoreMeter()
855    {
856        Label scoreMeter = new Label(METER_LENGTH, METER_HEIGHT);
857        scoreMeter.Position = SMETER_POSITION;
858        scoreMeter.TextColor = Color.Green;
859        scoreMeter.BindTo(SCOREMETER);
860        Add(scoreMeter);
861    }
862
863    /// <summary>
864    /// Creates a power meter on the screen. Value represented by the attribute POWERMETER.
865    /// </summary>
866    public void CreatePowerMeter()
867    {
868        Label powerMeter = new Label(METER_LENGTH, METER_HEIGHT);
869        powerMeter.Position = PMETER_POSITION;
870        powerMeter.TextColor = Color.BloodRed;
871        powerMeter.BindTo(POWERMETER);
872        Add(powerMeter);
873    }
874
875    /// <summary>
876    /// Creates a health meter on the screen recursively. Length of the health meter is dependant on player maximum health.
877    /// </summary>
878    /// <param name="i"></param>
879    public void CreateHealthMeter(int i)
880    {
881        if (i >= PLAYER_HP) return;
882        METER_RECTANGLES[i] = new GameObject(HMETER_LENGTH, METER_HEIGHT);
883        METER_RECTANGLES[i].Position = new Vector(HMETER_POSITION.X + (HMETER_LENGTH * i), HMETER_POSITION.Y);
884        METER_RECTANGLES[i].Color = Color.Green;
885        Add(METER_RECTANGLES[i]);
886        CreateHealthMeter(i + 1);
887    }
888
889    public void UpgradeMenu()
890    {
891    }
892
893    #endregion
894
895    #region Colliders
896    /// <summary>
897    /// Handles collisions between player projectiles and other objects.
898    /// </summary>
899    /// <param name="projectile">A projectile fired by the player (collider)</param>
900    /// <param name="target">Target of collision</param>
901    public void playerCollisionHandler(PhysicsObject projectile, PhysicsObject target)
902    {
903        if (target.Tag.ToString() == "B" & projectile.Tag.ToString() != "BX") projectile.Destroy(); // If the bullet hits the top wall, destroy it
904        else if (target.Tag.ToString() == "EP" || target.Tag.ToString() == "PP")
905        {
906            if (projectile.Tag.ToString() != "BOMB" || projectile.Tag.ToString() != "BE") projectile.Destroy();
907            target.Destroy();
908        }
909
910        else if (target.Tag.ToString().EndsWith("E"))
911        {
912            RREnemy enemy = target as RREnemy;
913            RRProjectile proj = projectile as RRProjectile;
914            if (enemy.Health >= 0) enemy.Health -= proj.Damage;
915            if (enemy.Health <= 0)
916            {
917                //System.Diagnostics.Debugger.Log(0, "Info", Convert.ToString(enemy.ScoreValue) + "\n");
918                SCOREMETER.Value += (int)enemy.ScoreValue;
919                POWERMETER.Value += (int)enemy.PowerValue;
920                enemy.Destroy();
921            }
922            if ((projectile.Tag.ToString() == "LP" & target.Tag.ToString() != "LE") || projectile.Tag.ToString() == "BX" || projectile.Tag.ToString() == "BS") return;
923            else if (projectile.Tag.ToString() == "BOMB" & (target.Tag.ToString().EndsWith("E") || target.Tag.ToString() == "B")) BombExplosion(projectile);
924            projectile.Destroy();
925        }
926    }
927
928    public void BombExplosion(PhysicsObject bomb)
929    {
930        SoundEffect BombExplosion = LoadSoundEffect("Bomb");
931        BombExplosion.Play();
932
933        RRProjectile bombExplosion = new RRProjectile(5.0, 999999999999, "explosion");
934        bombExplosion.Position = bomb.Position;
935        bombExplosion.Damage = 150;
936        bombExplosion.Tag = "BX";
937        bombExplosion.IgnoresCollisionResponse = true;
938        bombExplosion.IgnoresGravity = true;
939        AddCollisionHandler<RRProjectile, RREnemy>(bombExplosion, playerCollisionHandler);
940        Add(bombExplosion);
941
942        RRProjectile bombShockwave = new RRProjectile(5.0, 999999999999, new Color(212, 0, 52, 30));
943        bombShockwave.Position = bomb.Position;
944        bombShockwave.Damage = 0.1;
945        bombShockwave.Tag = "BS";
946        bombShockwave.IgnoresCollisionResponse = true;
947        bombShockwave.IgnoresGravity = true;
948        AddCollisionHandler<RRProjectile, RREnemy>(bombShockwave, playerCollisionHandler);
949        Add(bombShockwave);
950
951        Timer growExplosion = new Timer();
952        growExplosion.Interval = 0.02;
953        growExplosion.Start();
954        growExplosion.Timeout += delegate 
955        {
956            if (bombExplosion.Width >= 2500 & bombExplosion.Height >= 2500) { growExplosion.Reset(); bombExplosion.Destroy(); bombShockwave.Destroy(); }
957            else { bombExplosion.Width = bombExplosion.Width * 1.05; bombExplosion.Height = bombExplosion.Height * 1.05; bombShockwave.Width = bombShockwave.Width * 2.5; bombShockwave.Height = bombShockwave.Height * 2.5; }
958        };
959    }
960
961    #endregion
962
963    #region Enemy Logic
964
965
966    /// <summary>
967    /// After a successfully ran game, opens score screen and starts the program over after closing it.
968    /// </summary>
969    public void GameEnd()
970    {
971        Pause();
972        ScoreList scoreList = new ScoreList(10, false, 2500);
973        scoreList = DataStorage.TryLoad<ScoreList>(scoreList, "scorelist.xml");
974        HighScoreWindow scoreWindow = new HighScoreWindow("High Scores", "You have made the high scores! Please enter your name: ", scoreList, SCOREMETER.Value);
975        scoreWindow.Closed += delegate { DataStorage.Save<ScoreList>(scoreList, "scorelist.xml"); Pause(); ClearAll(); Begin(); };
976        Add(scoreWindow);
977    }
978    #endregion
979
980    #region Legacy
981    // Below: legacy code to document previous logic errors
982
983    //Old enemy generator code. Replaced by RREnemySpawner!
984
985    /** /// <summary>
986    /// Creates an enemy on the field with the given parameters. Returns the created enemy.
987    /// </summary>
988    /// <param name="position">Position to create enemy in</param>
989    /// <param name="radius">Radius of the enemy</param>
990    /// <param name="hp">Health of the enemy</param>
991    /// <param name="powerValue">Power given by the enemy on death</param>
992    /// <param name="scoreValue">Score given by the enemy on death</param>
993    /// <returns>The created enemy.</returns>
994    public RRObject CreateEnemy(Vector position, double radius, ushort hp, ushort powerValue, ushort scoreValue)
995    {
996        RRObject enemy = new RRObject(radius, radius);
997        enemy.Tag = "E";
998        enemy.Position = position;
999        enemy.Color = Color.HotPink;
1000        enemy.CollisionIgnoreGroup = 3;
1001        enemy.Mass = ENEMY_MASS;
1002        enemy.LinearDamping = ENEMY_DAMPING;
1003        enemy.CanRotate = false;
1004        enemy.Health = hp;
1005        enemy.ScoreValue = scoreValue;
1006        enemy.PowerValue = powerValue;
1007        Add(enemy);
1008        return enemy;
1009    } **/
1010
1011    /// <summary>
1012    /// Main process for enemy spawns. If this isn't called in GameStart, no enemies will spawn.
1013    /// REPLACED BY RREnemySpawner
1014    /// </summary>
1015    /*public void MainEnemyProcess(int spawnLogic)
1016    {
1017        for (int i = 0; i < SPAWN_COUNT.Length; i++)
1018        {
1019            SPAWN_COUNT[i] = i;
1020        }
1021        Timer spawns = new Timer();
1022        spawns.Interval = SPAWNLOGIC_INTERVAL;
1023        spawns.Start();
1024        spawns.Timeout += delegate
1025        {
1026            if (spawnLogic == SPAWN_COUNT[0] || spawnLogic == SPAWN_COUNT[2] || spawnLogic == SPAWN_COUNT[4] || spawnLogic == SPAWN_COUNT[5])
1027            {
1028                for (int i = 0; i < ENEMY_SPAWNS1.Length; i++)
1029                {
1030                    CreateEnemy(ENEMY_SPAWNS1[i], SMALLENEMY_SIZE, SMALLENEMY_HP, SMALLENEMY_PVALUE, SMALLENEMY_SVALUE);
1031                }
1032            }
1033            else if (spawnLogic == SPAWN_COUNT[1] || spawnLogic == SPAWN_COUNT[3] || spawnLogic == SPAWN_COUNT[6] || spawnLogic == SPAWN_COUNT[10])
1034            {
1035                for (int i = 0; i < ENEMY_SPAWNS2.Length; i++)
1036                {
1037                    CreateEnemy(ENEMY_SPAWNS2[i], MEDENEMY_SIZE, MEDENEMY_HP, MEDENEMY_PVALUE, MEDENEMY_SVALUE);
1038                }
1039            }
1040            else if (spawnLogic >= SPAWN_COUNT[7] & spawnLogic < SPAWN_COUNT[10])
1041            {
1042                for (int i = 0; i < ENEMY_SPAWNS3.Length; i++)
1043                {
1044                    CreateEnemy(ENEMY_SPAWNS3[i], BIGENEMY_SIZE, BIGENEMY_HP, BIGENEMY_PVALUE, BIGENEMY_SVALUE);
1045                }
1046            }
1047            else if (spawnLogic == 11)
1048            {
1049                RRObject boss = CreateEnemy(BOSS_SPAWN, BOSS_SIZE, BOSS_HP, BOSS_PVALUE, BOSS_SVALUE);
1050                boss.Destroyed += delegate { GameEnd(); };
1051            }
1052            spawnLogic++;
1053        };
1054    }*/
1055
1056    /// <summary>
1057    /// Handles collisions between the player and objects that can damage the player.
1058    /// </summary>
1059    /// <param name="player">The player (collider)</param>
1060    /// <param name="target">Target of collision</param>
1061    /* public void PlayerCollision(RRObject player, PhysicsObject target)
1062     {
1063         if (player.Velocity.X + player.Velocity.Y > 200.0)
1064         {
1065             if (target.Tag.ToString() == "B")
1066             {
1067                 if (player.Health == 1) METER_RECTANGLES[0].Color = Color.Red;
1068                 else METER_RECTANGLES[player.Health - 1].Color = Color.Red;
1069                 player.Health -= 1;
1070             }
1071             else if (target.Tag.ToString() == "E")
1072             {
1073                 target.Destroy();
1074                 if (player.Health == 1)
1075                 {
1076                     METER_RECTANGLES[0].Color = Color.Red;
1077                     player.Health -= 1;
1078                 }
1079                 else METER_RECTANGLES[player.Health - 1].Color = Color.Red;
1080                 if (player.Health > 1)
1081                 {
1082                     METER_RECTANGLES[player.Health - 2].Color = Color.Red;
1083                     player.Health -= 2;
1084                 }
1085             }
1086             if (player.Health == 0)
1087             {
1088                 player.Destroy();
1089                 SCOREMETER.Value -= player.ScoreValue;
1090                 POWERMETER.Reset();
1091                 ClearControls();
1092                 Keyboard.Listen(Key.Z, ButtonState.Pressed, delegate
1093                 {
1094                     for (int i = 0; i < METER_RECTANGLES.Length; i++)
1095                     {
1096                         METER_RECTANGLES[i].Color = Color.Green;
1097                     }
1098                     CreatePlayer(RESPAWN_POSITION, 20, 20, ControllerType.Keyboard);
1099                 }, null);
1100                 ControllerOne.Listen(Button.A, ButtonState.Pressed, delegate
1101                 {
1102                     for (int i = 0; i < METER_RECTANGLES.Length; i++)
1103                     {
1104                         METER_RECTANGLES[i].Color = Color.Green;
1105                     }
1106                     CreatePlayer(RESPAWN_POSITION, 20, 20, ControllerType.Xbox);
1107                 }, null);
1108             }
1109         }
1110     } */
1111
1112    /*
1113    /// <summary>
1114    /// Void that adds an invisible PhysicsObject entity to an
1115    /// existing PhysicsObject, to serve as an origin point for Bullet entities.
1116    /// </summary>
1117    /// <param name="shooter">The entity that the origin object is to be attached to</param>
1118    /// <param name="controllerType">The type of controls used</param>
1119    public void AddWeapons(PhysicsObject shooter)
1120    {
1121        PhysicsObject origin = new PhysicsObject(shooter.Width, shooter.Height, Shape.Rectangle);
1122        origin.IgnoresCollisionResponse = true;
1123        shooter.Add(origin);
1124    }
1125
1126    /// <summary>
1127    /// Uses a timer delegate to set the rate-of-fire for the player's weapon. Allows "rapid fire" controls.
1128    /// </summary>
1129    /// <param name="origin">The object to originate shots from</param>
1130    /// <param name="weapon">The timer to set. The timer is created in a previous Listen method</param>
1131    /// <param name="controlType">The type of controls used (Controller true/Keyboard false)</param>
1132    public void WeaponRate(PhysicsObject origin, Timer weapon, bool controlType)
1133    {
1134        weapon.Interval = 0.225;
1135        weapon.Timeout += delegate { FireWeapon(origin, Shape.Rectangle); };
1136        weapon.Start();
1137        if (controlType == true) {
1138            ControllerOne.Listen(Button.RightTrigger, ButtonState.Released, StopRate, null, weapon);
1139        }
1140        else { Keyboard.Listen(Key.Z, ButtonState.Released, StopRate, null, weapon); }
1141    }
1142
1143    /// <summary>
1144    /// Stops the weapon timer from cycling the next shot.
1145    /// </summary>
1146    /// <param name="weapon">The timer to stop</param>
1147    public void StopRate(Timer weapon)
1148    {
1149        weapon.Stop();
1150    }
1151
1152    /// <summary>
1153    /// Calls a subprogram which creates a Bullet at the specified location and sends it off flying.
1154    /// </summary>
1155    /// <param name="origin">The object to set origin point for</param>
1156    /// <param name="shape">Shape of the bullet's collision detector</param>
1157    public void FireWeapon(PhysicsObject origin, Shape shape)
1158    {
1159        CreateBullet(origin.X + 5, origin.Y + 10, 15.0, 4.0, shape);
1160        CreateBullet(origin.X - 5, origin.Y + 10, 15.0, 4.0, shape);
1161    }
1162
1163    public void CreateBullet(double x, double y, double width, double height, Shape shape)
1164    {
1165        Bullet Weapon1 = new Bullet(width, height);
1166        Weapon1.Damage = 5;
1167        Weapon1.X = x;
1168        Weapon1.Y = y;
1169        Weapon1.Shape = shape;
1170        Weapon1.Hit(new Vector(0.0, 600.0));
1171    }
1172    */
1173    #endregion
1174}
Note: See TracBrowser for help on using the repository browser.