source: 2013/27/ArttuY/trunk/RampageRebellion/RampageRebellion/RampageRebellion/RRBegin.cs @ 4451

Revision 4451, 44.9 KB checked in by eearyla, 7 years ago (diff)

Backup

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