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.

177 lines
8.0 KiB

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