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.

174 lines
7.1 KiB

  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Graphics;
  3. using System;
  4. using System.Collections.Generic;
  5. namespace Jumpy {
  6. enum Terrain {
  7. Empty,
  8. Grass,
  9. GrassL,
  10. GrassR,
  11. Rock,
  12. RockL,
  13. RockR,
  14. Water,
  15. Block
  16. }
  17. class Tile {
  18. Texture2D texture;
  19. Terrain terrain;
  20. Rectangle position;
  21. public Tile(Texture2D texture, Terrain terrain, Rectangle position) {
  22. this.texture = texture;
  23. this.terrain = terrain;
  24. this.position = position;
  25. }
  26. public Rectangle Position { get { return position; } }
  27. public Terrain Terrain { get { return terrain; } }
  28. public void Draw(SpriteBatch spriteBatch, Camera camera) {
  29. int size = World.TileSize;
  30. Vector2 drawPos = new Vector2(position.Left - camera.Left, position.Top);
  31. switch (terrain) {
  32. case Terrain.Grass: {
  33. // TODO: hold these rectangles statically instead of making them anew constantly.
  34. Rectangle source = new Rectangle(3 * size, 0 * size, size, size);
  35. spriteBatch.Draw(texture, drawPos, source, Color.White);
  36. break;
  37. }
  38. case Terrain.GrassL: {
  39. Rectangle source = new Rectangle(2 * size, 0 * size, size, size);
  40. spriteBatch.Draw(texture, drawPos, source, Color.White);
  41. break;
  42. }
  43. case Terrain.GrassR: {
  44. Rectangle source = new Rectangle(4 * size, 0 * size, size, size);
  45. spriteBatch.Draw(texture, drawPos, source, Color.White);
  46. break;
  47. }
  48. case Terrain.Rock: {
  49. Rectangle source = new Rectangle(3 * size, 1 * size, size, size);
  50. spriteBatch.Draw(texture, drawPos, source, Color.White);
  51. break;
  52. }
  53. case Terrain.RockL: {
  54. Rectangle source = new Rectangle(1 * size, 2 * size, size, size);
  55. spriteBatch.Draw(texture, drawPos, source, Color.White);
  56. break;
  57. }
  58. case Terrain.RockR: {
  59. Rectangle source = new Rectangle(5 * size, 2 * size, size, size);
  60. spriteBatch.Draw(texture, drawPos, source, Color.White);
  61. break;
  62. }
  63. case Terrain.Water: {
  64. Rectangle source = new Rectangle(9 * size, 2 * size, size, size);
  65. spriteBatch.Draw(texture, drawPos, source, Color.White);
  66. break;
  67. }
  68. case Terrain.Block: {
  69. Rectangle source = new Rectangle(6 * size, 3 * size, size, size);
  70. spriteBatch.Draw(texture, drawPos, source, Color.White);
  71. break;
  72. }
  73. case Terrain.Empty:
  74. default:
  75. break;
  76. }
  77. }
  78. }
  79. class World {
  80. public const int TileSize = 16;
  81. int width;
  82. int height;
  83. Tile[,] tiles;
  84. public int Width { get; }
  85. public int Height { get; }
  86. string[] worldDesc = new string[] {
  87. " X ",
  88. " . ",
  89. " X <======> <==X X <=> <XX> XX . ",
  90. " XXX . ",
  91. " XXXX . ",
  92. " XXXXX . ",
  93. " X <X=X> <> <> <X> = <> X X X X <> X X XX X <=X> XXXXXX . ",
  94. " <> [] [] XX XX XXX XX XXXXXXX . ",
  95. " <> [] [] [] XXX XXX XXXX XXX <> <> XXXXXXXX ",
  96. " []12345678[]123456[]123456789[]1234567890 123456 123456 12345 1234 12345 1234 123XXXX XXXX1234XXXXX XXXX1234[]123 1234567[]XXXXXXXXX12345678 ",
  97. "===========================..========..======..=========..=========> <=============> <==============================================================> <=======..==============..==============================",
  98. "...................................................................] [.............] [..............................................................] [......................................................." };
  99. public World(Texture2D texture) {
  100. // TODO: better error handling for if the string[] isn't rectangular.
  101. width = worldDesc[0].Length;
  102. height = worldDesc.Length;
  103. tiles = new Tile[width, height];
  104. for (int j = 0; j < height; j++) {
  105. for (int i = 0; i < width; i++) {
  106. Terrain terrain;
  107. switch (worldDesc[j][i]) {
  108. case '=':
  109. terrain = Terrain.Grass;
  110. break;
  111. case '<':
  112. terrain = Terrain.GrassL;
  113. break;
  114. case '>':
  115. terrain = Terrain.GrassR;
  116. break;
  117. case '.':
  118. terrain = Terrain.Rock;
  119. break;
  120. case '[':
  121. terrain = Terrain.RockL;
  122. break;
  123. case ']':
  124. terrain = Terrain.RockR;
  125. break;
  126. case '~':
  127. terrain = Terrain.Water;
  128. break;
  129. case 'X':
  130. terrain = Terrain.Block;
  131. break;
  132. case ' ':
  133. default:
  134. terrain = Terrain.Empty;
  135. break;
  136. }
  137. var position = new Rectangle(i * TileSize, j * TileSize, TileSize, TileSize);
  138. tiles[i, j] = new Tile(texture, terrain, position);
  139. }
  140. }
  141. }
  142. public void Draw(SpriteBatch spriteBatch, Camera camera) {
  143. for (int j = 0; j < height; j++) {
  144. for (int i = 0; i < width; i++) {
  145. tiles[i, j].Draw(spriteBatch, camera);
  146. }
  147. }
  148. }
  149. public List<Rectangle> CollisionTargets() {
  150. var result = new List<Rectangle>();
  151. for (int j = 0; j < height; j++) {
  152. for (int i = 0; i < width; i++) {
  153. var t = tiles[i, j];
  154. if (t.Terrain != Terrain.Empty) {
  155. result.Add(t.Position);
  156. }
  157. }
  158. }
  159. return result;
  160. }
  161. }
  162. }