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

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