script.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. const text_decoder = new TextDecoder();
  2. let console_log_buffer = "";
  3. const startGameButton = document.getElementById("start-game-button");
  4. const currentScoreElement = document.getElementById("current-score");
  5. const finalScoreElement = document.getElementById("final-score");
  6. const canvas = document.getElementById("game-canvas");
  7. const context = canvas.getContext("2d");
  8. //canvas.width = window.innerWidth;
  9. //canvas.height = window.innerHeight;
  10. canvas.width = window.innerWidth - 10; // todo think why got scrollbars
  11. canvas.height = window.innerHeight - 10;
  12. const gameOverContainer = document.getElementById("game-over-container-div");
  13. /* utilities */
  14. function colorToStyle(r, g, b, a) {
  15. return "rgb(" + r + ", " + g + ", " + b + ", " + a + ")";
  16. }
  17. /* WASM imported symbols */
  18. function jsClearRectangle(x, y, width, height) {
  19. // context.clearRect(x, y, width, height);
  20. context.fillStyle = "rgba(0, 0, 0, .1)";
  21. context.fillRect(x, y, width, height);
  22. }
  23. function jsDrawCircle(x, y, radius, r, g, b, a) {
  24. context.beginPath();
  25. context.arc(x, y, radius, 0, Math.PI * 2);
  26. context.fillStyle = colorToStyle(r, g, b, a);
  27. context.fill();
  28. }
  29. function jsDrawRectangle(x, y, width, height, r, g, b, a) {
  30. context.beginPath();
  31. context.strokeRect(x, y, width, height);
  32. context.fillStyle = colorToStyle(r, g, b, a);
  33. context.lineWidth = 5;
  34. context.fill();
  35. }
  36. function jsUpdateScore(score) {
  37. currentScoreElement.innerHTML = score;
  38. }
  39. // See build.zig for reasoning
  40. var memory = new WebAssembly.Memory({
  41. initial: 17 /* pages */,
  42. maximum: 17 /* pages */,
  43. });
  44. const wasm = {
  45. imports: {
  46. env: {
  47. jsRandom: function () {
  48. return Math.random();
  49. },
  50. jsClearRectangle: jsClearRectangle,
  51. jsDrawCircle: jsDrawCircle,
  52. jsDrawRectangle: jsDrawRectangle,
  53. jsUpdateScore: jsUpdateScore,
  54. jsConsoleLogWrite: function (ptr, len) {
  55. const str = text_decoder.decode(new Uint8Array(memory.buffer, ptr, len));
  56. console_log_buffer += str;
  57. },
  58. jsConsoleLogFlush: function () {
  59. console.log(console_log_buffer);
  60. console_log_buffer = "";
  61. },
  62. memory: memory,
  63. },
  64. },
  65. exports: {},
  66. };
  67. function loadGame() {
  68. WebAssembly.instantiateStreaming(fetch("zig-out/bin/DodgeBallz.wasm"), wasm.imports).then((result) => {
  69. wasm.exports = result.instance.exports;
  70. window.addEventListener("keydown", (event) => {
  71. const key = event.key;
  72. const char = key.charCodeAt(0);
  73. wasm.exports.key_down(char);
  74. });
  75. window.addEventListener("keyup", (event) => {
  76. const key = event.key;
  77. const char = key.charCodeAt(0);
  78. wasm.exports.key_up(char);
  79. });
  80. window.addEventListener("click", (event) => {
  81. const client_x = event.clientX;
  82. const client_y = event.clientY;
  83. wasm.exports.shoot_projectile(client_x, client_y);
  84. });
  85. startGameButton.addEventListener("click", (event) => {
  86. restartGame();
  87. });
  88. wasm.exports.game_init(canvas.width, canvas.height);
  89. restartGame();
  90. // gameOverContainer.style.display = "flex";
  91. });
  92. }
  93. function resetGame() {
  94. currentScoreElement.innerHTML = 0;
  95. gameOverContainer.style.display = "none";
  96. wasm.exports.game_reset();
  97. }
  98. function runGame() {
  99. wasm.exports.game_step();
  100. if (!wasm.exports.is_game_over()) {
  101. window.requestAnimationFrame(runGame);
  102. } else {
  103. // If the game is over, show the Game Over container (with the start buttong) and the achieved score.
  104. gameOverContainer.style.display = "flex";
  105. finalScoreElement.innerHTML = wasm.exports.get_score();
  106. }
  107. }
  108. function restartGame() {
  109. resetGame();
  110. // Set the rate at which the enemies will be spawned.
  111. setInterval(wasm.exports.spawn_enemy, 500);
  112. runGame();
  113. }
  114. function main() {
  115. loadGame();
  116. }
  117. main();