Jeu de démineur sur navigateur avec p5.js
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

sketch.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. var COLS;
  2. var ROWS;
  3. var MINES;
  4. var W;
  5. const GAME_STATE = {
  6. DEFEAT: 1,
  7. VICTORY: 2,
  8. ONGOING: 3,
  9. STOPPED: 4
  10. }
  11. function setup() {
  12. newGame();
  13. }
  14. function newGame() {
  15. let params = gatherMenuValues();
  16. COLS = params.COLUMNS;
  17. ROWS = params.ROWS;
  18. MINES = params.MINES;
  19. W = params.CELLSIZE;
  20. console.log(COLS, ROWS, MINES);
  21. this.grid = new Grid(COLS, ROWS, MINES);
  22. this.nbCellsToWin = COLS * ROWS - MINES;
  23. this.gamestate = GAME_STATE.ONGOING;
  24. createCanvas(COLS * W, ROWS * W);
  25. //resizeCanvas(COLS * W, ROWS * W);
  26. needUpdate = true;
  27. }
  28. function mousePressed(e) {
  29. if (this.gamestate != GAME_STATE.ONGOING) return;
  30. let cellX = floor(mouseX / W);
  31. let cellY = floor(mouseY / W);
  32. if (!this.grid.inbounds(cellX, cellY)) return;
  33. let clickedCell = this.grid.cell(cellX, cellY);
  34. if (mouseButton === LEFT) {
  35. handleLeftClickAtCell(clickedCell);
  36. }
  37. if (mouseButton === RIGHT) {
  38. clickedCell.toggleFlag();
  39. }
  40. needUpdate = true;
  41. return false;
  42. }
  43. function gatherMenuValues() {
  44. let menu_columns = parseInt(document.getElementById("columns").value);
  45. let menu_rows = parseInt(document.getElementById("rows").value);
  46. let menu_mines = parseInt(document.getElementById("mines").value);
  47. let menu_cellsize = parseInt(document.getElementById("cellsize").value);
  48. return {
  49. COLUMNS: menu_columns,
  50. ROWS: menu_rows,
  51. MINES: menu_mines,
  52. CELLSIZE: menu_cellsize
  53. };
  54. }
  55. function handleLeftClickAtCell(cell) {
  56. let nbRevealed = this.grid.revealCell(cell);
  57. if (nbRevealed == -1) { // hit mine
  58. defeat();
  59. return;
  60. }
  61. this.nbCellsToWin -= nbRevealed;
  62. if (this.nbCellsToWin == 0) {
  63. victory();
  64. }
  65. }
  66. function victory() {
  67. grid.fullReveal();
  68. this.gamestate = GAME_STATE.VICTORY;
  69. }
  70. function defeat() {
  71. grid.fullReveal();
  72. this.gamestate = GAME_STATE.DEFEAT;
  73. }
  74. function displayMessage(message, color) {
  75. textSize(W);
  76. textAlign(CENTER, CENTER);
  77. fill(200);
  78. stroke(1);
  79. strokeWeight(2);
  80. let textW = textWidth(message);
  81. let textH = textAscent(message);
  82. let padding = 10;
  83. rect (
  84. width / 2 - padding,
  85. height / 2 - textH / 2 - padding,
  86. 2 * padding + textW,
  87. 2 * padding + textH
  88. );
  89. noFill();
  90. noStroke();
  91. fill(color);
  92. text(message, width / 2 + textW / 2, height / 2);
  93. }
  94. function displayVictoryMessage() {
  95. displayMessage('Victory !', 'green');
  96. }
  97. function displayDefeatMessage() {
  98. displayMessage('Perdu !', 'red');
  99. }
  100. var needUpdate = true; // optimization trick
  101. function draw() {
  102. if (!needUpdate) return;
  103. background(0);
  104. drawGrid();
  105. if (this.gamestate == GAME_STATE.DEFEAT) displayDefeatMessage();
  106. if (this.gamestate == GAME_STATE.VICTORY) displayVictoryMessage();
  107. needUpdate = false;
  108. }
  109. function drawGrid() {
  110. for (let i = 0; i < COLS; i++) {
  111. for (let j = 0; j < ROWS; j++) {
  112. drawCell(this.grid.cell(i, j));
  113. }
  114. }
  115. }
  116. function drawCell(cell) {
  117. if (cell.revealed) {
  118. drawRevealedCell(cell)
  119. } else {
  120. drawHiddenCell(cell);
  121. }
  122. }
  123. function drawRevealedCell(cell) {
  124. let drawX = cell.x * W;
  125. let drawY = cell.y * W;
  126. fill(255);
  127. strokeWeight(0);
  128. rect (drawX, drawY, W, W);
  129. if (cell.hasMine) {
  130. drawMine(drawX, drawY, W);
  131. }
  132. if (cell.weight > 0) {
  133. drawCellMinesNumber(cell);
  134. }
  135. }
  136. function drawCellMinesNumber(cell) {
  137. let drawX = cell.x * W;
  138. let drawY = cell.y * W;
  139. textAlign(CENTER, CENTER);
  140. textSize(W / 2);
  141. fill(0);
  142. text (cell.weight, drawX, drawY, W, W);
  143. }
  144. function drawHiddenCell(cell) {
  145. let drawX = cell.x * W;
  146. let drawY = cell.y * W;
  147. stroke(0);
  148. strokeWeight(1);
  149. fill(155);
  150. rect (drawX, drawY, W, W);
  151. if (cell.flagged) {
  152. drawFlag(drawX, drawY, W);
  153. }
  154. }
  155. function drawFlag(x, y, w) {
  156. stroke(0);
  157. strokeWeight(1);
  158. line (
  159. x + w * 0.3,
  160. y + w * 0.2,
  161. x + w * 0.3,
  162. y + w * 0.8,
  163. );
  164. fill('red');
  165. triangle(
  166. x + w * 0.3,
  167. y + w * 0.2,
  168. x + w * 0.7,
  169. y + w * 0.35,
  170. x + w * 0.3,
  171. y + w * 0.5
  172. );
  173. }
  174. let sin60 = Math.sin(Math.PI / 3); // optimization
  175. function drawMine(x, y, w) {
  176. let r = w * 0.4;
  177. stroke(0);
  178. strokeWeight(1);
  179. fill(0);
  180. circle (
  181. r * 1.2 + x,
  182. r * 1.2 + y,
  183. r * 1.4
  184. );
  185. triangle(
  186. r * 1.7 + x, r * (sin60 + 1.2) + y,
  187. r * 1.7 + x, r * (1.2 - sin60) + y,
  188. r * 0.2 + x, r * 1.2 + y
  189. );
  190. triangle (
  191. r * 0.7 + x, r * (sin60 + 1.2) + y,
  192. r * 0.7 + x, r * (1.2 - sin60) + y,
  193. r * 2.2 + x, r * 1.2 + y
  194. );
  195. }