Game for OLC Code Jam 2022
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. const $ = (s) => document.querySelector(s);
  2. const $$ = (s) => Array.from(document.querySelectorAll(s));
  3. const ROOT = $('#root');
  4. const CANVAS = $('#canvas');
  5. const CTX = CANVAS.getContext('2d');
  6. const X_BOUND = 0.05;
  7. const GAME_OVER_BOUND = 0.9;
  8. const MAX_RAINDROPS = 100;
  9. const clouds = new Set();
  10. const bullets = new Set();
  11. const raindrops = new Set();
  12. let shootingPad = new ShootingPad();
  13. let running = true;
  14. let direction = 1;
  15. const initCloudField = () => {
  16. for (let y = 0; y < 6; y++) {
  17. for (let x = 0; x < 11; x++) {
  18. const cloud = new Cloud(X_BOUND + 0.06 * x, 0.04 + 0.06 * y, 0.03, 0.02);
  19. clouds.add(cloud);
  20. }
  21. }
  22. }
  23. const initRainEffect = () => {
  24. noise.seed(Math.random());
  25. for (let i = 0; i < MAX_RAINDROPS; i++) {
  26. const raindrop = new BackgroundRaindrop(
  27. randRange(-0.5, 1.5),
  28. randRange(-1, -0.1),
  29. randRange(0.01, 0.03),
  30. );
  31. raindrops.add(raindrop);
  32. }
  33. }
  34. const start = () => {
  35. $('.result')?.remove();
  36. shootingPad?.destroy();
  37. shootingPad = new ShootingPad();
  38. bullets.forEach(c => c.destroy());
  39. bullets.clear();
  40. clouds.forEach(c => c.destroy());
  41. clouds.clear();
  42. Cloud.reset();
  43. initCloudField();
  44. running = true;
  45. loop();
  46. }
  47. const gameOver = (result) => {
  48. const resultLabel = document.createElement('div');
  49. resultLabel.className = 'result';
  50. resultLabel.textContent = result;
  51. ROOT.appendChild(resultLabel);
  52. running = false;
  53. }
  54. const loop = () => {
  55. if (!running) return;
  56. document.title = `${fps()} FPS | CloudInvaders | OLC Codejam 2022`;
  57. CTX.clearRect(0, 0, CANVAS.width, CANVAS.height);
  58. let directionUpdated = false;
  59. let isOver = false;
  60. Array.from(clouds).forEach(c => {
  61. c.update(direction);
  62. c.draw();
  63. if (c.x < X_BOUND || c.x > 1 - X_BOUND) {
  64. directionUpdated = true;
  65. }
  66. if (c.y >= GAME_OVER_BOUND) {
  67. isOver = true;
  68. }
  69. if (!c.alive) {
  70. clouds.delete(c);
  71. }
  72. });
  73. if (directionUpdated) {
  74. direction = -direction;
  75. }
  76. if (isOver) {
  77. gameOver('Game over');
  78. }
  79. Array.from(bullets).forEach(b => {
  80. b.update();
  81. b.draw();
  82. if (!b.alive) {
  83. bullets.delete(b);
  84. }
  85. });
  86. raindrops.forEach(d => {
  87. d.update();
  88. d.draw();
  89. });
  90. shootingPad.update();
  91. shootingPad.draw();
  92. if (clouds.size === 0) {
  93. gameOver('WIN');
  94. }
  95. requestAnimationFrame(loop);
  96. };
  97. document.addEventListener('keypress', () => {
  98. if (!running) {
  99. start();
  100. }
  101. });
  102. initRainEffect();
  103. start();