From b2ba582cecac45cbea3af998ace0d6b4b958ced1 Mon Sep 17 00:00:00 2001 From: hkri Date: Sun, 25 Jul 2021 22:26:58 +0800 Subject: [PATCH] Add initial codes. --- README.md | 12 +++ dist/app.css | 115 ++++++++++++++++++++++ dist/app.js | 249 ++++++++++++++++++++++++++++++++++++++++++++++++ dist/index.html | 34 +++++++ screenshot.png | Bin 0 -> 22586 bytes 5 files changed, 410 insertions(+) create mode 100644 README.md create mode 100644 dist/app.css create mode 100644 dist/app.js create mode 100644 dist/index.html create mode 100644 screenshot.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d7b8f5 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Number Slide + +Simple number slide game using HTML and vanila JavaScript. + +
+ +
+ +## Development + +- Open `index.html` on a modern browser. +- Edit the files on your favorite text editor. \ No newline at end of file diff --git a/dist/app.css b/dist/app.css new file mode 100644 index 0000000..d5a472a --- /dev/null +++ b/dist/app.css @@ -0,0 +1,115 @@ +body { + padding: 0; + margin: 0; + background-color: rgb(240, 240, 244); + font-family: sans-serif; +} + +main { + background-color: rgb(230, 230, 234); + border-radius: 8px; +} + +h1 { + font-size: 2.5em; + color: rgb(57, 57, 61); + margin: 0; + width: 100%; +} + +footer { + text-align: center; + font-size: 12px; + color: rgb(110, 110, 114); + text-transform: uppercase; +} + +footer a { + color: rgb(110, 110, 114); + text-decoration: none; +} + +footer a:hover { + text-decoration: underline; +} + +#wrapper { + margin: 0 auto; + max-width: 500px; + width: 100%; + margin: 0 auto; + padding: 0 2em; + box-sizing: border-box; +} + +#controls { + display: flex; + margin: 2em 0 1em 0; + justify-content: center; + align-items: center; +} + +#controls button { + background-color: rgb(220, 220, 224); + border: 0; + border-radius: 6px; + padding: 0.7em 1.5em; + transition: all 0.12s ease-out; +} + +#controls button:not([disabled]):hover { + cursor: pointer; + background-color: #04bbd9; + color: white; +} + +#stage { + margin: 4em auto 6em auto; +} + +#stage section { + width: 100%; + min-height: 130px; + border-radius: 8px; + position: relative; + display: grid; + grid-template-columns: [c1] 33.33% [c2] 33.33% [c3] 33.33% [c-end]; + grid-template-rows: [r1] 33.33% [r2] 33.33% [r3] 33.33% [r-end]; + filter: drop-shadow(0 0 8px rgba(0, 0, 0, 0.15)); +} + +#stage button { + margin: 0; + padding: 0; + font-size: 3em; + background: rgb(250, 250, 252); + color: rgb(50, 50, 55); + overflow: hidden; + transition: transform 0.12s ease-out, background-color 0.12s ease-out; + border-radius: 8px; + border: 1px solid rgb(198, 198, 201); + grid-column-start: c1; + grid-row-start: r1; + z-index: 1; +} + +#stage button.fast { + transition: transform 0.08s ease-out; +} + +#stage.done button[disabled] { + background-color: #20a076; + color: white; +} + +.c1.r1 { transform: translate(0, 0); } +.c1.r2 { transform: translate(0, 100%); } +.c1.r3 { transform: translate(0, 200%); } + +.c2.r1 { transform: translate(100%, 0); } +.c2.r2 { transform: translate(100%, 100%); } +.c2.r3 { transform: translate(100%, 200%); } + +.c3.r1 { transform: translate(200%, 0); } +.c3.r2 { transform: translate(200%, 100%); } +.c3.r3 { transform: translate(200%, 200%); } \ No newline at end of file diff --git a/dist/app.js b/dist/app.js new file mode 100644 index 0000000..cb45723 --- /dev/null +++ b/dist/app.js @@ -0,0 +1,249 @@ +var grid = [1, 2, 3, 4, 5, 6, 7, 8, 0 ]; +var COLS = 3; +var ROWS = grid.length / COLS; +var SHUFFLES = 35; + +var MOV_LEFT = 0; +var MOV_RIGHT = 1; +var MOV_UP = 2; +var MOV_DOWN = 3; + +var tiles = document.querySelectorAll('#stage button'); +var textTime = document.getElementById('time'); +var buttonShuffle = document.getElementById('shuffle'); +var stage = document.getElementById('stage'); +var stageSection = document.querySelector('#stage section'); +var wrapper = document.getElementById('wrapper'); + +var timer = null; +var startTime = 0; + +function getRow(index) { + return Math.floor(index / COLS); +} + +function getCol(index) { + return (index % COLS); +} + +function render() { + grid.forEach(function (value, index) { + var col = getCol(index) + 1; + var row = getRow(index) + 1; + var element = document.getElementById(value); + if (element === null) { + return; + } + element.classList.remove('c1', 'c2', 'c3', 'r1', 'r2', 'r3'); + element.classList.add('c' + col, 'r' + row); + }); +} + +function swap(a, b) { + var tmp = grid[a]; + grid[a] = grid[b]; + grid[b] = tmp; +} + +function getSpacePossibleMoves(reverseDir) { + var index = grid.indexOf(0); + var possibleMoves = new Set([MOV_LEFT, MOV_RIGHT, MOV_UP, MOV_DOWN]); + if (index % COLS == COLS - 1) + possibleMoves.delete(MOV_RIGHT); + if (index % COLS == 0) + possibleMoves.delete(MOV_LEFT); + if (Math.floor(index / ROWS) == 0) + possibleMoves.delete(MOV_UP); + if (Math.floor(index / ROWS) == ROWS - 1) + possibleMoves.delete(MOV_DOWN); + possibleMoves.delete(reverseDir); + return Array.from(possibleMoves); +} + +function moveSpace(direction) { + var index = grid.indexOf(0); + var step = 0; + switch (direction) { + case MOV_LEFT: case MOV_UP: + step = -1; + break; + case MOV_RIGHT: case MOV_DOWN: + step = 1; + break; + default: + step = 0; + } + if ([MOV_LEFT, MOV_RIGHT].indexOf(direction) > -1) { + // horizontal + var inc = index + step; + if (inc < 2 || inc >= 0) { + swap(index, inc); + } + } else { + // vertical + var inc = index + (ROWS * step); + if (inc < grid.length || inc >= 0) { + swap(index, inc); + } + } + render(); +} + +function moveHorizontal(index) { + var col = getCol(index); + if (col == 0) { + if (grid[index + 1] == 0) + swap(index, index + 1); + } else if (col == COLS - 1) { + if (grid[index - 1] == 0) + swap(index, index - 1); + } else { + if (grid[index + 1] == 0) + swap(index, index + 1); + else if (grid[index - 1] == 0) + swap(index, index - 1); + } +} + +function moveVertical(index) { + var row = getRow(index); + if (row == 0) { + if (grid[index + ROWS] == 0) + swap(index, index + ROWS); + } else if (row == ROWS - 1) { + if (grid[index - ROWS] == 0) + swap(index, index - ROWS); + } else { + if (grid[index + ROWS] == 0) + swap(index, index + ROWS); + else if (grid[index - ROWS] == 0) + swap(index, index - ROWS); + } +} + +function shuffle(steps) { + var i = 0; + var prevDir = -1; + tiles.forEach(function (tile) { + tile.classList.add('fast'); + }); + var loop = setInterval(function () { + var reverseDir = -1; + if (prevDir == MOV_DOWN) + reverseDir = MOV_UP; + if (prevDir == MOV_UP) + reverseDir = MOV_DOWN; + if (prevDir == MOV_LEFT) + reverseDir = MOV_RIGHT; + if (prevDir == MOV_RIGHT) + reverseDir = MOV_LEFT; + var possibleMoves = getSpacePossibleMoves(reverseDir); + var dir = possibleMoves[Math.floor(Math.random() * possibleMoves.length)]; + moveSpace(dir); + prevDir = dir; + i++; + if (i >= steps) { + clearInterval(loop); + enableTiles(); + document.getElementById('stage').classList.remove('done'); + buttonShuffle.disabled = false; + tiles.forEach(function (tile) { + tile.classList.remove('fast'); + }); + return; + } + }, 90); + disableTiles(); + buttonShuffle.disabled = true; +} + +function formatTime(time) { + var minutes = Math.floor(time / 60).toString().padStart(2, '0'); + var seconds = Math.floor(time % 60).toString().padStart(2, '0'); + var millis = Math.floor((time % 1) * 100).toString().padStart(2, '0'); + return minutes + ':' + seconds + '.' + millis + ''; +} + +function startTimer() { + if (timer !== null) { + return; + } + startTime = (new Date()).getTime(); + timer = setInterval(function () { + var diff = ((new Date()).getTime() - startTime) / 1000; + textTime.innerHTML = formatTime(diff); + }, 16); +} + +function stopTimer() { + clearInterval(timer); + timer = null; +} + +function resetTimer() { + stopTimer(); + startTime = 0; + textTime.innerHTML = formatTime(0); +} + +function checkCompleted() { + for (var i = 0; i < grid.length - 2; ++i) { + if (grid[i + 1] < grid[i]) { + return; + } + } + document.getElementById('stage').classList.add('done'); + disableTiles(); + stopTimer(); +} + +function disableTiles() { + tiles.forEach(function (button) { + button.disabled = true; + }); +} + +function enableTiles() { + tiles.forEach(function (button) { + button.disabled = false; + }); +} + +function resizeStage() { + var wrapperStyle = getComputedStyle(wrapper); + var paddingLeft = parseInt(wrapperStyle.getPropertyValue('padding-left')); + var paddingRight = parseInt(wrapperStyle.getPropertyValue('padding-right')); + var width = parseInt(wrapperStyle.getPropertyValue('width')); + var adjustedWidth = width - paddingLeft - paddingRight; + while (adjustedWidth % 3 != 0) { + adjustedWidth--; + } + stage.style.fontSize = (adjustedWidth / 24) + 'px'; + stage.style.width = adjustedWidth + 'px'; + stageSection.style.height = adjustedWidth + 'px'; +} + +tiles.forEach(function (button) { + button.onclick = function (e) { + var tileId = e.target.id; + var index = grid.indexOf(parseInt(tileId)); + moveHorizontal(index); + moveVertical(index); + render(); + startTimer(); + checkCompleted(); + } +}); + +buttonShuffle.onclick = function () { + resetTimer(); + shuffle(SHUFFLES); +} + +window.onload = function () { + resizeStage(); + render(); + shuffle(SHUFFLES); +}; + +window.onresize = resizeStage; diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 0000000..c989ea7 --- /dev/null +++ b/dist/index.html @@ -0,0 +1,34 @@ + + + + + + + + Number Slide + + +
+
+

00:00.00

+ +
+
+
+ + + + + + + + +
+
+ +
+ + + \ No newline at end of file diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c4fe0cce87b4d386af88b8927283fc86b27d55fe GIT binary patch literal 22586 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