A stealth-based 2D platformer where you don't have to kill anyone unless you want to. https://www.semicolin.games
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.9 KiB

  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using Microsoft.Xna.Framework.Input;
  4. using System;
  5. using System.Collections.Generic;
  6. namespace Jumpy {
  7. public class JumpyGame : Game {
  8. GraphicsDeviceManager graphics;
  9. // TODO: use a History<RenderTarget2D> but implement functions that let us re-use the
  10. // RenderTargets instead of re-creating them every frame?
  11. const int numRenderTargets = 1;
  12. RenderTarget2D[] renderTargets = new RenderTarget2D[numRenderTargets];
  13. int renderTargetIdx = 0;
  14. SpriteBatch spriteBatch;
  15. SpriteFont font;
  16. bool fullScreen = false;
  17. IDisplay display;
  18. History<KeyboardState> keyboard = new History<KeyboardState>(2);
  19. History<GamePadState> gamePad = new History<GamePadState>(2);
  20. FpsCounter fpsCounter = new FpsCounter();
  21. Player player;
  22. Texture2D grassland;
  23. Texture2D grasslandBg1;
  24. Texture2D grasslandBg2;
  25. public JumpyGame() {
  26. graphics = new GraphicsDeviceManager(this);
  27. IsMouseVisible = true;
  28. Content.RootDirectory = "Content";
  29. }
  30. // Performs initialization that's needed before starting to run.
  31. protected override void Initialize() {
  32. display = (IDisplay) Services.GetService(typeof(IDisplay));
  33. display.Initialize(Window, graphics);
  34. display.SetFullScreen(fullScreen);
  35. for (int i = 0; i < renderTargets.Length; i++) {
  36. renderTargets[i] = new RenderTarget2D(
  37. GraphicsDevice, Camera.Width, Camera.Height, false /* mipmap */,
  38. GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24);
  39. }
  40. base.Initialize();
  41. }
  42. // Called once per game. Loads all game content.
  43. protected override void LoadContent() {
  44. spriteBatch = new SpriteBatch(GraphicsDevice);
  45. font = Content.Load<SpriteFont>("font");
  46. player = new Player(Content.Load<Texture2D>("player_1x"));
  47. grassland = Content.Load<Texture2D>("grassland");
  48. grasslandBg1 = Content.Load<Texture2D>("grassland_bg1");
  49. grasslandBg2 = Content.Load<Texture2D>("grassland_bg2");
  50. }
  51. // Called once per game. Unloads all game content.
  52. protected override void UnloadContent() {
  53. // TODO: Unload any non ContentManager content here.
  54. }
  55. // Updates the game world.
  56. protected override void Update(GameTime gameTime) {
  57. gamePad.Add(GamePad.GetState(PlayerIndex.One));
  58. keyboard.Add(Keyboard.GetState());
  59. if (keyboard[0].IsKeyDown(Keys.Escape) || gamePad[0].IsButtonDown(Buttons.Start)) {
  60. Exit();
  61. }
  62. if (keyboard[0].IsKeyDown(Keys.F12) && keyboard[1].IsKeyUp(Keys.F12) ||
  63. gamePad[0].IsButtonDown(Buttons.Back) && gamePad[1].IsButtonUp(Buttons.Back)) {
  64. fullScreen = !fullScreen;
  65. display.SetFullScreen(fullScreen);
  66. }
  67. player.Update(gameTime, gamePad);
  68. base.Update(gameTime);
  69. }
  70. // Called when the game should draw itself.
  71. protected override void Draw(GameTime gameTime) {
  72. // We need to update the FPS counter in Draw() since Update() might get called more
  73. // frequently, especially when gameTime.IsRunningSlowly.
  74. fpsCounter.Update();
  75. // Draw scene to RenderTarget.
  76. RenderTarget2D renderTarget = renderTargets[renderTargetIdx];
  77. renderTargetIdx = (renderTargetIdx + 1) % renderTargets.Length;
  78. GraphicsDevice.SetRenderTarget(renderTarget);
  79. GraphicsDevice.Clear(Color.CornflowerBlue);
  80. spriteBatch.Begin();
  81. // Draw background.
  82. Rectangle bgSource = new Rectangle(0, grasslandBg1.Height - Camera.Height, Camera.Width, Camera.Height);
  83. Rectangle bgTarget = new Rectangle(0, 0, Camera.Width, Camera.Height);
  84. spriteBatch.Draw(grasslandBg2, bgTarget, bgSource, Color.White);
  85. spriteBatch.Draw(grasslandBg1, bgTarget, bgSource, Color.White);
  86. // Draw player.
  87. player.Draw(gameTime, spriteBatch);
  88. // Draw foreground tiles.
  89. int size = 16;
  90. Rectangle textureSource = new Rectangle(3 * size, 0 * size, size, size);
  91. for (int i = 0; i < Camera.Width / size; i++) {
  92. Vector2 drawPos = new Vector2(i * size, Camera.Height - size);
  93. spriteBatch.Draw(grassland, drawPos, textureSource, Color.White);
  94. }
  95. // Aaaaand we're done.
  96. spriteBatch.End();
  97. // Draw RenderTarget to screen.
  98. GraphicsDevice.SetRenderTarget(null);
  99. GraphicsDevice.Clear(Color.Black);
  100. spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend,
  101. SamplerState.PointClamp, DepthStencilState.Default,
  102. RasterizerState.CullNone);
  103. Rectangle drawRect = new Rectangle(
  104. 0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
  105. spriteBatch.Draw(renderTarget, drawRect, Color.White);
  106. string fpsText = $"{GraphicsDevice.Viewport.Width}x{GraphicsDevice.Viewport.Height}, " +
  107. $"{fpsCounter.Fps} FPS";
  108. spriteBatch.DrawString(font, fpsText, new Vector2(10, 10), Color.White);
  109. spriteBatch.End();
  110. base.Draw(gameTime);
  111. }
  112. }
  113. }