PrimitivesSampleGame.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. //-----------------------------------------------------------------------------
  2. // PrimitivesSampleGame.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Graphics;
  12. using Microsoft.Xna.Framework.Content;
  13. using Microsoft.Xna.Framework.Input;
  14. namespace PrimitivesSample
  15. {
  16. // This sample illustrates the use of PrimitiveBatch to draw lines and points
  17. // on the screen. Lines and points are used to recreate the Spacewars starter kit's
  18. // retro mode.
  19. public class PrimitivesSampleGame : Microsoft.Xna.Framework.Game
  20. {
  21. #if ANDROID
  22. // Static reference to the Android activity
  23. public new static object? Activity;
  24. #endif
  25. // this constant controls the number of stars that will be created when the game
  26. // starts up.
  27. const int NumStars = 500;
  28. // what percentage of those stars will be "big" stars? the default is 20%.
  29. const float PercentBigStars = .2f;
  30. // how bright will stars be? somewhere between these two values.
  31. const byte MinimumStarBrightness = 56;
  32. const byte MaximumStarBrightness = 255;
  33. // how big is the ship?
  34. const float ShipSizeX = 10f;
  35. const float ShipSizeY = 15f;
  36. const float ShipCutoutSize = 5f;
  37. // the radius of the sun.
  38. const float SunSize = 30f;
  39. GraphicsDeviceManager graphics;
  40. // PrimitiveBatch is the new class introduced in this sample. We'll use it to
  41. // draw everything in this sample, including the stars, ships, and sun.
  42. PrimitiveBatch primitiveBatch = null!;
  43. // these two lists, stars, and starColors, keep track of the positions and
  44. // colors of all the stars that we will randomly generate during the initialize
  45. // phase.
  46. List<Vector2> stars = new List<Vector2>();
  47. List<Color> starColors = new List<Color>();
  48. public PrimitivesSampleGame()
  49. {
  50. graphics = new GraphicsDeviceManager(this);
  51. Content.RootDirectory = "Content";
  52. graphics.PreferredBackBufferWidth = 480;
  53. graphics.PreferredBackBufferHeight = 800;
  54. IsMouseVisible = true;
  55. #if MOBILE
  56. graphics.IsFullScreen = true;
  57. #endif
  58. }
  59. protected override void Initialize()
  60. {
  61. base.Initialize();
  62. // CreateStars needs to know how big the GraphicsDevice's viewport is, so
  63. // once base.Initialize has been called, we can call this.
  64. CreateStars();
  65. }
  66. private void CreateStars()
  67. {
  68. // since every star will be put in a random place and have a random color,
  69. // a random number generator might come in handy.
  70. Random random = new Random();
  71. // where can we put the stars?
  72. int screenWidth = graphics.GraphicsDevice.Viewport.Width;
  73. int screenHeight = graphics.GraphicsDevice.Viewport.Height;
  74. for (int i = 0; i < NumStars; i++)
  75. {
  76. // pick a random spot...
  77. Vector2 where = new Vector2(
  78. random.Next(0, screenWidth),
  79. random.Next(0, screenHeight));
  80. // ...and a random color. it's safe to cast random.Next to a byte,
  81. // because MinimumStarBrightness and MaximumStarBrightness are both
  82. // bytes.
  83. byte greyValue =
  84. (byte)random.Next(MinimumStarBrightness, MaximumStarBrightness);
  85. Color color = new Color(greyValue, greyValue, greyValue);
  86. // if the random number was greater than the percentage chance for a big
  87. // star, this is just a normal star.
  88. if ((float)random.NextDouble() > PercentBigStars)
  89. {
  90. starColors.Add(color);
  91. stars.Add(where);
  92. }
  93. else
  94. {
  95. // if this star is randomly selected to be a "big" star, we actually
  96. // add four points and colors to stars and starColors. big stars are
  97. // a block of four points, instead of just one point.
  98. for (int j = 0; j < 4; j++)
  99. {
  100. starColors.Add(color);
  101. }
  102. stars.Add(where);
  103. stars.Add(where + Vector2.UnitX);
  104. stars.Add(where + Vector2.UnitY);
  105. stars.Add(where + Vector2.One);
  106. }
  107. }
  108. }
  109. /// <summary>
  110. /// Load your graphics content.
  111. /// </summary>
  112. protected override void LoadContent()
  113. {
  114. primitiveBatch = new PrimitiveBatch(graphics.GraphicsDevice);
  115. }
  116. /// <summary>
  117. /// Allows the game to run logic such as updating the world,
  118. /// checking for collisions, gathering input and playing audio.
  119. /// </summary>
  120. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  121. protected override void Update(GameTime gameTime)
  122. {
  123. // Allows the game to exit
  124. if ((GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  125. || Keyboard.GetState().IsKeyDown(Keys.Escape))
  126. this.Exit();
  127. base.Update(gameTime);
  128. }
  129. /// <summary>
  130. /// This is called when the game should draw itself.
  131. /// </summary>
  132. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  133. protected override void Draw(GameTime gameTime)
  134. {
  135. graphics.GraphicsDevice.Clear(Color.Black);
  136. // how big is the screen? we'll use that information to center the sun
  137. // and place the ships.
  138. int screenWidth = graphics.GraphicsDevice.Viewport.Width;
  139. int screenHeight = graphics.GraphicsDevice.Viewport.Height;
  140. // draw the sun in the center
  141. DrawSun(new Vector2(screenWidth / 2, screenHeight / 2));
  142. // draw the left hand ship
  143. DrawShip(new Vector2(100, screenHeight / 2));
  144. // and the right hand ship
  145. DrawShip(new Vector2(screenWidth - 100, screenHeight / 2));
  146. DrawStars();
  147. base.Draw(gameTime);
  148. }
  149. // DrawStars is called to do exactly what its name says: draw the stars.
  150. private void DrawStars()
  151. {
  152. // stars are drawn as a list of points, so begin the primitiveBatch.
  153. primitiveBatch.Begin(PrimitiveType.TriangleList);
  154. // loop through all of the stars, and tell primitive batch to draw them.
  155. // each star is a very small triangle.
  156. for (int i = 0; i < stars.Count; i++)
  157. {
  158. primitiveBatch.AddVertex(stars[i], starColors[i]);
  159. primitiveBatch.AddVertex(stars[i] + Vector2.UnitX, starColors[i]);
  160. primitiveBatch.AddVertex(stars[i] + Vector2.UnitY, starColors[i]);
  161. }
  162. // and then tell it that we're done.
  163. primitiveBatch.End();
  164. }
  165. // called to draw the spacewars ship at a point on the screen.
  166. private void DrawShip(Vector2 where)
  167. {
  168. // tell the primitive batch to start drawing lines
  169. primitiveBatch.Begin(PrimitiveType.LineList);
  170. // from the nose, down the left hand side
  171. primitiveBatch.AddVertex(
  172. where + new Vector2(0f, -ShipSizeY), Color.White);
  173. primitiveBatch.AddVertex(
  174. where + new Vector2(-ShipSizeX, ShipSizeY), Color.White);
  175. // to the right and up, into the cutout
  176. primitiveBatch.AddVertex(
  177. where + new Vector2(-ShipSizeX, ShipSizeY), Color.White);
  178. primitiveBatch.AddVertex(
  179. where + new Vector2(0f, ShipSizeY - ShipCutoutSize), Color.White);
  180. // to the right and down, out of the cutout
  181. primitiveBatch.AddVertex(
  182. where + new Vector2(0f, ShipSizeY - ShipCutoutSize), Color.White);
  183. primitiveBatch.AddVertex(
  184. where + new Vector2(ShipSizeX, ShipSizeY), Color.White);
  185. // and back up to the nose, where we started.
  186. primitiveBatch.AddVertex(
  187. where + new Vector2(ShipSizeX, ShipSizeY), Color.White);
  188. primitiveBatch.AddVertex(
  189. where + new Vector2(0f, -ShipSizeY), Color.White);
  190. // and we're done.
  191. primitiveBatch.End();
  192. }
  193. // called to draw the spacewars sun.
  194. private void DrawSun(Vector2 where)
  195. {
  196. // the sun is made from 4 lines in a circle.
  197. primitiveBatch.Begin(PrimitiveType.LineList);
  198. // draw the vertical and horizontal lines
  199. primitiveBatch.AddVertex(where + new Vector2(0, SunSize), Color.White);
  200. primitiveBatch.AddVertex(where + new Vector2(0, -SunSize), Color.White);
  201. primitiveBatch.AddVertex(where + new Vector2(SunSize, 0), Color.White);
  202. primitiveBatch.AddVertex(where + new Vector2(-SunSize, 0), Color.White);
  203. // to know where to draw the diagonal lines, we need to use trig.
  204. // cosine of pi / 4 tells us what the x coordinate of a circle's radius is
  205. // at 45 degrees. the y coordinate normally would come from sin, but sin and
  206. // cos 45 are the same, so we can reuse cos for both x and y.
  207. float sunSizeDiagonal = (float)Math.Cos(MathHelper.PiOver4);
  208. // since that trig tells us the x and y for a unit circle, which has a
  209. // radius of 1, we need scale that result by the sun's radius.
  210. sunSizeDiagonal *= SunSize;
  211. primitiveBatch.AddVertex(
  212. where + new Vector2(-sunSizeDiagonal, sunSizeDiagonal), Color.Gray);
  213. primitiveBatch.AddVertex(
  214. where + new Vector2(sunSizeDiagonal, -sunSizeDiagonal), Color.Gray);
  215. primitiveBatch.AddVertex(
  216. where + new Vector2(sunSizeDiagonal, sunSizeDiagonal), Color.Gray);
  217. primitiveBatch.AddVertex(
  218. where + new Vector2(-sunSizeDiagonal, -sunSizeDiagonal), Color.Gray);
  219. primitiveBatch.End();
  220. }
  221. // #region Entry point
  222. //
  223. // /// <summary>
  224. // /// The main entry point for the application.
  225. // /// </summary>
  226. // static void Main()
  227. // {
  228. // using (PrimitivesSampleGame game = new PrimitivesSampleGame())
  229. // {
  230. // game.Run();
  231. // }
  232. // }
  233. //
  234. // #endregion
  235. }
  236. }