Tank.cs 4.2 KB

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