My code returns "not defined" when I press on any of the buttons or type in a function in the console (for example if I press the Roll! button or type Roll() in the console). I don't think the HTML has anything to do with it but it might so I put it in. Here is my code:
<!DOCTYPE html>
<html>
<head>
<style>
.dropbtn {
color: black;
padding: 4px;
font-size: 16px;
border: none;
cursor: pointer;
min-width: 160px;
}
.dropbtn:hover, .dropbtn:focus {
background-color: gray;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #ffffff;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #f1f1f1}
.show {display:block;}
</style>
</head>
<body>
<img id="Dice1" src="White.png"></img>
<img id="Dice2" src="White.png"></img>
<img id="Dice3" src="White.png"></img>
<p></p>
<div class="dropdown">
<button onclick="Dropdown()" class="dropbtn">Number of Dice</button>
<div id="myDropdown" class="dropdown-content">
<button class="dropbtn" onclick="DiceNum(1)">1 Dice</button>
<button class="dropbtn" onclick="DiceNum(2)">2 Die</button>
<button class="dropbtn" onclick="DiceNum(3)">3 Die</button>
</div>
</div>
<p></p>
<button class="dropbtn" onclick="Roll()">Roll!</button>
<script>
var Dice = 1;
function Dropdown() {
document.getElementById("myDropdown").classList.toggle("show");
}
var openDropdown
window.onclick = function(event) {
if (!event.target.matches(".dropbtn")) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i += 1) {
openDropdown = dropdowns[i];
if (openDropdown.classList.contains("show")) {
openDropdown.classList.remove("show");
}
}
}
}
var randNum1 = Math.floor((Math.random() * 6) + 1);
var randNum2 = Math.floor((Math.random() * 6) + 1);
var randNum3 = Math.floor((Math.random() * 6) + 1);
function Roll() {
if(Dice===1) {
randNum1 = Math.floor((Math.random() * 6) + 1);
document.getElementById("Dice1").src = "Dice"+randNum1+".png";
document.getElementById("Dice2").src = "White.png";
document.getElementById("Dice3").src = "White.png";
} else if(Dice===2) {
randNum1 = Math.floor((Math.random() * 6) + 1);
randNum2 = Math.floor((Math.random() * 6) + 1);
document.getElementById("Dice1").src = "Dice"+randNum1+".png";
document.getElementById("Dice2").src = "Dice"+randNum2+".png";
document.getElementById("Dice3").src = "White.png";
} else if(Dice===3) {
randNum1 = Math.floor((Math.random() * 6) + 1);
randNum2 = Math.floor((Math.random() * 6) + 1);
randNum3 = Math.floor((Math.random() * 6) + 1);
document.getElementById("Dice1").src = "Dice"+randNum1+".png";
document.getElementById("Dice2").src = "Dice"+randNum2+".png";
document.getElementById("Dice3").src = "Dice"+randNum3+".png";
}
}
var DiceNum = function (x) {
if(x===1) {
return var Dice = 1;
} else if(x===2) {
return var Dice = 2;
} else if(x===3) {
return var Dice = 3;
}
}
</script>
</body>
</html>
You can't return an variable assignment. Instead do it this way
var DiceNum = function(x) {
if (x === 1) {
Dice = 1;
} else if (x === 2) {
Dice = 2;
} else if (x === 3) {
Dice = 3;
}
}
There is an error in your DiceNum function:
var DiceNum = function (x) {
if(x===1) {
return var Dice = 1;
} else if(x===2) {
return var Dice = 2;
} else if(x===3) {
return var Dice = 3;
}
}
You return var Dice = 1 is not correct syntax in Javascript, try changing it to return Dice = 1(change it in the other places as well)
I hope this helps!
You can not declare the variable so many times your function should look like this:
var DiceNum = function (x) {
if(x===1) {
return Dice = 1;
} else if(x===2) {
return Dice = 2;
} else if(x===3) {
return Dice = 3;
}
}
DiceNum() is returning 'var Dice = 1' try commenting and see if it runs also,
try defining the function as var Roll = function(){.... similar to DiceNum
Related
Recently I've been looking at different projects and trying to modify them to try and understand the JS code much better. Recently I came across this lotto game from code pen. So I thought to try to make it to a game where you had coins as lives, then you get some stars based on how many numbers you got right.
The thing that I am struggling at is trying to loop the code on the click of a button. Currently the code is restarting the game by recalling its own link, in this case I just used my index.html as replacement for the href just to work on it for now. I want to change this because it doesn't let me consume all my coins (lives) without refreshing the page.
I tried putting everything in a function instead of calling it through the DOM being loaded. I then called that function when the dom has loaded, then after each draw I tried calling it again by using another button but it doesn't work. Tried changing the href to the function but that doesn't work as well. I also tried a few other things but I cannot make a work around this. Any help is appreciated! I'm still learning Javascript, so please pardon my question.
The code is not owned by me, I am just playing around with it, here's the original codepen link. https://codepen.io/EwaTrojanowskaGrela/pen/KmJMWb
// Declaration of scores and lives
var stars = 0;
var coins = 5;
// End of comment
// For redeclaration in innerHTML
var starsEarned;
// End of comment
// For displaying current score
document.getElementById("star-count").innerHTML = stars;
document.getElementById("coin-count").innerHTML = coins;
// End of comment
document.addEventListener("DOMContentLoaded", function(e){
var body = document.querySelector("body");
var section = document.querySelector("section");
var articleLotto = document.querySelector(".lotto");
var articleBalls = document.querySelector(".balls");
var numbers = [];
var balls = document.getElementsByClassName("ball");
var drawnNums = [];
var chosenByMachine = [];
function createNumberBoard(number){
console.log("I work");
var board = document.createElement("div");
board.classList.add("board");
articleLotto.appendChild(board);
for( var i = 0; i<number; i ++){
var boardEl = document.createElement("button");
boardEl.classList.add("boardEl");
board.appendChild(boardEl);
}
var boardEls = document.getElementsByClassName("boardEl");
for( var i =0; i<boardEls.length; i++){
boardEls[i].setAttribute("data-number", i+1);
var dataNumber = boardEls[i].getAttribute("data-number");
var number = parseInt(dataNumber, 10);
numbers.push(number);
boardEls[i].textContent = number;
}
}
createNumberBoard(49);
var board = document.querySelector(".board");
var boardEls = document.querySelectorAll(".boardEl");
function drawNumbers(){
//boardEls.forEach(boardEl => boardEl.addEventListener("click", selectNums));
for (var i = 0; i<boardEls.length; i++){
boardEls[i].addEventListener("click", selectNums);
}
function selectNums(){
var number = parseInt(this.dataset.number, 10);
if(this.hasAttribute("data-number")){
drawnNums.push(number);
this.removeAttribute("data-number");
this.classList.add("crossedOut");
}
if(drawnNums.length=== 6){
//boardEls.forEach( boardEl => boardEl.removeAttribute("data-number"));
//boardEls.forEach(boardEl => boardEl.addEventListener("click", makeAlert));
for ( var i = 0; i<boardEls.length; i++){
boardEls[i].removeAttribute("data-number");
boardEls[i].addEventListener("click", makeAlert);
}
var startDraw = document.querySelector(".startDraw");
if(startDraw === null){ // you have to prevent creating the button if it is already there!
createButtonForMachineDraw();
} else {
return;
}
}
}
return drawnNums;
}
drawNumbers();
function makeAlert() {
var alertBox = document.createElement("div");
board.appendChild(alertBox);
alertBox.classList.add("alertBox");
alertBox.textContent = "You can only choose 6!";
setTimeout(function() {
alertBox.parentNode.removeChild(alertBox);
}, 1500);
}
function machineDraw(){
for( var i =0; i<6; i++){
var idx = Math.floor(Math.random() * numbers.length)
chosenByMachine.push(numbers[idx]);
/*a very important line of code which prevents machine from drawing the same number again
*/
numbers.splice(idx,1);
console.log(numbers)
/*this line of code allows to check if numbers are taken out*/
}
var btnToRemove = document.querySelector(".startDraw");
btnToRemove.classList.add("invisible");
/* why not remove it entirely? because it might then be accidentally created if for some reason you happen to try to click on board!!! and you may do that*/
return chosenByMachine;
}
//machineDraw();
function createButtonForMachineDraw(){
var startDraw = document.createElement("button");
startDraw.classList.add("startDraw");
section.appendChild(startDraw);
startDraw.textContent ="Release the balls";
startDraw.addEventListener("click", machineDraw);
startDraw.addEventListener("click", compareArrays);
}
function compareArrays(){
for( var i =0; i<balls.length; i++) {
balls[i].textContent = chosenByMachine[i];
(function() {
var j = i;
var f = function(){
balls[j].classList.remove("invisible");
balls[j].classList.add("ball-align");
}
setTimeout(f, 1000*(j+1));
})();
}
var common =[];
var arr1 = chosenByMachine;
var arr2 = drawnNums;
for(var i = 0; i<arr1.length; i++){
for(var j= 0; j<arr2.length; j++){
if(arr1[i]===arr2[j]){
common.push(arr1[i]);
}
}
}
console.log(arr1, arr2, common); /* you can monitor your arrays in console*/
function generateResult(){
// Deduction of coins once draw started
coins = coins - 1;
// End of comment
var resultsBoard = document.createElement("article");
section.appendChild(resultsBoard);
var paragraph = document.createElement("p");
resultsBoard.appendChild(paragraph);
resultsBoard.classList.add("resultsBoard");
resultsBoard.classList.add("invisible");
if(common.length === 0){
paragraph.textContent ="Oh no! You got " + common.length + " Star!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 1){
paragraph.textContent ="You got " + common.length + " Star!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 2){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 3) {
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 4){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return ststarsEarnedars;
} else if(common.length === 5){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
}
else if(common.length===6){
paragraph.textContent ="A true winner! You got " + common.length + " Stars!";
stars = stars + common.length;
return starsEarned;
}
// Returning of new coins
return coins;
// End of comment
}
setTimeout(function() {
makeComebackBtn();
document.querySelector(".resultsBoard").classList.remove("invisible"); //well, you cannot acces this outside the code
// Displaying of new scores
stars = stars + starsEarned;
document.getElementById("coin-count").innerHTML = coins;
document.getElementById("star-count").innerHTML = stars;
// End of comment
}, 8000);
generateResult();
}
function makeComebackBtn(){
var comebackBtn = document.createElement("a");
comebackBtn.classList.add("comebackBtn");
section.appendChild(comebackBtn);
comebackBtn.textContent ="Go again"
comebackBtn.setAttribute("href", "index.html");
}
})
body {
padding: 0 15%;
}
.game-container {
height: auto;
background-color:#424B54;
font-family: "Allerta", sans-serif;
margin: 0;
max-width: 425px;
height: 750px;
/* padding: 0 2%; */
box-sizing: border-box;
}
section {
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: auto;
padding-bottom: 15px;
}
h1,
p {
width: 100%;
text-align: center;
color: #FF6663;
text-shadow: 3px 3px #A20202;
font-family: "Bungee", cursive;
}
h1 {
font-size: 35px;
margin: 0;
}
p {
font-size: 30px;
margin: 0;
}
h3 {
color: #FF6663;
text-align: center;
text-shadow: 2px 2px #A20202;
font-size: 25px;
margin-bottom: 5px;
}
article {
height: 90%;
width: 250px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 1rem;
}
.scores {
width: 100%;
}
.coins,
.stars{
display: flex;
align-items: center;
gap: .5rem;
}
.score-icons {
color: #F6BD60;
font-size: 3rem;
}
.scores span {
color: white;
}
#star-count,
#coin-count{
font-size: 1.5 rem;
}
.invisible {
display: none;
}
.ball-align {
display: flex;
justify-content: center;
align-items: center;
}
.board {
position: relative;
background-color: #FF6663;
width: 13.125rem;
height: 13.125rem;
border: 1px solid #FF6663;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
}
.boardEl {
background-color: #E8F7EE;
width: 28px;
height: 28px;
color: #000000;
text-align: center;
font-size: 15px;
border: none;
}
.crossedOut {
background-color: #424B54;
color: #F7EDE2;
}
.startDraw {
background: #FF6663;
border: none;
font-size: 1.3rem;
font-weight: bolder;
color: #ffffff;
padding: 0.5rem 1rem;
margin: 0 auto;
border-radius: .5rem;
padding: .5rem 1rem;
}
.ball {
width: 2rem;
height: 2rem;
border-radius: 50%;
line-height: 2;
color: #efefef;
font-weight: bold;
text-align: center;
}
.ball:nth-of-type(2n) {
align-self: flex-end;
}
.ball:nth-of-type(2n + 1) {
align-self: flex-start;
}
.ball:first-of-type {
background-color: gold;
border: 1px solid #ccac00;
}
.ball:nth-of-type(2) {
background-color: hotpink;
border: 1px solid #ff369b;
}
.ball:nth-of-type(3) {
background-color: teal;
border: 1px solid #004d4d;
}
.ball:nth-of-type(4) {
background-color: #009900;
border: 1px solid #006600;
}
.ball:nth-of-type(5) {
background-color: #339999;
border: 1px solid #267373;
}
.ball:last-of-type {
background-color: #ff6633;
border: 1px solid #ff4000;
}
#ballContainer {
background-color: inherit;
border-bottom: none;
display: flex;
align-items: center;
gap: 0.1rem;
}
.resultsBoard {
margin-top: .5rem;
text-align: center;
width: 100%;
}
.resultsBoard p {
color: #F6BD60;
font-size: 2rem;
font-family: "Allerta", sans-serif;
text-shadow: none;
}
.comebackBtn {
line-height: 2;
margin-top: 2rem;
font-size: 1.3rem;
text-align: center;
background-color: #FF6663;
text-decoration: none;
color: #ffffff;
padding: .3rem 1rem;
border-radius: .3rem;
text-transform: uppercase;
}
.alertBox {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 3;
color: #ffffff;
background-color: #FF6663;
text-align: center;
line-height: 210px;
}
<!DOCTYPE html>
<html lang="eng-ENG">
<head>
<meta charset="UTF-8">
<title>lotto</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="style.css">
<link href="https://fonts.googleapis.com/css?family=Allerta|Bungee" rel="stylesheet">
<link href='https://unpkg.com/boxicons#2.1.2/css/boxicons.min.css' rel='stylesheet'>
</head>
<body>
<main>
<div class="game-container">
<section>
<h1>Lottery</h1>
<div class="scores">
<div class="coins">
<i class='score-icons bx bxs-star'></i><span id="star-count"></span>
</div>
<div class="stars">
<i class='score-icons bx bx-coin'></i><span id="coin-count"></span>
</div>
</div>
<article class="lotto">
<h3>Pick 6 numbers:</h3>
</article>
<article class="balls">
<div id="ballContainer">
<div class="ball invisible"></div>
<div class="ball invisible"></div>
<div class="ball invisible"></div>
<div class="ball invisible"></div>
<div class="ball invisible"></div>
<div class="ball invisible"></div>
</div>
</article>
</section>
</div>
</main>
<script type="text/javascript" src="index.js"></script>
<!--<script type="text/javascript" src="js/app2.js"></script>-->
</body>
</html>
[UPDATED]
I've tried and modified the js script code and no need to save values in local storage. And in addition, no need to refresh page to reload game state. I implemented in JSFiddle here
var stars = 0;
var coins = 5;
var starsEarned = 0;
// For displaying current score
document.getElementById("star-count").innerHTML = stars;
document.getElementById("coin-count").innerHTML = coins;
document.addEventListener("DOMContentLoaded", function(e){
var body = document.querySelector("body");
var section = document.querySelector("section");
var articleLotto = document.querySelector(".lotto");
var articleBalls = document.querySelector(".balls");
var numbers = [];
var balls = document.getElementsByClassName("ball");
var drawnNums = [];
var chosenByMachine = [];
var board;
var boardEls;
function createNumberBoard(number){
console.log("I work");
numbers = [];
drawnNums = [];
chosenByMachine = [];
var board = document.createElement("div");
board.classList.add("board");
articleLotto.appendChild(board);
for( var i = 0; i<number; i ++){
var boardEl = document.createElement("button");
boardEl.classList.add("boardEl");
board.appendChild(boardEl);
}
var boardEls = document.getElementsByClassName("boardEl");
for( var i =0; i<boardEls.length; i++){
boardEls[i].setAttribute("data-number", i+1);
var dataNumber = boardEls[i].getAttribute("data-number");
var number = parseInt(dataNumber, 10);
numbers.push(number);
boardEls[i].textContent = number;
}
}
createNumberBoard(49);
board = document.querySelector(".board");
boardEls = document.querySelectorAll(".boardEl");
function drawNumbers(){
//boardEls.forEach(boardEl => boardEl.addEventListener("click", selectNums));
for (var i = 0; i<boardEls.length; i++){
boardEls[i].addEventListener("click", selectNums);
}
function selectNums(){
var number = parseInt(this.dataset.number, 10);
if(this.hasAttribute("data-number")){
drawnNums.push(number);
this.removeAttribute("data-number");
this.classList.add("crossedOut");
}
if(drawnNums.length=== 6){
//boardEls.forEach( boardEl => boardEl.removeAttribute("data-number"));
//boardEls.forEach(boardEl => boardEl.addEventListener("click", makeAlert));
for ( var i = 0; i<boardEls.length; i++){
boardEls[i].removeAttribute("data-number");
boardEls[i].addEventListener("click", makeAlert);
}
var startDraw = document.querySelector(".startDraw");
if(startDraw === null){ // you have to prevent creating the button if it is already there!
createButtonForMachineDraw();
} else {
return;
}
}
}
return drawnNums;
}
drawNumbers();
function makeAlert() {
var alertBox = document.createElement("div");
board.appendChild(alertBox);
alertBox.classList.add("alertBox");
alertBox.textContent = "You can only choose 6!";
setTimeout(function() {
alertBox.parentNode.removeChild(alertBox);
}, 1500);
}
function machineDraw(){
for( var i =0; i<6; i++){
var idx = Math.floor(Math.random() * numbers.length)
chosenByMachine.push(numbers[idx]);
/*a very important line of code which prevents machine from drawing the same number again
*/
numbers.splice(idx,1);
/* console.log(numbers) */
/*this line of code allows to check if numbers are taken out*/
}
var btnToRemove = document.querySelector(".startDraw");
btnToRemove.classList.add("invisible");
/* why not remove it entirely? because it might then be accidentally created if for some reason you happen to try to click on board!!! and you may do that*/
return chosenByMachine;
}
//machineDraw();
function createButtonForMachineDraw(){
var startDraw = document.createElement("button");
startDraw.classList.add("startDraw");
section.appendChild(startDraw);
startDraw.textContent ="Release the balls";
startDraw.addEventListener("click", machineDraw);
startDraw.addEventListener("click", compareArrays);
}
function compareArrays(){
for( var i =0; i<balls.length; i++) {
balls[i].textContent = chosenByMachine[i];
(function() {
var j = i;
var f = function(){
balls[j].classList.remove("invisible");
balls[j].classList.add("ball-align");
}
setTimeout(f, 1000*(j+1));
})();
}
var common =[];
var arr1 = chosenByMachine;
var arr2 = drawnNums;
for(var i = 0; i<arr1.length; i++){
for(var j= 0; j<arr2.length; j++){
if(arr1[i]===arr2[j]){
common.push(arr1[i]);
}
}
}
/* console.log(arr1, arr2, common) */; /* you can monitor your arrays in console*/
function generateResult(){
// Deduction of coins once draw started
coins = coins - 1;
// End of comment
var resultsBoard = document.createElement("article");
section.appendChild(resultsBoard);
var paragraph = document.createElement("p");
resultsBoard.appendChild(paragraph);
resultsBoard.classList.add("resultsBoard");
resultsBoard.classList.add("invisible");
if(common.length === 0){
paragraph.textContent ="Oh no! You got " + common.length + " Star!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 1){
paragraph.textContent ="You got " + common.length + " Star!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 2){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 3) {
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 4){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return ststarsEarnedars;
} else if(common.length === 5){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
}
else if(common.length===6){
paragraph.textContent ="A true winner! You got " + common.length + " Stars!";
stars = stars + common.length;
return starsEarned;
}
// Returning of new coins
return coins;
// End of comment
}
setTimeout(function() {
makeComebackBtn();
document.querySelector(".resultsBoard").classList.remove("invisible"); //well, you cannot acces this outside the code
// Displaying of new scores
stars = starsEarned;
document.getElementById("coin-count").innerHTML = coins;
document.getElementById("star-count").innerHTML = stars;
// End of comment
}, 8000);
generateResult();
}
function makeComebackBtn(){
var comebackBtn = document.createElement("a");
comebackBtn.classList.add("comebackBtn");
section.appendChild(comebackBtn);
comebackBtn.textContent ="Go again";
if (coins === 0) {
comebackBtn.addEventListener("click", function () {
alert("You ran out of coins");
});
} else {
comebackBtn.addEventListener("click", function () {
const board_ = document.querySelector(".board");
board_.parentNode.removeChild(board_);
const startDraw_ = document.querySelector(".startDraw");
startDraw_.parentNode.removeChild(startDraw_);
for( let i=0; i<balls.length; i++) {
balls[i].classList.add("invisible");
balls[i].classList.remove("ball-align");
}
const resultsBoard_ = document.querySelector(".resultsBoard");
resultsBoard_.parentNode.removeChild(resultsBoard_);
createNumberBoard(49);
board = document.querySelector(".board");
boardEls = document.querySelectorAll(".boardEl");
drawNumbers();
const comebackBtn_ = document.querySelector(".comebackBtn");
comebackBtn_.parentNode.removeChild(comebackBtn_);
});
}
}
})
You need to save the values of stars and coins to localStorage using localStorage.setItem("stars", stars) or sessionStorage and get the values again at beginning of each turn.
Also initialize value of variable starsEarned = 0 and check condition of number of coins when reload the page. If run out of coins, alert player.
You can see following code I modified from your
// Declaration of scores and lives
var stars = Number(localStorage.getItem("stars")) || 0;
var coins = Number(localStorage.getItem("coins")) || 5;
// End of comment
// For redeclaration in innerHTML
var starsEarned = 0;
// End of comment
// For displaying current score
document.getElementById("star-count").innerHTML = stars;
document.getElementById("coin-count").innerHTML = coins;
// End of comment
document.addEventListener("DOMContentLoaded", function(e){
var body = document.querySelector("body");
var section = document.querySelector("section");
var articleLotto = document.querySelector(".lotto");
var articleBalls = document.querySelector(".balls");
var numbers = [];
var balls = document.getElementsByClassName("ball");
var drawnNums = [];
var chosenByMachine = [];
function createNumberBoard(number){
console.log("I work");
var board = document.createElement("div");
board.classList.add("board");
articleLotto.appendChild(board);
for( var i = 0; i<number; i ++){
var boardEl = document.createElement("button");
boardEl.classList.add("boardEl");
board.appendChild(boardEl);
}
var boardEls = document.getElementsByClassName("boardEl");
for( var i =0; i<boardEls.length; i++){
boardEls[i].setAttribute("data-number", i+1);
var dataNumber = boardEls[i].getAttribute("data-number");
var number = parseInt(dataNumber, 10);
numbers.push(number);
boardEls[i].textContent = number;
}
}
createNumberBoard(49);
var board = document.querySelector(".board");
var boardEls = document.querySelectorAll(".boardEl");
function drawNumbers(){
//boardEls.forEach(boardEl => boardEl.addEventListener("click", selectNums));
for (var i = 0; i<boardEls.length; i++){
boardEls[i].addEventListener("click", selectNums);
}
function selectNums(){
var number = parseInt(this.dataset.number, 10);
if(this.hasAttribute("data-number")){
drawnNums.push(number);
this.removeAttribute("data-number");
this.classList.add("crossedOut");
}
if(drawnNums.length=== 6){
//boardEls.forEach( boardEl => boardEl.removeAttribute("data-number"));
//boardEls.forEach(boardEl => boardEl.addEventListener("click", makeAlert));
for ( var i = 0; i<boardEls.length; i++){
boardEls[i].removeAttribute("data-number");
boardEls[i].addEventListener("click", makeAlert);
}
var startDraw = document.querySelector(".startDraw");
if(startDraw === null){ // you have to prevent creating the button if it is already there!
createButtonForMachineDraw();
} else {
return;
}
}
}
return drawnNums;
}
drawNumbers();
function makeAlert() {
var alertBox = document.createElement("div");
board.appendChild(alertBox);
alertBox.classList.add("alertBox");
alertBox.textContent = "You can only choose 6!";
setTimeout(function() {
alertBox.parentNode.removeChild(alertBox);
}, 1500);
}
function machineDraw(){
for( var i =0; i<6; i++){
var idx = Math.floor(Math.random() * numbers.length)
chosenByMachine.push(numbers[idx]);
/*a very important line of code which prevents machine from drawing the same number again
*/
numbers.splice(idx,1);
/* console.log(numbers) */
/*this line of code allows to check if numbers are taken out*/
}
var btnToRemove = document.querySelector(".startDraw");
btnToRemove.classList.add("invisible");
/* why not remove it entirely? because it might then be accidentally created if for some reason you happen to try to click on board!!! and you may do that*/
return chosenByMachine;
}
//machineDraw();
function createButtonForMachineDraw(){
var startDraw = document.createElement("button");
startDraw.classList.add("startDraw");
section.appendChild(startDraw);
startDraw.textContent ="Release the balls";
startDraw.addEventListener("click", machineDraw);
startDraw.addEventListener("click", compareArrays);
}
function compareArrays(){
for( var i =0; i<balls.length; i++) {
balls[i].textContent = chosenByMachine[i];
(function() {
var j = i;
var f = function(){
balls[j].classList.remove("invisible");
balls[j].classList.add("ball-align");
}
setTimeout(f, 1000*(j+1));
})();
}
var common =[];
var arr1 = chosenByMachine;
var arr2 = drawnNums;
for(var i = 0; i<arr1.length; i++){
for(var j= 0; j<arr2.length; j++){
if(arr1[i]===arr2[j]){
common.push(arr1[i]);
}
}
}
/* console.log(arr1, arr2, common) */; /* you can monitor your arrays in console*/
function generateResult(){
// Deduction of coins once draw started
coins = coins - 1;
// End of comment
var resultsBoard = document.createElement("article");
section.appendChild(resultsBoard);
var paragraph = document.createElement("p");
resultsBoard.appendChild(paragraph);
resultsBoard.classList.add("resultsBoard");
resultsBoard.classList.add("invisible");
if(common.length === 0){
paragraph.textContent ="Oh no! You got " + common.length + " Star!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 1){
paragraph.textContent ="You got " + common.length + " Star!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 2){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 3) {
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
} else if(common.length === 4){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return ststarsEarnedars;
} else if(common.length === 5){
paragraph.textContent ="You got " + common.length + " Stars!";
starsEarned = stars + common.length;
return starsEarned;
}
else if(common.length===6){
paragraph.textContent ="A true winner! You got " + common.length + " Stars!";
stars = stars + common.length;
return starsEarned;
}
// Returning of new coins
return coins;
// End of comment
}
setTimeout(function() {
makeComebackBtn();
document.querySelector(".resultsBoard").classList.remove("invisible"); //well, you cannot acces this outside the code
// Displaying of new scores
stars = starsEarned;
document.getElementById("coin-count").innerHTML = coins;
document.getElementById("star-count").innerHTML = stars;
localStorage.setItem("stars", stars);
localStorage.setItem("coins", coins);
// End of comment
}, 8000);
generateResult();
}
function makeComebackBtn(){
var comebackBtn = document.createElement("a");
comebackBtn.classList.add("comebackBtn");
section.appendChild(comebackBtn);
comebackBtn.textContent ="Go again";
if (coins === 0) {
comebackBtn.setAttribute("onClick", "alert('You ran out of coins')");
} else {
comebackBtn.setAttribute("onClick", "window.location.reload();");
}
}
})
I want to add 10 points when blue box goes into brown box.
I tried to set score = 0 and points to add = 10 but it doesn't work.
I alert '+10 points' and it shows me the alert so I guess the problem is the DOM ?!?
Any suggestions ?
Thanks !
let moveCounter = 0;
let score = 0;
let obs = 10;
document.getElementById('score').textContent = '0';
var grid = document.getElementById("grid-box");
for (var i = 1; i <= 49; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var obstacles = [];
while (obstacles.length < 10) {
var randomIndex = parseInt(49 * Math.random());
if (obstacles.indexOf(randomIndex) === -1) {
obstacles.push(randomIndex);
var drawObstacle = document.getElementById('square' + randomIndex);
$(drawObstacle).addClass("ob")
}
}
var playerOne = [];
while (playerOne.length < 1) {
var randomIndex = parseInt(49 * Math.random());
if (playerOne.indexOf(randomIndex) === -1) {
playerOne.push(randomIndex);
var drawPone = document.getElementById('square' + randomIndex);
$(drawPone).addClass("p-0")
}
}
var addPoints = $('#score');
$('#button_right').on('click', function() {
if ($(".p-0").hasClass("ob")) {
alert('add +10 points !!!')
addPoints.text( parseInt(addPoints.text()) + obs );
}
moveCounter += 1;
if ($(".p-0").hasClass("ob")) {
}
$pOne = $('.p-0')
$pOneNext = $pOne.next();
$pOne.removeClass('p-0');
$pOneNext.addClass('p-0');
});
#grid-box {
width: 400px;
height: 400px;
margin: 0 auto;
font-size: 0;
position: relative;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.ob {
background-color: brown;
}
.p-0 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box">
</div>
<div class="move">
<button id="button_right">right</button><br>
</div>
<div id="score">
</div>
Thank you very much! I am new to JavaScript/ JQuery
Thank you very much!
You are trying to change the HTML inside of the div with id "score".
Selecting the css element using $("#id") retrieves the DOM element and not its contents so adding the score directly to it has no consequences.
What you want to do is: update the score variable and then set the HTML inside the div to the score value.
So instead of just:
addPoints += obs
you should
score += obs
addPoints.html(score)
I want to randomly assign a class at two boxes.
But even with indexOf(randomIndex) === -1) Math.random is duplicating the numbers.
If you refresh you will see that the boxes are changing classes but sometimes they both have the same class, this should happened.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
var weapon3 = [];
while (weapon3.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weapon3.indexOf(randomIndex) === -1) {
weapon3.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
You are using two different arrays for storing the weapons. Use same array so that the number is not repeated.
var grid = document.getElementById("grid-box");
for (var i = 0; i <= 1; i++) {
var square = document.createElement("div");
square.className = 'square';
square.id = 'square' + i;
grid.appendChild(square);
}
var weaponTwo = [];
while (weaponTwo.length < 1) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var drawWtwo = document.getElementById('square' + randomIndex);
$(drawWtwo).addClass("w2")
}
};
while (weaponTwo.length < 2) {
var randomIndex = parseInt(2 * Math.random());
if (weaponTwo.indexOf(randomIndex) === -1) {
weaponTwo.push(randomIndex);
var draw3 = document.getElementById('square' + randomIndex);
$(draw3).addClass("w3")
}
};
#grid-box {
width: 420px;
height: 220px;
}
#grid-box>div.square {
font-size: 1rem;
vertical-align: top;
display: inline-block;
width: 10%;
height: 10%;
box-sizing: border-box;
border: 1px solid #000;
}
.w2 {
background-color: red;
}
.w3 {
background-color: blue;
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="grid-box"></div>
Better Approach : You can create an array of classes and then shuffle it using this alogrithm. Then you can pop from the array and add to classes one by one.
I'm creating a minefiled game and I'm trying to put 10 bombs in a random location each time. The problem is that sometimes 2 or more bombs can be placed in the same block, resulting in less than 10 bombs in the game. How can I prevent this?
I've already tried saving all the bombs locations in an array and each time compare the new bomb location to all the past ones, but id didn't work.
Here is my code:
var number_of_blocks = 0;
var number_of_bombs = 10;
var minefield_width = 500;
var minefield_height = 500;
var block_width = 50;
var block_height = 50;
var bombs = [];
number_of_blocks = (minefield_width * minefield_height) / (block_width * block_height);
$("#new_game").click(function() {
create_blocks();
create_bombs();
});
function random(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function create_blocks() {
//Create the "normal blocks".
for (var i = 0; i < number_of_blocks; i++) {
var block = document.createElement("div");
block.style.width = block_width + "px";
block.style.height = block_height + "px";
block.className = "block";
block.id = "b" + i;
block.onclick = function() {
console.log(this.id);
this.style.backgroundColor = "#ddd";
};
document.getElementById("field").appendChild(block);
}
}
function create_bombs() {
//Select a "normal block" and transform it into a "bomb block".
for (var i = 0; i < number_of_bombs; i++) {
var random_block = bombs_do_not_repeat();
var bomb = document.getElementById(random_block);
bomb.style.backgroundColor = "red";
bomb.classList.add("bomb");
bomb.onclick = function() {
alert("GAME OVER");
};
bombs[i] = random_block;
}
}
function bombs_do_not_repeat() {
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
bombs_do_not_repeat();
}
}
return random_num;
}
* {
list-style: none;
font-family: sans-serif;
margin: 0px;
}
#field {
width: 500px;
height: 500px;
border: solid 1px black;
margin: 0px auto;
margin-top: 50px;
overflow: auto;
background-color: #ccc;
}
.block {
background-color: #aaa;
border: solid 1px #000;
box-sizing: border-box;
float: left;
cursor: pointer;
}
.block:hover {
background-color: #eee
}
.block:active {
background-color: #ddd
}
#container {
overflow: auto;
}
#menu {
width: 100%;
height: auto;
background-color: #333;
overflow: auto;
}
#menu li {
float: left;
text-align: center;
width: 100px;
color: white;
cursor: pointer;
}
#menu li:hover {
background-color: #555
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="container">
<div id="menu">
<ul>
<li id="new_game">New Game</li>
</ul>
</div>
<div id="field"></div>
</div>
</body>
</html>
SOLVED:
function bombs_do_not_repeat(){
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1,number_of_blocks);
for(var j = 0; j < bombs.length; j++){
if(random_num == bombs[j]){
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
return random_num = bombs_do_not_repeat();
}
}
return random_num;
}
You're recursively calling bombs_do_not_repeat(), but always ignoring the recursive result and just going with whatever was selected first whether it's a repeat or not.
I suspect you mean to assign the result of the recursion:
random_num = bombs_do_not_repeat();
I suggest you to change your function to this
function bombs_do_not_repeat() {
var check = false;
var random_num;
do{
random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length && !check; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
check = true;
}
}
}while(check);
return random_num;
}
Instead of creating each random number prepare a random (shuffled) array. Something like this.
var number_of_blocks = 0;
var number_of_bombs = 10;
var minefield_width = 500;
var minefield_height = 500;
var block_width = 50;
var block_height = 50;
var bombs = [];
var blockArr = []; //helper array
number_of_blocks = (minefield_width * minefield_height) / (block_width * block_height);
$("#new_game").click(function() {
//reset blockArr and bombs
bombs = [];
blockArr = [];
//clean the field
document.getElementById('field').innerHTML = '';
create_blocks();
//blockArr is now fillewd
bombs = blockArr.sort(function() {
return Math.random() < 0.5 ? -1 : 1;
}) //shuffle
.slice(0, number_of_bombs);
//for debug purpose
//console.log(bombs);
create_bombs();
});
//function random(min, max) {//obsolete
// return Math.floor(Math.random() * (max - min)) + min;
//}
function create_blocks() {
//Create the "normal blocks".
for (var i = 0; i < number_of_blocks; i++) {
//fill blockArr in the samee loop
blockArr.push(i);
var block = document.createElement("div");
block.style.width = block_width + "px";
block.style.height = block_height + "px";
block.className = "block";
block.id = "b" + i;
block.onclick = function() {
console.log(this.id);
this.style.backgroundColor = "#ddd";
};
document.getElementById("field").appendChild(block);
}
}
function create_bombs() {
//Select a "normal block" and transform it into a "bomb block".
for (var i = 0; i < number_of_bombs; i++) {
//var random_block = bombs_do_not_repeat(); //no need
var bomb = document.getElementById('b' + bombs[i]); //random_block);
bomb.style.backgroundColor = "red";
bomb.classList.add("bomb");
bomb.onclick = function() {
alert("GAME OVER");
};
//bombs[i] = random_block;
}
}
/*
function bombs_do_not_repeat() { //obsolete
//Should prevent a 'bomb block' to go inside the same 'block' more than 1 time. Example:
//CORRECT: bombs[] = "b1", "b2", "b3", "b4", "b5";
//INCORRECT: bombs[] = "b1", "b1", "b3", "b4", "b4";
var random_num = "b" + random(1, number_of_blocks);
for (var j = 0; j < bombs.length; j++) {
if (random_num == bombs[j]) {
console.info("random_num = " + random_num + " && bombs[" + j + "] = " + bombs[j]);
bombs_do_not_repeat();
}
}
return random_num;
}
*/
* {
list-style: none;
font-family: sans-serif;
margin: 0px;
}
#field {
width: 500px;
height: 500px;
border: solid 1px black;
margin: 0px auto;
margin-top: 50px;
overflow: auto;
background-color: #ccc;
}
.block {
background-color: #aaa;
border: solid 1px #000;
box-sizing: border-box;
float: left;
cursor: pointer;
}
.block:hover {
background-color: #eee
}
.block:active {
background-color: #ddd
}
#container {
overflow: auto;
}
#menu {
width: 100%;
height: auto;
background-color: #333;
overflow: auto;
}
#menu li {
float: left;
text-align: center;
width: 100px;
color: white;
cursor: pointer;
}
#menu li:hover {
background-color: #555
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<div id="container">
<div id="menu">
<ul>
<li id="new_game">New Game</li>
</ul>
</div>
<div id="field"></div>
</div>
</body>
</html>
I've created a snake game, and when the snake hit the wall or itself, it still wont stop moving. I figured out if I used the clearTimeout(), it would help. but it didn't.
Is there a way to stop the loop? or it is another issue?
jQuery(document).ready(function($) {
init();
});
var move;
function init() {
board.initBoard();
drawSnake();
food.createFood();
}
function play() {
$('.newGame').css('visibility', 'hidden');
$('.playgame').css('visibility', 'hidden');
moveSnake();
getSnakeDir();
}
function gameover() {
clearTimeout(move);
$('.newGame').css('visibility', 'visible');
}
function playGame() {
$('#gameboard').empty();
$('.newGame').hide();
init();
play();
}
var board = {
DIM: 20,
initBoard: function() {
for (var i = 0; i < board.DIM; i++) {
var row = $('<div class="row-' + i + '"></div>');
for (var j = 0; j < board.DIM; j++) {
var col = ('<div class="col-' + j + '-' + i + '"></div>');
$(row).append(col);
}
$("#gameboard").append(row);
}
}
}
var snake = {
position: ['10-10', '10-11', '10-12'],
direction: 'r',
speed: 200,
};
function drawSnake() {
$('.col-10-10').addClass('snake');
$('.col-11-10').addClass('snake');
}
function getSnakeDir() {
$(document).keydown(function(event) {
//event.preventDefault();
if (event.which == 38) {
snake.direction = 'u';
} else if (event.which == 39) {
snake.direction = 'r';
} else if (event.which == 40) {
snake.direction = 'd';
} else if (event.which == 37) {
snake.direction = 'l';
}
});
}
function moveSnake() {
var tail = snake.position.pop();
$('.col-' + tail).removeClass('snake');
var coords = snake.position[0].split('-');
var x = parseInt(coords[0]);
var y = parseInt(coords[1]);
if (snake.direction == 'r') {
x = x + 1;
} else if (snake.direction == 'd') {
y = y + 1;
} else if (snake.direction == 'l') {
x = x - 1;
} else if (snake.direction == 'u') {
y = y - 1;
}
var currentcoords = x + '-' + y;
snake.position.unshift(currentcoords);
$('.col-' + currentcoords).addClass('snake');
//when snake eats food
if (currentcoords == food.coords) {
console.log('true');
$('.col-' + food.coords).removeClass('food');
snake.position.push(tail);
food.createFood();
}
//game over
if (x < 0 || y < 0 || x > board.DIM || y > board.DIM) {
gameover();
}
//if snake touch itself
if (hitItself(snake.position) == true) {
gameover();
}
move=setTimeout(moveSnake, 200);
}
var food = {
coords: "",
createFood: function() {
var x = Math.floor(Math.random() * (board.DIM-1)) + 1;
var y = Math.floor(Math.random() * (board.DIM-1)) + 1;
var fruitCoords = x + '-' + y;
$('.col-' + fruitCoords).addClass('food');
food.coords = fruitCoords;
},
}
function hitItself(array) {
var valuesSoFar = Object.create(null);
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (value in valuesSoFar) {
return true;
}
valuesSoFar[value] = true;
}
return false;
}
.buttonnewgame {
position: relative;
}
.newGame {
position: absolute;
top: 45%;
left: 25%;
padding: 15px;
font-size: 1em;
font-family: arial;
visibility: hidden;
}
.gameContainer{
width: 100%;
}
#gameboard {
background-color:#eee;
padding:3px;
}
.playgame {
position: absolute;
top: 45%;
left: 20%;
padding: 15px;
font-size: 1em;
font-family: arial;
}
/* styling the board */
div[class^='row'] {
height: 15px;
text-align: center;
}
div[class*='col']{
display: inline-block;
border: 1px solid grey;
width: 15px;
height: 15px;
}
/*display the snake*/
.snake {
background-color: blue;
z-index: 99;
}
.food {
background: red;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="game">
<div class="buttonnewgame">
<input type="button" name="new game" value="new game" class="newGame" onclick="playGame()" />
<button class="playgame" onclick="play()">Play Game</button>
<div class="gameContainer">
<div id="gameboard">
<!-- snake game in here -->
</div>
</div>
</div>
</div>
There were a few problems, but here is the 'working version' (there are more bugs).
1) I renamed drawSnake to createSnake. You weren't fully reinitializing the snake when you called init(). The snakes position was not being reset in the previous drawSnake method, so it would seem like the game was not playable.
After that there were 2 more bugs.
2) You have to return after you call gameOver or the game never really ends does it? Once you clear the timeout in gameover, you immediately set another Timeout for on the last line of moveSnake() because you didn't return once the game was over. That lead to weird results that made it seem like the game was unresponsive.
3) You were using a combination of visibility none or visible and $.hide(). $.hide() uses display: none, so when you tried to show it again with the visibility style change, its still display: none so the new game button would stop appearing.
My advice to any game coder is to learn how to separate the code that handles how the game works (logic of the game, how the clock ticks, initialization of game state, etc) , and how it is displayed (the html and css). Modeling the game logic after a cleanly written system is easy to read and debug. The code becomes harder to understand and modify when the display code is mixed in with game logic. In theory, our game should work perfectly without any kind of rendering. Then we could write a renderer that produces an HTML canvas, html DOM, text in the command line, or OpenGL.
Heres an old project I never finished that should illustrate a separation between model and view.
http://tando.us/ganix/ganix.htm
jQuery(document).ready(function($) {
init();
});
var move;
function init() {
board.initBoard();
createSnake();
food.createFood();
}
function play() {
$('.newGame').hide();
$('.playgame').hide();
moveSnake();
getSnakeDir();
}
function gameover() {
clearTimeout(move);
$('.newGame').show();
}
function playGame() {
$('#gameboard').empty();
$('.newGame').hide();
init();
play();
}
var board = {
DIM: 20,
initBoard: function() {
for (var i = 0; i < board.DIM; i++) {
var row = $('<div class="row-' + i + '"></div>');
for (var j = 0; j < board.DIM; j++) {
var col = ('<div class="col-' + j + '-' + i + '"></div>');
$(row).append(col);
}
$("#gameboard").append(row);
}
}
}
var snake = {
position: ['10-10', '10-11', '10-12'],
direction: 'r',
speed: 200,
};
function createSnake() {
$('.col-10-10').addClass('snake');
$('.col-11-10').addClass('snake');
snake.position = ['10-10', '10-11', '10-12'];
}
function getSnakeDir() {
$(document).keydown(function(event) {
//event.preventDefault();
if (event.which == 38) {
snake.direction = 'u';
} else if (event.which == 39) {
snake.direction = 'r';
} else if (event.which == 40) {
snake.direction = 'd';
} else if (event.which == 37) {
snake.direction = 'l';
}
});
}
function moveSnake() {
var tail = snake.position.pop();
$('.col-' + tail).removeClass('snake');
var coords = snake.position[0].split('-');
var x = parseInt(coords[0]);
var y = parseInt(coords[1]);
if (snake.direction == 'r') {
x = x + 1;
} else if (snake.direction == 'd') {
y = y + 1;
} else if (snake.direction == 'l') {
x = x - 1;
} else if (snake.direction == 'u') {
y = y - 1;
}
var currentcoords = x + '-' + y;
snake.position.unshift(currentcoords);
$('.col-' + currentcoords).addClass('snake');
//when snake eats food
if (currentcoords == food.coords) {
console.log('true');
$('.col-' + food.coords).removeClass('food');
snake.position.push(tail);
food.createFood();
}
//game over
if (x < 0 || y < 0 || x > board.DIM || y > board.DIM) {
gameover();
return;
}
//if snake touch itself
if (hitItself(snake.position) == true) {
gameover();
return;
}
move=setTimeout(moveSnake, 200);
}
var food = {
coords: "",
createFood: function() {
var x = Math.floor(Math.random() * (board.DIM-1)) + 1;
var y = Math.floor(Math.random() * (board.DIM-1)) + 1;
var fruitCoords = x + '-' + y;
$('.col-' + fruitCoords).addClass('food');
food.coords = fruitCoords;
},
}
function hitItself(array) {
var valuesSoFar = Object.create(null);
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (value in valuesSoFar) {
return true;
}
valuesSoFar[value] = true;
}
return false;
}
.buttonnewgame {
position: relative;
}
.newGame {
position: absolute;
top: 45%;
left: 25%;
padding: 15px;
font-size: 1em;
font-family: arial;
}
.gameContainer{
width: 100%;
}
#gameboard {
background-color:#eee;
padding:3px;
}
.playgame {
position: absolute;
top: 45%;
left: 20%;
padding: 15px;
font-size: 1em;
font-family: arial;
}
/* styling the board */
div[class^='row'] {
height: 15px;
text-align: center;
}
div[class*='col']{
display: inline-block;
border: 1px solid grey;
width: 15px;
height: 15px;
}
/*display the snake*/
.snake {
background-color: blue;
z-index: 99;
}
.food {
background: red;
z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="game">
<div class="buttonnewgame">
<input type="button" name="new game" value="new game" class="newGame" style="display:none;" onclick="playGame()" />
<button class="playgame" onclick="play()">Play Game</button>
<div class="gameContainer">
<div id="gameboard">
<!-- snake game in here -->
</div>
</div>
</div>
You could try not to initiate a new setTimeout call at the and of the moveSnake function, but instead using.
function play() {
$('.newGame').css('visibility', 'hidden');
$('.playgame').css('visibility', 'hidden');
move = setInterval(moveSnake, 200);
getSnakeDir();
}
and remove the
move = setTimeout(moveSnake, 200)
from the moveSnake function and do
function gameover() {
clearInterval(move);
$('.newGame').css('visibility', 'visible');
}