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

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