JavaScriptで数字タッチゲーム

この記事を書いている人 - WRITER -
http://mukuchan.com/dotinstall/js/touchgame/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Numbers Game</title> <link rel="stylesheet" href="styles.css"> </head> <body> <div id="container"> <div id="timer">0.0</div> <ul id="board"> </ul> <div id="btn">START</div> </div> <script src="main.js"></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
'use strict'; { class Panel { constructor(game) { this.game = game; this.el = document.createElement('li'); this.el.classList.add('pressed'); this.el.addEventListener('click', () => { this.check(); }); } getEl() { return this.el; } activate(num) { this.el.classList.remove('pressed'); this.el.textContent = num; } check() { if (this.game.getCurrentNum() === parseInt(this.el.textContent, 10)) { this.el.classList.add('pressed'); this.game.addCurrentNum(); if (this.game.getCurrentNum() === this.game.getLevel() ** 2) { clearTimeout(this.game.getTimeoutId()); } } } } class Board { constructor(game) { this.game = game; this.panels = []; for (let i = 0; i < this.game.getLevel() ** 2; i++) { this.panels.push(new Panel(this.game)); } this.setup(); } setup() { const board = document.getElementById('board'); this.panels.forEach(panel => { board.appendChild(panel.getEl()); }); } activate() { const nums = []; for (let i = 0; i < this.game.getLevel() ** 2; i++) { nums.push(i); } this.panels.forEach(panel => { const num = nums.splice(Math.floor(Math.random() * nums.length), 1)[0]; panel.activate(num); }); } } class Game { constructor(level) { this.level = level; this.board = new Board(this); this.currentNum = undefined; this.startTime = undefined; this.timeoutId = undefined; const btn = document.getElementById('btn'); btn.addEventListener('click', () => { this.start(); }); this.setup(); } setup() { const container = document.getElementById('container'); const PANEL_WIDTH = 50; const BOARD_PADDING = 10; /* 50px * 2 + 10px * 2 */ container.style.width = PANEL_WIDTH * this.level + BOARD_PADDING * 2 + 'px'; } start() { if (typeof this.timeoutId !== 'undefined') { clearTimeout(this.timeoutId); } this.currentNum = 0; this.board.activate(); this.startTime = Date.now(); this.runTimer(); } runTimer() { const timer = document.getElementById('timer'); timer.textContent = ((Date.now() - this.startTime) / 1000).toFixed(2); this.timeoutId = setTimeout(() => { this.runTimer(); }, 10); } addCurrentNum() { this.currentNum++; } getCurrentNum() { return this.currentNum; } getTimeoutId() { return this.timeoutId; } getLevel() { return this.level; } } new Game(5); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
body { background: #ccc; color: #fff; font-family: 'Courier New', sans-serif; font-size: 16px; font-weight: bold; } #container { /* 50px * 2 + 10px * 2 */ margin: 16px auto; } #board { display: flex; flex-wrap: wrap; list-style: none; margin: 0 0 8px; padding: 10px; background: #fff; border-radius: 4px; } #board li { background: #00aaff; width: 40px; height: 40px; margin: 5px; cursor: pointer; border-radius: 4px; line-height: 40px; text-align: center; box-shadow: 0 4px 0 #0088cc; } #board li.pressed { background: #ccc; box-shadow: none; margin-top: 9px; margin-bottom: 1px; } #timer { margin-bottom: 8px; font-size: 20px; text-align: right; } #btn { cursor: pointer; user-select: none; background: #f44336; padding: 8px; border-radius: 4px; text-align: center; box-shadow: 0 4px 0 #d1483e; } #btn:active { margin-top: 12px; box-shadow: none; } |
この記事を書いている人 - WRITER -