Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.63 KB | None | 0 0
  1. using System;
  2.  
  3. namespace ascii_game
  4. {
  5.  
  6.  
  7. /*
  8. * Open world
  9. *
  10. * GAME ENGINE ARCHITECTURE
  11. * some game data
  12. * Player (position, health)
  13. * Enemies (positions, health, various)
  14. * World data (buildings, dungeons, forests, fields)
  15. * Some text to describe what's happening (responds to events)
  16. * Characters (position, health, dialogue)
  17. * Elements and effects
  18. * Randomly generated
  19. * Save progress (file I/O)
  20. * Game Loop
  21. * keep track of the time
  22. * input
  23. * simulation (other loops, conditions, score/stats)
  24. * render
  25. * */
  26.  
  27. // A struct is not allocated on the heap the way
  28. // a class is. It is allocated on the Stack
  29. // The heap refers essentially to some random place in RAM
  30. // For instance an array of structs are going to be adjacent
  31. // in memory, instead of all over RAM
  32. struct Vector2
  33. {
  34. // Position, Direction, Rotation, Velocity
  35. public int x;
  36. public int y;
  37.  
  38. public Vector2(int newX, int newY)
  39. {
  40. x = newX;
  41. y = newY;
  42. }
  43.  
  44. public Vector2(Vector2 a)
  45. {
  46. x = a.x;
  47. y = a.y;
  48. }
  49. }
  50.  
  51. static class GameMath
  52. {
  53. static public bool Equals(Vector2 a, Vector2 b)
  54. {
  55. return a.x == b.x && a.y == b.y;
  56. }
  57. }
  58.  
  59. class Game
  60. {
  61. bool running = true;
  62.  
  63. Vector2 screenDimensions;
  64.  
  65. Vector2 playerPosition;
  66. int playerHealth;
  67. int playerXP;
  68. int playerStrength;
  69.  
  70. Vector2 bigRatPosition;
  71. int bigRatHealth;
  72.  
  73. Vector2 cougarPosition;
  74. int cougarHealth;
  75. int cougarStrength;
  76.  
  77. MyRandom random;
  78.  
  79. public Game()
  80. {
  81. random = new MyRandom();
  82. random.Seed(1001);
  83.  
  84. screenDimensions = new Vector2(24, 16);
  85.  
  86. playerPosition = new Vector2(12, 8);
  87. playerHealth = 100;
  88. playerStrength = 2;
  89.  
  90. bigRatPosition = new Vector2(20, 12);
  91. bigRatHealth = 25;
  92.  
  93. cougarHealth = 125;
  94. cougarPosition = new Vector2(4, 4);
  95. cougarStrength = 5;
  96. }
  97.  
  98. Vector2 GetPlayerInput()
  99. {
  100. ConsoleKeyInfo keyInfo = Console.ReadKey(true);
  101.  
  102. char c = keyInfo.KeyChar;
  103.  
  104. Vector2 movementDirection = new Vector2(0, 0);
  105.  
  106. if (c == 'w')
  107. {
  108. movementDirection.y--;
  109. }
  110. if (c == 's')
  111. {
  112. movementDirection.y++;
  113. }
  114. if (c == 'a')
  115. {
  116. movementDirection.x--;
  117. }
  118. if (c == 'd')
  119. {
  120. movementDirection.x++;
  121. }
  122. if (c == ' ')
  123. {
  124.  
  125. }
  126.  
  127. // Read the rest of the keys when they are holding down a key because
  128. // we'll get input faster than we can render
  129. while (Console.KeyAvailable)
  130. {
  131. Console.ReadKey(true);
  132. }
  133.  
  134. return movementDirection;
  135. }
  136.  
  137. struct Message
  138. {
  139. // @TODO: we should really start taking types of messages
  140. // for instance a Hit message,
  141. // a dead message,
  142. // XP message
  143. // push-back message
  144. String thing;
  145. String hitter;
  146. int damage;
  147.  
  148. public Message (String thing_, String hitter_, int damage_) {
  149. thing = thing_;
  150. hitter = hitter_;
  151. damage = damage_;
  152. }
  153.  
  154. public void PrintMessage()
  155. {
  156. Console.Write(thing);
  157. Console.Write(" was hit by ");
  158. Console.Write(hitter);
  159. Console.Write(" for ");
  160. Console.Write(damage);
  161. Console.WriteLine();
  162. }
  163. }
  164.  
  165.  
  166. public void Update()
  167. {
  168. int messageCount = 0;
  169. Message[] messages = new Message[4];
  170.  
  171.  
  172. while (running) {
  173. messageCount = 0;
  174.  
  175. // Input
  176.  
  177. // Player update
  178. Vector2 movementDirection = GetPlayerInput();
  179.  
  180. playerPosition.x += movementDirection.x;
  181. playerPosition.y += movementDirection.y;
  182.  
  183. bool playerMoved = !GameMath.Equals(movementDirection, new Vector2(0, 0));
  184.  
  185. // Rat update
  186. bool ratMoved = true;
  187.  
  188. Vector2 prevRatPosition = new Vector2(bigRatPosition);
  189. Vector2 ratDirection = new Vector2(random.RandomInclusive(-1, 1), 0);
  190. if (ratDirection.x == 0)
  191. {
  192. ratDirection.y = random.RandomInclusive(-1, 1);
  193. }
  194.  
  195. bigRatPosition.x += ratDirection.x;
  196. bigRatPosition.y += ratDirection.y;
  197.  
  198.  
  199. bool cougarMoved = false;
  200.  
  201. Vector2 prevCougarPosition = new Vector2(cougarPosition);
  202. Vector2 cougarDirection = new Vector2(random.RandomInclusive(0, 0), 0);
  203. if (cougarDirection.x == 0)
  204. {
  205. cougarDirection.y = random.RandomInclusive(0, 0);
  206. }
  207.  
  208. cougarPosition.x += cougarDirection.x;
  209. cougarPosition.y += cougarDirection.y;
  210.  
  211.  
  212. bool ratHit = false;
  213. bool cougarHit = false;
  214. bool playerHit = false;
  215. bool playerGainedXP = false;
  216.  
  217. // handle case where they move into each other
  218. // means that they never actually occupy the same spot
  219.  
  220. // direction (1, 0)
  221. // rat dir (-1, 0)
  222.  
  223. bool playerMoveInvalid = false;
  224.  
  225. if (cougarHealth > 0)
  226. {
  227. if (GameMath.Equals(playerPosition, cougarPosition))
  228. {
  229. if (cougarMoved)
  230. {
  231. playerHealth -= 25;
  232. playerHit = true;
  233. // TODO: push player back really far based on strength
  234. }
  235.  
  236. if (playerMoved)
  237. {
  238.  
  239.  
  240. if (cougarStrength < playerStrength)
  241. {
  242. cougarHealth -= 10;
  243. cougarPosition.x += movementDirection.x;
  244. cougarPosition.y += movementDirection.y;
  245. }
  246. else
  247. {
  248. playerHit = true;
  249. playerHealth -= 25;
  250. playerMoveInvalid = true;
  251.  
  252. messages[messageCount++] = new Message("Player", "Cougar", 25);
  253. }
  254.  
  255. cougarHit = true;
  256. }
  257. }
  258. else if (GameMath.Equals(playerPosition, prevCougarPosition))
  259. {
  260. playerPosition.x -= movementDirection.x;
  261. playerPosition.y -= movementDirection.y;
  262.  
  263. if (cougarMoved)
  264. {
  265. playerHealth -= 5;
  266. playerHit = true;
  267. }
  268.  
  269. if (playerMoved)
  270. {
  271. cougarHealth -= 10;
  272.  
  273. cougarPosition.x += movementDirection.x;
  274. cougarPosition.y += movementDirection.y;
  275.  
  276. cougarHit = true;
  277. }
  278. }
  279.  
  280. if (cougarHealth <= 0)
  281. {
  282. playerXP += 50000;
  283. playerGainedXP = true;
  284. }
  285. }
  286.  
  287. if (bigRatHealth > 0)
  288. {
  289. if (GameMath.Equals(playerPosition, bigRatPosition))
  290. {
  291. if (ratMoved)
  292. {
  293. playerHealth -= 5;
  294. playerHit = true;
  295.  
  296. messages[messageCount++] = new Message("Player", "Rat", 5);
  297. }
  298.  
  299. if (playerMoved)
  300. {
  301. bigRatHealth -= 10;
  302.  
  303. bigRatPosition.x += movementDirection.x;
  304. bigRatPosition.y += movementDirection.y;
  305.  
  306. ratHit = true;
  307.  
  308. messages[messageCount++] = new Message("Rat", "Player", 10);
  309. }
  310. }
  311. else if (GameMath.Equals(playerPosition, prevRatPosition))
  312. {
  313. playerPosition.x -= movementDirection.x;
  314. playerPosition.y -= movementDirection.y;
  315.  
  316. if (ratMoved)
  317. {
  318. playerHealth -= 5;
  319. playerHit = true;
  320.  
  321. messages[messageCount++] = new Message("Player", "Rat", 5);
  322. }
  323.  
  324. if (playerMoved)
  325. {
  326. bigRatHealth -= 10;
  327.  
  328. bigRatPosition.x += movementDirection.x;
  329. bigRatPosition.y += movementDirection.y;
  330.  
  331. messages[messageCount++] = new Message("Rat", "Player", 10);
  332.  
  333. ratHit = true;
  334. }
  335. }
  336.  
  337. if (bigRatHealth <= 0)
  338. {
  339. playerXP += 5;
  340. playerGainedXP = true;
  341. }
  342. }
  343.  
  344. if (playerMoveInvalid)
  345. {
  346. playerPosition.x -= movementDirection.x;
  347. playerPosition.y -= movementDirection.y;
  348. }
  349.  
  350. // Render
  351. Console.Clear();
  352.  
  353. // Instead of this just put things in a string and print it
  354. Vector2 cursorPosition = new Vector2(0, 0);
  355. for (int y = 0; y < screenDimensions.y; y++)
  356. {
  357. for (int x = 0; x < screenDimensions.x; x++)
  358. {
  359. cursorPosition.x = x;
  360. cursorPosition.y = y;
  361.  
  362. if (GameMath.Equals(playerPosition, cursorPosition))
  363. {
  364. Console.Write("@");
  365. }
  366. else if (bigRatHealth > 0 && GameMath.Equals(bigRatPosition, cursorPosition))
  367. {
  368. Console.Write("R");
  369. }
  370. else if (cougarHealth > 0 && GameMath.Equals(cougarPosition, cursorPosition))
  371. {
  372. Console.Write("C");
  373. }
  374. else
  375. {
  376. Console.Write(".");
  377. }
  378. }
  379. Console.WriteLine();
  380. }
  381.  
  382.  
  383.  
  384. if (cougarHit)
  385. {
  386. if (cougarHealth > 0)
  387. {
  388. Console.WriteLine("Cougar was barely hurt");
  389. }
  390. }
  391.  
  392. if (playerGainedXP)
  393. {
  394. Console.WriteLine("Player gained 5 XP");
  395. }
  396.  
  397. for (int i = 0; i < messageCount; i++) {
  398. messages[i].PrintMessage();
  399. }
  400. }
  401. }
  402. }
  403.  
  404. class MyRandom
  405. {
  406. int seed;
  407. int state;
  408.  
  409. int multiplier = 98765;
  410. int increment = 100554387;
  411.  
  412. // Only seed once per instance of class
  413. // public means that other "calling sites" can look
  414. // at the variable, or use the function, or change
  415. // the value of the variable, etc
  416. public void Seed(int n)
  417. {
  418. seed = n;
  419. state = seed;
  420. }
  421.  
  422. public int Random()
  423. {
  424. state = state * multiplier + increment;
  425.  
  426. int result = state;
  427.  
  428. // Since it right shifts and only 0s will fill in the left
  429. // 1000 >> 3 = 0001
  430. // this number is guaranteed(?) to be non-negative so keep in mind
  431. //return (result >> 16) & 0x7FFF;
  432. return result;
  433. }
  434.  
  435. // Method/function overloading is when the functions share the same name
  436. // but take different arguments
  437. public int Random(int upperLimit)
  438. {
  439. int result = Random() % upperLimit;
  440.  
  441. return result;
  442. }
  443.  
  444. // Note that this upper limit is exclusive, not inclusive
  445. public int Random(int lowerLimit, int upperLimit)
  446. {
  447. int range = upperLimit - lowerLimit;
  448. int result = lowerLimit + (Random() % range);
  449.  
  450. if (result < lowerLimit)
  451. {
  452. result += range;
  453. }
  454.  
  455. return result;
  456. }
  457.  
  458. // six sided dice RandomInclusive(1, 6);
  459. public int RandomInclusive(int lowerLimit, int upperLimit)
  460. {
  461. return Random(lowerLimit, upperLimit + 1);
  462. }
  463. }
  464.  
  465. class Program
  466. {
  467. static void Main(string[] args)
  468. {
  469. Game game = new Game();
  470. game.Update();
  471. }
  472. }
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement