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.

146 lines
3.9 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. Water
  13. }
  14. class Tile {
  15. Texture2D texture;
  16. Terrain terrain;
  17. Rectangle position;
  18. public Tile(Texture2D texture, Terrain terrain, Rectangle position) {
  19. this.texture = texture;
  20. this.terrain = terrain;
  21. this.position = position;
  22. }
  23. public Rectangle Position { get { return position; } }
  24. public Terrain Terrain { get { return terrain; } }
  25. public void Draw(SpriteBatch spriteBatch) {
  26. int size = World.TileSize;
  27. switch (terrain) {
  28. case Terrain.Grass: {
  29. // TODO: hold these rectangles statically instead of making them anew constantly.
  30. Rectangle source = new Rectangle(3 * size, 0 * size, size, size);
  31. spriteBatch.Draw(texture, position, source, Color.White);
  32. break;
  33. }
  34. case Terrain.GrassL: {
  35. Rectangle source = new Rectangle(2 * size, 0 * size, size, size);
  36. spriteBatch.Draw(texture, position, source, Color.White);
  37. break;
  38. }
  39. case Terrain.GrassR: {
  40. Rectangle source = new Rectangle(4 * size, 0 * size, size, size);
  41. spriteBatch.Draw(texture, position, source, Color.White);
  42. break;
  43. }
  44. case Terrain.Rock: {
  45. Rectangle source = new Rectangle(3 * size, 1 * size, size, size);
  46. spriteBatch.Draw(texture, position, source, Color.White);
  47. break;
  48. }
  49. case Terrain.Water: {
  50. Rectangle source = new Rectangle(9 * size, 2 * size, size, size);
  51. spriteBatch.Draw(texture, position, source, Color.White);
  52. break;
  53. }
  54. case Terrain.Empty:
  55. default:
  56. break;
  57. }
  58. }
  59. }
  60. class World {
  61. public const int TileSize = 16;
  62. int width;
  63. int height;
  64. Tile[,] tiles;
  65. public int Width { get; }
  66. public int Height { get; }
  67. string[] worldDesc = new string[] {
  68. " ",
  69. " ",
  70. " ",
  71. " <=> ",
  72. " ",
  73. " ",
  74. " <=> <=> ",
  75. " = ",
  76. " ",
  77. " ",
  78. "=============> <===",
  79. "..............~~~~~." };
  80. public World(Texture2D texture) {
  81. // TODO: better error handling for if the string[] isn't rectangular.
  82. width = worldDesc[0].Length;
  83. height = worldDesc.Length;
  84. tiles = new Tile[width, height];
  85. for (int j = 0; j < height; j++) {
  86. for (int i = 0; i < width; i++) {
  87. Terrain terrain;
  88. switch (worldDesc[j][i]) {
  89. case '=':
  90. terrain = Terrain.Grass;
  91. break;
  92. case '<':
  93. terrain = Terrain.GrassL;
  94. break;
  95. case '>':
  96. terrain = Terrain.GrassR;
  97. break;
  98. case '.':
  99. terrain = Terrain.Rock;
  100. break;
  101. case '~':
  102. terrain = Terrain.Water;
  103. break;
  104. case ' ':
  105. default:
  106. terrain = Terrain.Empty;
  107. break;
  108. }
  109. var position = new Rectangle(i * TileSize, j * TileSize, TileSize, TileSize);
  110. tiles[i, j] = new Tile(texture, terrain, position);
  111. }
  112. }
  113. }
  114. public void Draw(SpriteBatch spriteBatch) {
  115. for (int j = 0; j < height; j++) {
  116. for (int i = 0; i < width; i++) {
  117. tiles[i, j].Draw(spriteBatch);
  118. }
  119. }
  120. }
  121. public List<Rectangle> CollisionTargets() {
  122. var result = new List<Rectangle>();
  123. for (int j = 0; j < height; j++) {
  124. for (int i = 0; i < width; i++) {
  125. var t = tiles[i, j];
  126. if (t.Terrain != Terrain.Empty) {
  127. result.Add(t.Position);
  128. }
  129. }
  130. }
  131. return result;
  132. }
  133. }
  134. }