first commit, working game, some work to do yet
This commit is contained in:
commit
3bc2b0fe18
17 changed files with 15694 additions and 0 deletions
17
.eslintrc.js
Normal file
17
.eslintrc.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
module.exports = {
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended",
|
||||||
|
"globals": {
|
||||||
|
"Atomics": "readonly",
|
||||||
|
"SharedArrayBuffer": "readonly"
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 2018,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
}
|
||||||
|
};
|
||||||
113
.gitignore
vendored
Normal file
113
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Node template
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# intellij
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# apple
|
||||||
|
.DS_Store
|
||||||
4
README.md
Normal file
4
README.md
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
* remake of word collect (app) without the ads
|
||||||
|
* no demo yet
|
||||||
|
* static html/javascript
|
||||||
|
* pretty hard!
|
||||||
25
index.html
Normal file
25
index.html
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta name="viewport" content="minimal-ui, width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>WordCollector</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<canvas id="canvas" draggable="false">
|
||||||
|
Your browser does not support the canvas element.
|
||||||
|
</canvas>
|
||||||
|
|
||||||
|
<div class="points"><img class="medal" src="src/img/medal.png"><span id="points">0</span></div>
|
||||||
|
<div id="slots">
|
||||||
|
</div>
|
||||||
|
<div id="guess" class="guess"></div>
|
||||||
|
<div class="hint"><img id="hint" alt="hint" src="src/img/hint.png" width="50px"></div>
|
||||||
|
<div class="reload"><img id="reload" alt="shuffle" src="src/img/reload.png" width="50px"></div>
|
||||||
|
<div id="characters"></div>
|
||||||
|
|
||||||
|
<script src="bundle.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
7729
package-lock.json
generated
Normal file
7729
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
25
package.json
Normal file
25
package.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "wordcollector",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"main": "src/js/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"build": "webpack",
|
||||||
|
"watch": "webpack --watch",
|
||||||
|
"start": "webpack-dev-server --open --host 0.0.0.0 --port 80"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"css-loader": "^3.4.2",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-loader": "^3.0.3",
|
||||||
|
"fabric": "^4.0.0-beta.6",
|
||||||
|
"file-loader": "^5.0.2",
|
||||||
|
"jquery": "^3.4.1",
|
||||||
|
"style-loader": "^1.1.3",
|
||||||
|
"webpack": "^4.41.6",
|
||||||
|
"webpack-cli": "^3.3.11",
|
||||||
|
"webpack-dev-server": "^3.10.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
154
src/css/style.css
Normal file
154
src/css/style.css
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
html {
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Quicksand', serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
background: #53a600;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-flow: row-reverse wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.character-tile {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
transform: translate(0, -15%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.medal {
|
||||||
|
height: 1em;
|
||||||
|
transform: translate(-12px, 2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.points {
|
||||||
|
position: absolute;
|
||||||
|
right: 5%;
|
||||||
|
top: 1%;
|
||||||
|
flex-flow: row-reverse wrap;
|
||||||
|
color: yellow;
|
||||||
|
background: black;
|
||||||
|
border: #dab107 2px solid;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding-left: 3px;
|
||||||
|
padding-right: 3px;
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
|
||||||
|
#slots {
|
||||||
|
top: 35px;
|
||||||
|
width: 90%;
|
||||||
|
margin: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row-reverse wrap;
|
||||||
|
border: #f5f1bc solid 15px;
|
||||||
|
border-radius: 15px;
|
||||||
|
background: #f5f1bc;
|
||||||
|
position: absolute;
|
||||||
|
horiz-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wordslot {
|
||||||
|
position: relative;
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
color: brown;
|
||||||
|
}
|
||||||
|
|
||||||
|
.revealed {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.characterslot {
|
||||||
|
vertical-align: center;
|
||||||
|
text-align: center;
|
||||||
|
width: 1.5em;
|
||||||
|
height: 1.5em;
|
||||||
|
background: brown;
|
||||||
|
border: black solid .5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tile {
|
||||||
|
position: absolute;
|
||||||
|
background: url("../img/wood.jpg");
|
||||||
|
width: 18vw;
|
||||||
|
height: 10vh;
|
||||||
|
max-width: 75px;
|
||||||
|
text-align: center;
|
||||||
|
color: rgb(99, 28, 28);
|
||||||
|
border: solid beige 1px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 1), 0 0 40px rgba(255, 255, 0, 0.2) inset;
|
||||||
|
font-size: 10vh;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guess {
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
visibility: hidden;
|
||||||
|
background: #f5f1bc;
|
||||||
|
position: absolute;
|
||||||
|
top: 37%;
|
||||||
|
left: 40%;
|
||||||
|
display: inline-block;
|
||||||
|
height: 11vh;
|
||||||
|
text-align: center;
|
||||||
|
color: black;
|
||||||
|
border: solid beige 2px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 1), 0 0 40px rgba(100,100,100, 0.1) inset;
|
||||||
|
font-size: 7vh;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shown {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
border-width: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Quicksand';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url(../font/quicksand.woff) format('woff');
|
||||||
|
}
|
||||||
|
|
||||||
|
.reload {
|
||||||
|
padding: 5px;
|
||||||
|
position: absolute;
|
||||||
|
top: 40%;
|
||||||
|
right: 5%;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
padding: 5px;
|
||||||
|
position: absolute;
|
||||||
|
top: 40%;
|
||||||
|
left: 5%;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
1525
src/data/wordcombis4.json.disabled
Normal file
1525
src/data/wordcombis4.json.disabled
Normal file
File diff suppressed because it is too large
Load diff
2271
src/data/wordcombis5.json.disabled
Normal file
2271
src/data/wordcombis5.json.disabled
Normal file
File diff suppressed because it is too large
Load diff
3511
src/data/wordcombis6.json
Normal file
3511
src/data/wordcombis6.json
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/font/quicksand.woff
Normal file
BIN
src/font/quicksand.woff
Normal file
Binary file not shown.
BIN
src/img/hint.png
Normal file
BIN
src/img/hint.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
src/img/medal.png
Normal file
BIN
src/img/medal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
BIN
src/img/reload.png
Normal file
BIN
src/img/reload.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
BIN
src/img/wood.jpg
Normal file
BIN
src/img/wood.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
278
src/js/index.js
Normal file
278
src/js/index.js
Normal file
|
|
@ -0,0 +1,278 @@
|
||||||
|
import $ from 'jquery';
|
||||||
|
import '../css/style.css';
|
||||||
|
import {fabric} from 'fabric';
|
||||||
|
import data from '../data/wordcombis6.json';
|
||||||
|
|
||||||
|
new function () {
|
||||||
|
const characterTiles = document.getElementsByClassName('tile'); //
|
||||||
|
|
||||||
|
let lines = []; //lines connecting the letters
|
||||||
|
let activeLine; //the line that moves with the pointer
|
||||||
|
let screenMiddle;
|
||||||
|
let words, // the words to guess
|
||||||
|
characters, // the letters to choose from
|
||||||
|
guess = "", // the current guess
|
||||||
|
points = 0;
|
||||||
|
const canvas = new fabric.Canvas('canvas', {selection: false});
|
||||||
|
|
||||||
|
resize();
|
||||||
|
registerEvents();
|
||||||
|
start();
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
// get new word
|
||||||
|
let challenge = data[Math.floor(Math.random() * data.length)];
|
||||||
|
words = challenge.words;
|
||||||
|
|
||||||
|
// max ten words to guess
|
||||||
|
// TODO put the rest in the extra-word list for bonus points
|
||||||
|
// TODO make sure words of all lengths are guaranteed to be in the list
|
||||||
|
while (words.length > 10) {
|
||||||
|
words.splice(Math.random() * Math.floor(words.length), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
showEmptySlots(); // this is where the guessed words appear
|
||||||
|
|
||||||
|
characters = shuffleLetters(challenge.chars); // random order, otherwise the longest word is to easily visible
|
||||||
|
layoutLetterTiles(); // put them on screen
|
||||||
|
}
|
||||||
|
|
||||||
|
// boxes for the guessed words
|
||||||
|
// TODO nice columnar layout
|
||||||
|
function showEmptySlots() {
|
||||||
|
let slots = $("#slots");
|
||||||
|
slots.children().remove();
|
||||||
|
|
||||||
|
for (let i = words.length - 1; i >= 0; i--) {
|
||||||
|
let word = words[i];
|
||||||
|
let wordSlot = $("<div class='wordslot hidden' id='" + word + "'>");
|
||||||
|
slots.append(wordSlot);
|
||||||
|
|
||||||
|
for (let j = 0; j < word.length; j++) {
|
||||||
|
wordSlot.append($("<div class='characterslot'>").append(word.charAt(j).toUpperCase()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// put all letter tiles in a nice circle
|
||||||
|
function layoutLetterTiles() {
|
||||||
|
let width = $(window).width();
|
||||||
|
let height = $(window).height();
|
||||||
|
let center_x = width / 2.4;
|
||||||
|
let center_y = height / 2.2;
|
||||||
|
|
||||||
|
let angleBetweenChars = 2 * Math.PI / characters.length;
|
||||||
|
|
||||||
|
//remove any characters that were there before
|
||||||
|
$("#characters div").remove();
|
||||||
|
|
||||||
|
// layout new ones in a circle
|
||||||
|
for (let i = 0; i < characters.length; i++) {
|
||||||
|
let radius_x = Math.min((width / 4), 150); // not too wide on big screens
|
||||||
|
|
||||||
|
let x = center_x - radius_x * Math.cos(i * angleBetweenChars) + Math.random();
|
||||||
|
let y = center_y * 1.5 - (height / 6) * Math.sin(i * angleBetweenChars) + Math.random() * 20 - 20;
|
||||||
|
|
||||||
|
// make visible
|
||||||
|
let span = $("<span class='character-tile' id='" + i + "-" + characters[i] + "'>");
|
||||||
|
span.append(characters[i].toUpperCase());
|
||||||
|
let div = $("<div class='tile' style='top:" + y + "px;left:" + x + "px;transform: rotate(" + (Math.random() * 8 - 4) + "deg)'>");
|
||||||
|
div.append(span);
|
||||||
|
$("#characters").append(div);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerEvents() {
|
||||||
|
$(window).resize(function () {
|
||||||
|
layoutLetterTiles();
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.on('mouse:down', event => {
|
||||||
|
if (!activeLine) {
|
||||||
|
addLineToCanvas(event);
|
||||||
|
updatePointer(event);
|
||||||
|
} else {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.on('mouse:up', () => {
|
||||||
|
checkGuess();
|
||||||
|
reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.on('mouse:move', updatePointer);
|
||||||
|
|
||||||
|
$("#reload").on("click", () => {
|
||||||
|
characters = shuffleLetters(characters);
|
||||||
|
layoutLetterTiles();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#hint").on("click", () => {
|
||||||
|
showHint();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkGuess() {
|
||||||
|
if (guess.length > 0) {
|
||||||
|
// if the guess is correct, the word will light up
|
||||||
|
$("#" + guess).attr("class", "wordslot revealed");
|
||||||
|
|
||||||
|
// check if all words are found
|
||||||
|
for (let i = 0; i < words.length; i++) {
|
||||||
|
if (guess === words[i]) {
|
||||||
|
|
||||||
|
//update points
|
||||||
|
points += guess.length;
|
||||||
|
$("#points").text(points);
|
||||||
|
|
||||||
|
//remove word from words to guess
|
||||||
|
words.splice(words.indexOf(guess), 1);
|
||||||
|
if (words.length === 0) {
|
||||||
|
start(); //restart
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePointer(event) {
|
||||||
|
if (activeLine) {
|
||||||
|
let pointer = canvas.getPointer(event.e, false);
|
||||||
|
|
||||||
|
//move current line to mouse pointer
|
||||||
|
activeLine.set({x2: pointer.x, y2: pointer.y});
|
||||||
|
|
||||||
|
// check for hits
|
||||||
|
for (let ix = 0; ix < characterTiles.length; ix++) {
|
||||||
|
let tile = characterTiles[ix];
|
||||||
|
if (isHit(tile, pointer)) {
|
||||||
|
registerHit(tile, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canvas.renderAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addLineToCanvas(event) {
|
||||||
|
let points = [event.e.layerX, event.e.layerY, event.e.layerX, event.e.layerY];
|
||||||
|
let line = new fabric.Line(points, {
|
||||||
|
strokeWidth: 4,
|
||||||
|
stroke: '#ffffff',
|
||||||
|
opacity: 0.5,
|
||||||
|
hasBorders: false,
|
||||||
|
hasControls: false,
|
||||||
|
selectable: false,
|
||||||
|
evented: false
|
||||||
|
});
|
||||||
|
|
||||||
|
activeLine = line; // the new line becomes the line that moves with the mouse/finger
|
||||||
|
lines.push(line); // register, to be able to remove later
|
||||||
|
|
||||||
|
canvas.add(line); // make visible on canvas
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
// remove visible lines
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
canvas.remove(lines[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty the lines in memory
|
||||||
|
lines = [];
|
||||||
|
|
||||||
|
// reset the activeline, so the gui goes into it's initial state
|
||||||
|
activeLine = null;
|
||||||
|
|
||||||
|
// reset all tiles
|
||||||
|
for (let i = 0; i < characterTiles.length; i++) {
|
||||||
|
characterTiles[i].setAttribute("class", "tile");
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset guess
|
||||||
|
let guessContainer = $("#guess");
|
||||||
|
guessContainer.children().remove();
|
||||||
|
guessContainer.attr("class", "guess");
|
||||||
|
guess = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple collision detection
|
||||||
|
function isHit(tile, pointer) {
|
||||||
|
let tileX = parseInt(tile.style.left.valueOf());
|
||||||
|
let tileY = parseInt(tile.style.top.valueOf());
|
||||||
|
let dx = pointer.x - tileX;
|
||||||
|
let dy = pointer.y + screenMiddle - tileY;
|
||||||
|
|
||||||
|
return dx > 10 && dx < 80 && dy > 10 && dy < 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerHit(tile, event) {
|
||||||
|
if (notHitAlready(tile)) {
|
||||||
|
updateViewToSelected(tile);
|
||||||
|
|
||||||
|
// create a new line from here
|
||||||
|
addLineToCanvas(event);
|
||||||
|
|
||||||
|
// extract the character on the selected tile
|
||||||
|
let character = tile.firstChild.id.substring(2);
|
||||||
|
|
||||||
|
// add it to the current guess
|
||||||
|
guess = guess + character;
|
||||||
|
|
||||||
|
// and update the guess view
|
||||||
|
let guessContainer = $("#guess");
|
||||||
|
let guessCharContainer = $("<span>");
|
||||||
|
guessCharContainer.text(character.toUpperCase());
|
||||||
|
guessCharContainer.appendTo(guessContainer);
|
||||||
|
guessContainer.attr("class", "guess shown");
|
||||||
|
|
||||||
|
// update guess view position on screen
|
||||||
|
let newSize = ($(window).width() - 20) / 2 - guess.length * 17;
|
||||||
|
guessContainer.css("left", newSize + "px");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateViewToSelected(tile) {
|
||||||
|
tile.setAttribute("class", "tile selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
function notHitAlready(tile) {
|
||||||
|
return tile.getAttribute("class") === "tile";
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
canvas.setWidth($(window).width());
|
||||||
|
screenMiddle = $(window).height() / 2;
|
||||||
|
canvas.setHeight(screenMiddle);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shuffleLetters(array) {
|
||||||
|
let j, x;
|
||||||
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
|
j = Math.floor(Math.random() * (i + 1));
|
||||||
|
x = array[i];
|
||||||
|
array[i] = array[j];
|
||||||
|
array[j] = x;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showHint() {
|
||||||
|
let found = false;
|
||||||
|
let count = 0; //100 tries
|
||||||
|
while (!found && count++ < 100) {
|
||||||
|
let word = words[Math.floor(Math.random() * words.length)];
|
||||||
|
let letter = word[Math.floor(Math.random() * word.length)].toUpperCase();
|
||||||
|
let slot = $("#" + word).children();
|
||||||
|
|
||||||
|
for (let i = 0; i < word.length; i++) {
|
||||||
|
if (slot[i].firstChild.nodeValue === letter && slot[i].getAttribute("class") === "characterslot") {
|
||||||
|
slot[i].setAttribute("class", "characterslot revealed");
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
42
webpack.config.js
Normal file
42
webpack.config.js
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: 'development',
|
||||||
|
entry: './src/js/index.js',
|
||||||
|
|
||||||
|
output: {
|
||||||
|
filename: 'bundle.js',
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: 'eslint-loader',
|
||||||
|
options: {
|
||||||
|
emitError: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [
|
||||||
|
'style-loader',
|
||||||
|
'css-loader',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|svg|jpg|gif)$/,
|
||||||
|
use: [
|
||||||
|
'file-loader',
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(woff|woff2|eot|ttf|otf)$/,
|
||||||
|
use: [
|
||||||
|
'file-loader',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
Loading…
Add table
Reference in a new issue