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

Revision 4490, 45.7 KB checked in by jaollipa, 8 years ago (diff)

PRE-ALPHA 1.0

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