2
0

Tank.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Tank.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Content;
  13. using Microsoft.Xna.Framework.Graphics;
  14. using Microsoft.Xna.Framework.Input;
  15. #endregion
  16. namespace PeerToPeer
  17. {
  18. /// <summary>
  19. /// Each player controls a tank, which they can drive around the screen.
  20. /// This class implements the logic for moving and drawing the tank, and
  21. /// responds to input that is passed in from outside. The Tank class does
  22. /// not implement any networking functionality, however: that is all
  23. /// handled by the main game class.
  24. /// </summary>
  25. class Tank
  26. {
  27. #region Constants
  28. // Constants control how fast the tank moves and turns.
  29. const float TankTurnRate = 0.01f;
  30. const float TurretTurnRate = 0.03f;
  31. const float TankSpeed = 0.3f;
  32. const float TankFriction = 0.9f;
  33. #endregion
  34. #region Fields
  35. // The current position and rotation of the tank.
  36. public Vector2 Position;
  37. public Vector2 Velocity;
  38. public float TankRotation;
  39. public float TurretRotation;
  40. // Input controls can be read from keyboard, gamepad, or the network.
  41. public Vector2 TankInput;
  42. public Vector2 TurretInput;
  43. // Textures used to draw the tank.
  44. Texture2D tankTexture;
  45. Texture2D turretTexture;
  46. Vector2 screenSize;
  47. #endregion
  48. /// <summary>
  49. /// Constructs a new Tank instance.
  50. /// </summary>
  51. public Tank (int gamerIndex,ContentManager content,
  52. int screenWidth,int screenHeight)
  53. {
  54. // Use the gamer index to compute a starting position, so each player
  55. // starts in a different place as opposed to all on top of each other.
  56. Position.X = screenWidth / 4 + (gamerIndex % 5) * screenWidth / 8;
  57. Position.Y = screenHeight / 4 + (gamerIndex / 5) * screenHeight / 5;
  58. TankRotation = -MathHelper.PiOver2;
  59. TurretRotation = -MathHelper.PiOver2;
  60. tankTexture = content.Load<Texture2D> ("Tank");
  61. turretTexture = content.Load<Texture2D> ("Turret");
  62. screenSize = new Vector2 (screenWidth, screenHeight);
  63. }
  64. /// <summary>
  65. /// Moves the tank in response to the current input settings.
  66. /// </summary>
  67. public void Update ()
  68. {
  69. // Gradually turn the tank and turret to face the requested direction.
  70. TankRotation = TurnToFace (TankRotation, TankInput, TankTurnRate);
  71. TurretRotation = TurnToFace (TurretRotation, TurretInput, TurretTurnRate);
  72. // How close the desired direction is the tank facing?
  73. Vector2 tankForward = new Vector2 ((float)Math.Cos (TankRotation),
  74. (float)Math.Sin (TankRotation));
  75. Vector2 targetForward = new Vector2 (TankInput.X, -TankInput.Y);
  76. float facingForward = Vector2.Dot (tankForward, targetForward);
  77. // If we have finished turning, also start moving forward.
  78. if (facingForward > 0)
  79. Velocity += tankForward * facingForward * facingForward * TankSpeed;
  80. // Update the position and velocity.
  81. Position += Velocity;
  82. Velocity *= TankFriction;
  83. // Clamp so the tank cannot drive off the edge of the screen.
  84. Position = Vector2.Clamp (Position, Vector2.Zero, screenSize);
  85. }
  86. /// <summary>
  87. /// Gradually rotates the tank to face the specified direction.
  88. /// </summary>
  89. static float TurnToFace (float rotation, Vector2 target, float turnRate)
  90. {
  91. if (target == Vector2.Zero)
  92. return rotation;
  93. float angle = (float)Math.Atan2 (-target.Y, target.X);
  94. float difference = rotation - angle;
  95. while (difference > MathHelper.Pi)
  96. difference -= MathHelper.TwoPi;
  97. while (difference < -MathHelper.Pi)
  98. difference += MathHelper.TwoPi;
  99. turnRate *= Math.Abs (difference);
  100. if (difference < 0)
  101. return rotation + Math.Min (turnRate, -difference);
  102. else
  103. return rotation - Math.Min (turnRate, difference);
  104. }
  105. /// <summary>
  106. /// Draws the tank and turret.
  107. /// </summary>
  108. public void Draw (SpriteBatch spriteBatch)
  109. {
  110. Vector2 origin = new Vector2 (tankTexture.Width / 2, tankTexture.Height / 2);
  111. spriteBatch.Draw (tankTexture, Position, null, Color.White,
  112. TankRotation, origin, 1, SpriteEffects.None, 0);
  113. spriteBatch.Draw (turretTexture, Position, null, Color.White,
  114. TurretRotation, origin, 1, SpriteEffects.None, 0);
  115. }
  116. }
  117. }