Blackthorn

I <3 Lambda Expressions

Dec 7th, 2014
471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.82 KB | None | 0 0
  1. // Allows the game to exit by checking that a specific key or button was pressed
  2. // on this frame, ks is the currentstate of the keyboard and ps is the current state
  3. // of a single gamepad. Every frame I save a backup of the current state so that I
  4. // can compare the current state and the state in the last frame.
  5.  
  6. // If I only checked the current state of input devices, this code would execute on
  7. // every frame the button is down for. Since this code will hide everything and show
  8. // the menu when the menu is inactive and then exit when the menu is active, a user
  9. // pushing escape or back from ingame (or a submenu) would see one frame of the main
  10. // menu and then exit the game unless they pressed escape for only 1/60th of a second.
  11.  
  12. // At this point only p1 can control menus because I didn't want my if conditions
  13. // to get crazy big.
  14. if (ks.IsKeyDown(Keys.Escape) && _oldKeyboardState.IsKeyUp(Keys.Escape) ||
  15.     ps.IsButtonDown(Buttons.Back) && _oldPadState.IsButtonUp(Buttons.Back))
  16. {
  17.     if (_menu.Enabled)
  18.         this.Exit();
  19.     else
  20.     {
  21.         HideAllScene();
  22.         SetTitle();
  23.         _menu.Show();
  24.     }
  25. }
  26.  
  27. // As of December 4, a virtual controller object was built to simplify this a bit.
  28. // Creating virtual controller objects is pretty straight forward, they have defaults
  29. // for keys and xbox buttons built in, you just need to give the object a refernce to
  30. // the game object (this) and the controller identifier (PlayerIndex.One/Two)
  31. PlayerOne = new VirtualController(this, PlayerIndex.One);
  32.  
  33. // Since the keyboard controls on player two should be different, we can manually
  34. // override them. xbox buttons are differentiated by the playerindex so we can leave
  35. // that alone. Here are all the buttons I currently change for PlayerTwo:
  36. PlayerTwo = new VirtualController(this, PlayerIndex.Two)
  37. {   // Regardless if it is one button/key or many, it needs to be an array.
  38.     MovementUpKeys = new[] { Keys.Up },
  39.     MovementDownKeys = new[] { Keys.Down },
  40.     MovementLeftKeys = new[] { Keys.Left },
  41.     MovementRightKeys = new[] { Keys.Right },
  42.  
  43.     AimUpKeys = new[] { Keys.NumPad8 },
  44.     AimDownKeys = new[] { Keys.NumPad2 },
  45.     AimLeftKeys = new[] { Keys.NumPad4 },
  46.     AimRightKeys = new[] { Keys.NumPad6 },
  47.     // I give player two the option of using any of these keys to fire.
  48.     GameFireKeys = new[] { Keys.Add, Keys.Subtract, Keys.Delete, Keys.Insert, }
  49. };
  50.  
  51. // Next is the start of the menu as of December 4th but now I've got virtual
  52. // controller telling me if each player is pressing a button for going back. The
  53. // VirtualController object handles old&new states of the keyboard and gamepad. If
  54. // either player presses back on this frame, ActionBack will return "True" and this
  55. // code will be executed.
  56. if (PlayerOne.ActionBack || PlayerTwo.ActionBack)
  57. {
  58.     if (_menu.Enabled)
  59.         Exit();
  60.     else
  61.     {
  62.         HideAllScene();
  63.         SetTitle();
  64.         _menu.Show();
  65.         GamePad.SetVibration(PlayerOne.PlayerIndex, 0, 0);
  66.         GamePad.SetVibration(PlayerTwo.PlayerIndex, 0, 0);
  67.     }
  68. }
  69.  
  70. // The following is today's code. I've got the two virtual controllers in an
  71. // array and I can check if any of them has a key or button pressed on this frame
  72. // by using a lambda expression. "inputs.Any(p => p.ActionBack)"
  73. var inputs = new[] {PlayerOne, PlayerTwo};
  74. if (AllowExit && inputs.Any(p => p.ActionBack))
  75. {
  76.     if (_menu.Enabled)
  77.     {
  78.         MenuEffects[0].Play();
  79.         Exit();
  80.     }
  81.     else
  82.     {
  83.         MenuEffects[0].Play();
  84.         HideAllScene();
  85.         SetTitle();
  86.         _menu.Show();
  87.         inputs.ForEach(p => GamePad.SetVibration(p.PlayerIndex, 0, 0));
  88.     }
  89. }
  90. // Using .Any(p => p.ActionBack) is kind of like doing this:
  91. foreach(VirtualController p in inputs)
  92. {
  93.     if(p.ActionBack) return true;
  94. }
  95.  
  96. // Also you don't just need to call methods on p, my own lack of an imagination
  97. // caused me to think lambda expressions were unnecessary when I first experienced
  98. // them in MVC. Just like in the for each loop you can do anything you want with the
  99. // parameter. Consider this:
  100.  
  101. Components.Where(c => c is Player).ForEach(p =>
  102. {
  103.     p.Kill();
  104.     Console.WriteLine("Just murdered {0}!", p);
  105. });
  106.  
  107. Components
  108.     .Where(c => Toolbox.IsComponentDead(c))
  109.     .All(component => Components.Remove(component));
  110.  
  111. // The first command would find all the components that are of type Player and call their
  112. // Kill method and write a line to the console. If you want to execute more than one
  113. // statement together in a linq expression (Just like you would in an if) you surround it
  114. // with braces {}. The next line shows calling an outside method with the irater as the
  115. // parameter.
  116.  
  117. // Another great thing about linq expressions is that they delay execution until it is
  118. // required (known as lazy or deferred execution). This can boost performance significantly.
  119. // See MSDNs description here:  http://msdn.microsoft.com/en-ca/library/bb943859.aspx
  120. // Also check out this example: http://msdn.microsoft.com/en-ca/library/bb669162.aspx
Advertisement
Add Comment
Please, Sign In to add comment