script.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. //document.addEventListener("DOMContentLoaded", main, false);
  2. const startGameButton = document.getElementById("start-game-button");
  3. const currentScoreElement = document.getElementById("current-score");
  4. const finalScoreElement = document.getElementById("final-score");
  5. const canvas = document.getElementById("game-canvas");
  6. const context = canvas.getContext("2d");
  7. canvas.width = window.innerWidth;
  8. canvas.height = window.innerHeight;
  9. const gameOverContainer = document.getElementById("game-over-container-div");
  10. /* utilities */
  11. function colorToStyle(r, g, b, a) {
  12. return "rgb(" + r + ", " + g + ", " + b + ", " + a + ")";
  13. }
  14. /* WASM imported symbols */
  15. function jsRandom() {
  16. return Math.random();
  17. }
  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. // Lots of jsConsole<type> functions. Leaving it here until I find a better way to print to console from wasm.
  40. function jsConsoleLogu32(n) {
  41. console.log("u32: " + n);
  42. }
  43. function jsConsoleLogf32(n) {
  44. console.log("f32: " + n);
  45. }
  46. function jsConsoleLogbool(b) {
  47. console.log("bool: " + b);
  48. }
  49. function jsConsoleLogVector2D(x, y) {
  50. console.log("{x: " + x + ", y:" + y + "}");
  51. }
  52. // See build.zig for reasoning
  53. var memory = new WebAssembly.Memory({
  54. initial: 17 /* pages */,
  55. maximum: 17 /* pages */,
  56. });
  57. const wasm = {
  58. imports: {
  59. env: {
  60. jsRandom: jsRandom,
  61. jsClearRectangle: jsClearRectangle,
  62. jsDrawCircle: jsDrawCircle,
  63. jsDrawRectangle: jsDrawRectangle,
  64. jsUpdateScore: jsUpdateScore,
  65. jsConsoleLogu32: jsConsoleLogu32,
  66. jsConsoleLogf32: jsConsoleLogf32,
  67. jsConsoleLogbool: jsConsoleLogbool,
  68. jsConsoleLogVector2D: jsConsoleLogVector2D,
  69. memory: memory,
  70. },
  71. },
  72. exports: {},
  73. };
  74. function loadGame() {
  75. WebAssembly.instantiateStreaming(fetch("zig-out/bin/DodgeBallz.wasm"), wasm.imports).then((result) => {
  76. wasm.exports = result.instance.exports;
  77. window.addEventListener("keydown", (event) => {
  78. const key = event.key;
  79. const char = key.charCodeAt(0);
  80. wasm.exports.key_down(char);
  81. });
  82. window.addEventListener("keyup", (event) => {
  83. const key = event.key;
  84. const char = key.charCodeAt(0);
  85. wasm.exports.key_up(char);
  86. });
  87. window.addEventListener("click", (event) => {
  88. const client_x = event.clientX;
  89. const client_y = event.clientY;
  90. wasm.exports.shoot_projectile(client_x, client_y);
  91. });
  92. startGameButton.addEventListener("click", (event) => {
  93. restartGame();
  94. });
  95. wasm.exports.game_init(canvas.width, canvas.height);
  96. restartGame();
  97. // gameOverContainer.style.display = "flex";
  98. });
  99. }
  100. function resetGame() {
  101. currentScoreElement.innerHTML = 0;
  102. gameOverContainer.style.display = "none";
  103. wasm.exports.game_reset();
  104. }
  105. function runGame() {
  106. wasm.exports.game_step();
  107. if (!wasm.exports.is_game_over()) {
  108. window.requestAnimationFrame(runGame);
  109. } else {
  110. // If the game is over, show the Game Over container (with the start buttong) and the achieved score.
  111. gameOverContainer.style.display = "flex";
  112. finalScoreElement.innerHTML = wasm.exports.get_score();
  113. }
  114. }
  115. function restartGame() {
  116. resetGame();
  117. // Set the rate at which the enemies will be spawned.
  118. setInterval(wasm.exports.spawn_enemy, 500);
  119. runGame();
  120. }
  121. function main() {
  122. loadGame();
  123. }
  124. main();