HTML/JAVASCRIPT/CSS simple function logic failure - javascript

My issue is with function onBall3Click1 (The code is at the bottom).
The ball, on click, is supposed to function as a lightbulb: when it's ON -> YELLOW color within ball, when it's OFF -> GRAY.
I have been covering the logic behind it for way too long for something so simple, and I just can't find the issue..
When I click on it, it changes the text to 'ON', but the colour remains gray..when it should be yellow.
Thanks in advance!
<html>
<head>
<style>
body {
background-color: black;
text-align: center;
}
h1 {
color: white;
}
div {
width: 100px;
height: 100px;
margin: auto;
margin-bottom: 10px;
border-radius: 50%;
transition: 0.3s;
line-height: 50px;
color: black
}
.ball1 {
background-color: yellow;
border: 6px solid gray;
color: black
}
.ball2 {
background-color: orange;
}
.ball3 {
background-color: gray;
}
.ball4 {
background-color: brown;
}
</style>
</head>
<body>
<h1>The Ball</h1>
<div class="ball1" onclick="onBall1Click()">
GROW 250 ORANGE
</div>
<div class="ball2" onclick="onBall2Click()">
GROW+50 SHRINK-50
</div>
<div class="ball3" onclick="onBall3Click1()">
OFF
</div>
<div class="ball4" onclick="onBall4Click()">
PROMPT
</div>
<script>
var ball1Size = 100;
var ball1SizeStep = 50;
function onBall1Click() {
var ball1 = document.querySelector('.ball1');
ball1Size = ball1Size + 50;
if (ball1Size > 400) {
ball1Size = 100;
}
ball1.innerText = ball1Size;
ball1.style.width = ball1Size;
ball1.style.height = ball1Size;
ball1.innerText = ball1Size;
if (ball1Size == 250) {
ball1.style.color = 'Orange';
} else {
ball1.style.color = 'black'
}
}
var ball2Size = 100;
var ball2SizeStep = 50;
function onBall2Click() {
var ball2 = document.querySelector('.ball2');
ball2Size += ball2SizeStep;
if (ball2Size === 400) {
ball2SizeStep = -50;
} else if (ball2Size === 100) {
ball2SizeStep = 50;
}
if (ball2Size > 100) {
ball2.style.backgroundColor = 'red';
} else if (ball2Size === 100) {
ball2.style.backgroundColor = 'Orange';
}
ball2.innerText = ball2Size;
ball2.style.width = ball2Size;
ball2.style.height = ball2Size;
}
function onBall3Click1() {
var ball3 = document.querySelector('.ball3');
console.log("HII0");
if (ball3.innerText == 'OFF') {
ball3.innerText = 'ON';
} else if (ball3.innerText == 'ON') {
ball3.innerText = 'OFF'
}
console.log(ball3.style.backgroundColor)
if (ball3.style.backgroundColor === 'gray') {
console.log("HII1");
ball3.style.backgroundColor = 'Yellow';
} else if (ball3.style.backgroundColor == 'Yellow') {
console.log("HII1");
ball3.style.backgroundColor = 'gray'
}
}
var ball4Size = 100;
function onBall4Click() {
var ball4 = document.querySelector('.ball4');
var user_input = prompt('Write ball size number 4 but do not exaggerate : ')
let user_input_int = parseInt(user_input)
console.log(user_input_int);
if (user_input_int < 1000) {
ball4.style.width = user_input_int;
ball4.style.height = user_input_int;
} else {
alert("Too big!");
}
}
</script>
</body>
</html>

You could merge the two if/elseif chains in the onBall3Click1 function like so:
function onBall3Click1() {
var ball3 = document.querySelector('.ball3');
console.log("HII0");
if (ball3.innerText == 'OFF') {
ball3.innerText = 'ON';
ball3.style.backgroundColor = 'yellow';
} else if (ball3.innerText == 'ON') {
ball3.innerText = 'OFF'
ball3.style.backgroundColor = 'gray'
}
console.log(ball3.style.backgroundColor)
}

Related

Window Not Scrolling When Content Fills It Up So New Content Not Visible Without Scrolling

I am currently constructing a roulette system programme ( this is more to keep me from betting than to bet! ) and am just doing the basic framework but already hit a problem with the main window '#results' not scrolling when it is filled with the results. The scroll needs to follow the latest line of content so the latest returned from the input in the modal box is always showing at the bottom. I have spent hours on lots of possible solutions to no avail.
Here is the code: ( i apologise for the length of the full script )
<!DOCTYPE html>
<html>
<body>
<div id="results">
</div>
<div id="modal">
<div id="modal-content">
<p>Select a number between 0 and 36:</p>
<div id="numberButtons"></div>
<button id="close-button" onclick="closeModal()">Close</button>
</div>
</div>
</div>
<style>
/* The modal background */
#modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
}
/* The modal content */
#modal-content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #fefefe;
padding: 20px;
width: 18%;
border: 3px solid black;
}
/* The close button */
#close-button {
display: block;
margin: 0 auto;
}
#numberButtons button {
color: white;
width: 50px;
height: 50px;
font-size:30px;
font-weight:600;
}
#modal.inactive{
opacity: 0.2;
}
</style>
<script>
var bankRoll = parseFloat(prompt("Please enter your starting bankroll:"));
if(isNaN(bankRoll)){
bankRoll = parseFloat(prompt("Invalid input. Please enter a valid number for your starting bankroll:"));
}
bankRoll = bankRoll.toFixed(2);
var spinNumber=0;
var backline="";
var isDragging = false;
var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;
const modalContent = document.querySelector("#modal-content");
modalContent.addEventListener("mousedown", dragStart);
modalContent.addEventListener("mouseup", dragEnd);
modalContent.addEventListener("mousemove", drag);
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
if (e.target === modalContent) {
isDragging = true;
}
}
let inactivityTimeout;
function dragEnd(e) {
initialX = currentX;
initialY = currentY;
isDragging = false;
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(() => {
modal.classList.add("inactive")
}, 15000)
}
function drag(e) {
if (e.buttons === 1) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, modalContent);
clearTimeout(inactivityTimeout);
modal.classList.remove("inactive")
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
function getNumberType(number) {
if (number === 0) {
return "green";
} else if (number % 2 === 0) {
return "even";
} else {
return "odd";
}
}
function roulette(number) {
// Determine the color of the number
var color;
if (number === 0) {
color = "Green";
} else if (number === 1 || number === 3 || number === 5 || number === 7 || number === 9 || number === 12 || number === 14 || number === 16 || number === 18 || number === 19 || number === 21 || number === 23 || number === 25 || number === 27 || number === 30 || number === 32 || number === 34 || number === 36) {
color = "Red";
} else {
color = "Black";
}
// Map the color names to CSS color values
if (color === "Green") {
return "rgb(0, 128, 0)";
} else if (color === "Red") {
return "rgb(255, 0, 0)";
} else {
return "rgb(0, 0, 0)";
}
}
function backgroundline() {
if (spinNumber % 2 === 0) {
backline="#D3D3D3"
} else {
backline="#E5E4E2";
}
}
function spin(number) {
// Determine the color of the number
var color = roulette(number);
spinNumber= spinNumber+1;
bankRoll=bankRoll-10;
backgroundline();
// Display the result
var resultsDiv = document.getElementById("results");
var resultHTML = `${number}`;
resultHTML = `<div style="padding:10px 0; background: ${backline};vertical-align:middle;margin-bottom:- 20px;">
<div style="padding:5px; display: inline-block; background: yellow; color:black;vertical-align:middle; width:30px; text-align:right;">${spinNumber}</div>
<div style="margin: 0 10px; display:inline-block; width: 70px; text-align:center;vertical-align:middle">£ ${bankRoll}</div>
<div style="color: white; padding: 5px; display: inline-block; width:30px; padding-top:15px;vertical-align:middle; font-size: 25px; font-weight:600; height:30px; text-align:center; background-color: ${color}; ">${resultHTML}</div>
</div>
<br style="height:0px;"/>`;
resultsDiv.innerHTML += resultHTML;
}
// Set up the buttons
for (let i = 0; i <= 36; i++) {
let button = document.createElement("button");
button.innerHTML = i;
button.style.backgroundColor = roulette(i);
button.addEventListener("click", function() {
spin(i);
});
document.getElementById("numberButtons").appendChild(button);
}
function closeModal() {
// Get the modal element
var modal = document.getElementById("modal");
// Remove the modal element from the DOM
modal.remove();
}
</script>
</body>
</html>
I have tried lots of solutions on Stack Overflow and across the Internet further field that I thought might work but it just doesn't seem to want to do it.
after adding element in Results div you have to call this function.
add this function
window.scrollTo(0, document.body.scrollHeight)
after this line
resultsDiv.innerHTML += resultHTML;

Difficulties with Button Activation in JavaScript

I am currently having issues with a game I am making for fun. I am quite new to Javascript, HTML, and CSS, hence the code that will be shown will not be very good. Anyway, the issue I am experiencing is the button activation part of my code not functioning. Here is the code (in case there are other errors), and the specific problematic area is highlighted.
//Variables and Other Basic Things
var Specs = ["Basic", "Advanced", "Insane", "Mythical", "Godly"];
var PlayerRanks = ["Begginer Grinder", "Advanced Grinder", "Insane Grinder", "Mythic Grinder", "Godlike Grinder"];
var Random = 1;
//Random Numbers
function RandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//Player Things
var Player = {
spec: "Plain",
rank: "Begginer Grinder",
points: 1000,
pointIncreaseAmount: 1,
timeToIncrease: 10000,
levelIncrease: function() {
this.points += this.pointIncreaseAmount
}
}
//Stats of different specs
function StatChange() {
if (Player.spec == "Basic") {
Player.pointIncreaseAmount = 2;
Player.timeToIncrease = 5000;
} else if (Player.spec == "Advanced") {
Player.pointIncreaseAmount = 5;
Player.timeToIncrease = 4000;
} else if (Player.spec == "Epic") {
Player.pointIncreaseAmount = 10;
Player.timeToIncrease = 3000;
} else if (Player.spec == "Mythical") {
Player.pointIncreaseAmount = 25;
Player.timeToIncrease = 2000;
} else if (Player.spec == "Godly") {
Player.pointIncreaseAmount = 50;
Player.timeToIncrease = 1000;
}
document.getElementById("SpecDisplay").innerHTML = "Your current spec is " + Player.spec;
}
function OpenBasicCrate() {
Random = RandomInt(1, 129);
if (Random < 75) {
Player.spec = "Basic";
Random = 1;
} else if (Random >= 75 && Random < 120) {
Player.spec = "Advanced";
Random = 1;
} else if (Random >= 120 && Random < 129) {
Player.spec = "Epic";
Random = 1;
}
StatChange();
}
function OpenBetterCrate() {
Random = RandomInt(1, 105);
if (Random < 30) {
Player.spec = "Basic";
Random = 1;
} else if (Random >= 30 && Random < 85) {
Player.spec = "Advanced";
Random = 1;
} else if (Random >= 85 && Random <= 105) {
Player.spec = "Epic";
Random = 1;
}
StatChange();
}
function OpenAdvancedCrate() {
Random = RandomInt(1, 80);
if (Random < 30) {
Player.spec = "Advanced";
Random = 1;
} else if (Random >= 30 && Random <= 70) {
Player.spec = "Epic";
Random = 1;
} else if (Random >= 70 && Random < 80) {
PLayer.spec = "Mythical";
Random = 1;
}
StatChange();
}
function OpenBetterAdvancedCrate() {
Random = RandomInt(1, 85);
if (Random < 80) {
Player.spec = "Mythical";
Random = 1;
} else if (Random >= 80 && Random <= 85) {
Player.spec = "Epic";
Random = 1;
}
StatChange();
}
function OpenMythicalCrate() {
Random = RandomInt(1, 100);
if (Random < 95) {
Player.spec = "Mythical";
Random = 1;
} else if (Random >= 95 && Random < 100) {
Player.spec = "Godly";
Random = 1;
}
}
//Start Command also Repeating Code
function Start() {
const pointGain = setInterval(function() {
Player.levelIncrease()
}, Player.timeToIncrease);
const alertPoints = setInterval(function() {
document.getElementById("Score").innerHTML = "Score: " + Player.points
}, 101);
}
//Checking button clicks
if (document.getElementById('Start').clicked == true) {
Start(); //Start button
}
//Checking crates and if the buttons are pressed
//HERE
if (document.getElementById("OpenCrateA").clicked == true) {
if (Player.points >= 50) {
OpenBasicCrate();
Player.points -= 50;
} else if (Player.points < 50) {
document.getElementById("DisplayError").style.display = "block";
setTimeout(function() {
document.getElementById("DisplayError").style.display = "none";
}, 3000);
}
}
if (document.getElementById("OpenCrateB").clicked == true) {
if (Player.points >= 125) {
OpenBetterCrate();
Player.points -= 125;
} else if (Player.points < 125) {
document.getElementById("DisplayError").style.display = "block";
setTimeout(function() {
document.getElementById("DisplayError").style.display = "none";
}, 3000); // Come back here later
}
}
if (document.getElementById("OpenCrateC").clicked == true) {
if (Player.points >= 300) {
OpenAdvancedCrate();
Player.points -= 300;
} else if (Player.points < 300) {
document.getElementById("DisplayError").style.display = "block";
setTimeout(function() {
document.getElementById("DisplayError").style.display = "none";
}, 3000);
}
}
if (document.getElementById("OpenCrateD").clicked == true) {
if (Player.points >= 1500) {
OpenBetterAdvancedCrate();
Player.points -= 1500;
} else if (Player.points < 1500) {
document.getElementById("DisplayError").style.display = "block";
setTimeout(function() {
document.getElementById("DisplayError").style.display = "none";
}, 3000);
}
}
if (document.getElementById("OpenCrateE").clicked == true) {
if (Player.points >= 15000) {
OpenMythicalCrate();
Player.points -= 15000;
} else if (Player.points < 15000) {
document.getElementById("DisplayError").style.display = "block";
setTimeout(function() {
document.getElementById("DisplayError").style.display = "none";
}, 3000);
}
}
//TO HERE
body {
background-image: url(https://cdn.discordapp.com/attachments/656847228219949067/855371548860350474/backgroundImage.png);
height: 500px;
width: 800px;
font-family: "Lucida Console", "Courier New", monospace;
}
img {
position: absolute;
right: 5px;
top: 375px;
width: 150px;
height: 150px;
outline: 3px dotted black;
}
.OpenCrateA {
background-image: url(https://cdn.discordapp.com/attachments/656847228219949067/855379404020121620/backgroundImage.png);
width: 100px;
height: 100px;
position: absolute;
top: 425px;
left: 5px;
outline: 2px solid black;
}
.OpenCrateB {
background-image: url(https://cdn.discordapp.com/attachments/656847228219949067/855379943093829642/backgroundImage.png);
width: 100px;
height: 100px;
position: absolute;
top: 425px;
left: 110px;
outline: 2px solid black;
}
.OpenCrateC {
background-image: url(https://cdn.discordapp.com/attachments/656847228219949067/855379735671865344/backgroundImage.png);
width: 100px;
height: 100px;
position: absolute;
top: 425px;
left: 215px;
outline: 2px solid black;
}
.OpenCrateD {
background-image: url(https://cdn.discordapp.com/attachments/656847228219949067/855380083225526282/backgroundImage.png);
width: 100px;
height: 100px;
position: absolute;
top: 425px;
left: 320px;
outline: 2px solid black;
}
.OpenCrateE {
background-image: url(https://cdn.discordapp.com/attachments/656847228219949067/855380283788492810/backgroundImage.png);
width: 100px;
height: 100px;
position: absolute;
top: 425px;
left: 425px;
outline: 2px solid black;
}
.Start {
width: 100;
height: 30;
font-family: "Lucida Console", "Courier New", monospace;
background-color: red;
outline: 2px solid black;
}
.InstructionMenu {
background-color: blue;
outline: 2px solid black
}
h1 {
font-family: "Lucida Console", "Courier New", monospace;
}
.RankDisplay {
position: absolute;
top: 375px;
background-color: blue;
outline: 3px solid black;
}
<script src="script.js"></script>
<h1 id="welcomingScreen">Welcome to "A Bad Grinding Game!"</h1>
<button id="StartButton" class="Start" onclick="Start()">Start</button>
<p id="Score"> Score: </p>
<p id="RankDisplay" class="RankDisplay"> Your current rank is: "Begginer Grinder"</p>
<p id="SpecDisplay" class="SpecDisplay"> Your current spec is "Plain"</p>
<h2 id="InstructionsMenu" class="InstructionMenu" style="display:none">Instrutions:</h2>
<p id="InstructionsMenu" class="InstructionMenu" style="display:none"> This is a simple grinding game. You have a "spec", which allows you to gain a specific amount of "points" per a specific amount of time. The longer you grind, the better your rank becomes, and a better rank gives a slight point increase. </p>
<p id="DisplayError" style="display:none"> You do not have enough money to purchase this crate!</p>
<img src="https://cdn.discordapp.com/attachments/656847228219949067/855161969615175680/ABGG_icon.png"></img>
<button type="button" class="OpenCrateA" id="OpenCrateA">Open Crate 1</p>
<button type="button" class="OpenCrateB" id="OpenCrateB">Open Crate 2 </button>
<button type="button" class="OpenCrateC" id="OpenCrateC">Open Crate 3 </button>
<button type="button" class="OpenCrateD" id="OpenCrateD">Open Crate 4 </button>
<button type="button" class="OpenCrateE" id="OpenCrateE">Open Crate 5 </button>
Your button activation logic is not working because you're checking if button.clicked == true. As far as I am aware, button HTML events don't even have a clicked property.
Even if they did, while you are indeed correct that that would check if a button is pressed, it would only so once, right when the user first loads the page, so any subsequent presses would be ignored.
The method you are looking for is button.onclick, which you can read about here. With it, your code would look something like:
document.getElementById("OpenCrateA").onclick = function(){
if (Player.points >= 50){
OpenBasicCrate();
Player.points -= 50;
}
else if (Player.points < 50){
document.getElementById("DisplayError").style.display = "block";
setTimeout(function(){ document.getElementById("DisplayError").style.display = "none"; }, 3000);
}
}
This registers a listener for the button's click event, which will trigger whenever the button is pressed and call the logic that you define.
Another issue you may face is that the button element you are trying to select is not defined. This would occur due to your <script> tag being at the top of your HTML, so it runs before any of your HTML is even rendered. I would suggest moving it to the bottom of your HTML <body>

Snake Code - Make the face of the snake an image

I would like to make the face of this snake an image. Currently, it using a fill style with a color but I would like it to be an image. How can I do it with this code?
In addition, I want to find out how to add arrows so that it could work on a mobile phone. Thank you for anyone who can help or provide insight.
(function() {
/////////////////////////////////////////////////////////////
// Canvas & Context
var canvas;
var ctx;
// Snake
var snake;
var snake_dir;
var snake_next_dir;
var snake_speed;
// Food
var food = {
x: 0,
y: 0
};
// Score
var score;
// Wall
var wall;
// HTML Elements
var screen_snake;
var screen_menu;
var screen_setting;
var screen_gameover;
var button_newgame_menu;
var button_newgame_setting;
var button_newgame_gameover;
var button_setting_menu;
var button_setting_gameover;
var ele_score;
var speed_setting;
var wall_setting;
/////////////////////////////////////////////////////////////
var activeDot = function(x, y) {
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(x * 10, y * 10, 10, 10);
}
/////////////////////////////////////////////////////////////
var changeDir = function(key) {
if (key == 38 && snake_dir != 2) {
snake_next_dir = 0;
} else {
if (key == 39 && snake_dir != 3) {
snake_next_dir = 1;
} else {
if (key == 40 && snake_dir != 0) {
snake_next_dir = 2;
} else {
if (key == 37 && snake_dir != 1) {
snake_next_dir = 3;
}
}
}
}
}
/////////////////////////////////////////////////////////////
var addFood = function() {
food.x = Math.floor(Math.random() * ((canvas.width / 10) - 1));
food.y = Math.floor(Math.random() * ((canvas.height / 10) - 1));
for (var i = 0; i < snake.length; i++) {
if (checkBlock(food.x, food.y, snake[i].x, snake[i].y)) {
addFood();
}
}
}
/////////////////////////////////////////////////////////////
var checkBlock = function(x, y, _x, _y) {
return (x == _x && y == _y) ? true : false;
}
/////////////////////////////////////////////////////////////
var altScore = function(score_val) {
ele_score.innerHTML = String(score_val);
}
/////////////////////////////////////////////////////////////
var mainLoop = function() {
var _x = snake[0].x;
var _y = snake[0].y;
snake_dir = snake_next_dir;
// 0 - Up, 1 - Right, 2 - Down, 3 - Left
switch (snake_dir) {
case 0:
_y--;
break;
case 1:
_x++;
break;
case 2:
_y++;
break;
case 3:
_x--;
break;
}
snake.pop();
snake.unshift({
x: _x,
y: _y
});
// --------------------
// Wall
if (wall == 1) {
// On
if (snake[0].x < 0 || snake[0].x == canvas.width / 10 || snake[0].y < 0 || snake[0].y == canvas.height / 10) {
showScreen(3);
return;
}
} else {
// Off
for (var i = 0, x = snake.length; i < x; i++) {
if (snake[i].x < 0) {
snake[i].x = snake[i].x + (canvas.width / 10);
}
if (snake[i].x == canvas.width / 10) {
snake[i].x = snake[i].x - (canvas.width / 10);
}
if (snake[i].y < 0) {
snake[i].y = snake[i].y + (canvas.height / 10);
}
if (snake[i].y == canvas.height / 10) {
snake[i].y = snake[i].y - (canvas.height / 10);
}
}
}
// --------------------
// Autophagy death
for (var i = 1; i < snake.length; i++) {
if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
showScreen(3);
return;
}
}
// --------------------
// Eat Food
if (checkBlock(snake[0].x, snake[0].y, food.x, food.y)) {
snake[snake.length] = {
x: snake[0].x,
y: snake[0].y
};
score += 1;
altScore(score);
addFood();
activeDot(food.x, food.y);
}
// --------------------
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// --------------------
for (var i = 0; i < snake.length; i++) {
activeDot(snake[i].x, snake[i].y);
}
// --------------------
activeDot(food.x, food.y);
// Debug
//document.getElementById("debug").innerHTML = snake_dir + " " + snake_next_dir + " " + snake[0].x + " " + snake[0].y;
setTimeout(mainLoop, snake_speed);
}
/////////////////////////////////////////////////////////////
var newGame = function() {
showScreen(0);
screen_snake.focus();
snake = [];
for (var i = 4; i >= 0; i--) {
snake.push({
x: i,
y: 15
});
}
snake_next_dir = 1;
score = 0;
altScore(score);
addFood();
canvas.onkeydown = function(evt) {
evt = evt || window.event;
changeDir(evt.keyCode);
}
mainLoop();
}
/////////////////////////////////////////////////////////////
// Change the snake speed...
// 150 = slow
// 100 = normal
// 50 = fast
var setSnakeSpeed = function(speed_value) {
snake_speed = speed_value;
}
/////////////////////////////////////////////////////////////
var setWall = function(wall_value) {
wall = wall_value;
if (wall == 0) {
screen_snake.style.borderColor = "#606060";
}
if (wall == 1) {
screen_snake.style.borderColor = "#FFFFFF";
}
}
/////////////////////////////////////////////////////////////
// 0 for the game
// 1 for the main menu
// 2 for the settings screen
// 3 for the game over screen
var showScreen = function(screen_opt) {
switch (screen_opt) {
case 0:
screen_snake.style.display = "block";
screen_menu.style.display = "none";
screen_setting.style.display = "none";
screen_gameover.style.display = "none";
break;
case 1:
screen_snake.style.display = "none";
screen_menu.style.display = "block";
screen_setting.style.display = "none";
screen_gameover.style.display = "none";
break;
case 2:
screen_snake.style.display = "none";
screen_menu.style.display = "none";
screen_setting.style.display = "block";
screen_gameover.style.display = "none";
break;
case 3:
screen_snake.style.display = "none";
screen_menu.style.display = "none";
screen_setting.style.display = "none";
screen_gameover.style.display = "block";
break;
}
}
/////////////////////////////////////////////////////////////
window.onload = function() {
canvas = document.getElementById("snake");
ctx = canvas.getContext("2d");
// Screens
screen_snake = document.getElementById("snake");
screen_menu = document.getElementById("menu");
screen_gameover = document.getElementById("gameover");
screen_setting = document.getElementById("setting");
// Buttons
button_newgame_menu = document.getElementById("newgame_menu");
button_newgame_setting = document.getElementById("newgame_setting");
button_newgame_gameover = document.getElementById("newgame_gameover");
button_setting_menu = document.getElementById("setting_menu");
button_setting_gameover = document.getElementById("setting_gameover");
// etc
ele_score = document.getElementById("score_value");
speed_setting = document.getElementsByName("speed");
wall_setting = document.getElementsByName("wall");
// --------------------
button_newgame_menu.onclick = function() {
newGame();
};
button_newgame_gameover.onclick = function() {
newGame();
};
button_newgame_setting.onclick = function() {
newGame();
};
button_setting_menu.onclick = function() {
showScreen(2);
};
button_setting_gameover.onclick = function() {
showScreen(2)
};
setSnakeSpeed(150);
setWall(1);
showScreen("menu");
// --------------------
// Settings
// speed
for (var i = 0; i < speed_setting.length; i++) {
speed_setting[i].addEventListener("click", function() {
for (var i = 0; i < speed_setting.length; i++) {
if (speed_setting[i].checked) {
setSnakeSpeed(speed_setting[i].value);
}
}
});
}
// wall
for (var i = 0; i < wall_setting.length; i++) {
wall_setting[i].addEventListener("click", function() {
for (var i = 0; i < wall_setting.length; i++) {
if (wall_setting[i].checked) {
setWall(wall_setting[i].value);
}
}
});
}
document.onkeydown = function(evt) {
if (screen_gameover.style.display == "block") {
evt = evt || window.event;
if (evt.keyCode == 32) {
newGame();
}
}
}
}
})();
::selection {
color: #FFFFFF;
background: transparent;
}
::-moz-selection {
color: #FFFFFF;
background: transparent;
}
* {
margin: 0;
padding: 0;
font-family: "VT323";
}
body {
background-color: #000000;
}
.wrap {
margin-left: auto;
margin-right: auto;
}
header {
width: 340px;
font-size: 0;
}
canvas {
display: none;
border-style: solid;
border-width: 10px;
border-color: #FFFFFF;
}
canvas:focus {
outline: none;
}
/* Top Styles */
h1 {
display: inline-block;
width: 100px;
font-size: 32px;
color: #FFFFFF;
}
.score {
display: inline-block;
width: 240px;
font-size: 20px;
color: #FFFFFF;
text-align: right;
}
.score_value {
font-size: inherit;
}
/* All screens style */
#gameover a,
#setting a,
#menu a {
display: block;
}
#gameover a,
#setting a:hover,
#menu a:hover {
cursor: pointer;
}
#gameover a:hover::before,
#setting a:hover::before,
#menu a:hover::before {
content: ">";
margin-right: 10px;
}
/* Menu Screen Style */
#menu {
display: block;
width: 340px;
padding-top: 95px;
padding-bottom: 95px;
font-size: 40px;
margin-left: auto;
margin-right: auto;
text-align: center;
color: #FFF;
}
#menu h2 {
-webkit-animation: logo-ani 1000ms linear infinite;
animation: logo-ani 1000ms linear infinite;
margin-bottom: 30px;
}
#menu a {
font-size: 30px;
}
#-webkit-keyframes logo-ani {
50% {
-webkit-transform: scale(1.3, 1.3);
}
100% {
-webkit-transform: scale(1.0, 1.0);
}
}
#keyframes logo-ani {
50% {
transform: scale(1.3, 1.3);
}
100% {
transform: scale(1.0, 1.0);
}
}
/* Game Over Screen Style */
#gameover {
display: none;
width: 340px;
padding-top: 95px;
padding-bottom: 95px;
margin-left: auto;
margin-right: auto;
text-align: center;
font-size: 30px;
color: #FFF;
}
#gameover p {
margin-top: 25px;
font-size: 20px;
}
/* Settings Screen Style */
#setting {
display: none;
width: 340px;
margin-left: auto;
margin-right: auto;
padding-top: 85px;
padding-bottom: 85px;
font-size: 30px;
color: #FFF;
text-align: center;
}
#setting h2 {
margin-bottom: 15px;
}
#setting p {
margin-top: 10px;
}
#setting input {
display: none;
}
#setting label {
cursor: pointer;
}
#setting input:checked+label {
background-color: #FFF;
color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<header class="wrap">
<h1>Snake</h1>
<p class="score">Score: <span id="score_value">0</span></p>
</header>
<canvas class="wrap" id="snake" width="320" height="320" tabindex="1"></canvas>
<!-- Game Over Screen -->
<div id="gameover">
<h2>Game Over</h2>
<p>press <span style="background-color: #FFFFFF; color: #000000">space</span> to begin a</p>
<a id="newgame_gameover">new game</a>
<a id="setting_gameover">settings</a>
</div>
<!-- Setting screen -->
<div id="setting">
<h2>Settings</h2>
<a id="newgame_setting">new game</a>
<p>Speed:
<input id="speed1" type="radio" name="speed" value="120" checked/>
<label for="speed1">Slow</label>
<input id="speed2" type="radio" name="speed" value="75" />
<label for="speed2">Normal</label>
<input id="speed3" type="radio" name="speed" value="35" />
<label for="speed3">Fast</label>
</p>
<p>Wall:
<input id="wallon" type="radio" name="wall" value="1" checked/>
<label for="wallon">On</label>
<input id="walloff" type="radio" name="wall" value="0" />
<label for="walloff">Off</label>
</p>
</div>
<!-- Main Menu Screen -->
<div id="menu">
<h2>Snake</h2>
<a id="newgame_menu">new game</a>
<a id="setting_menu">settings</a>
</div>
Convert your image to a base64 string, then for the first dot/head use the image instead:
var img = new Image(); // Create new img element
img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAA21BMVEXoTTvqTTzpUD7nTjzmTTvrUkDpTjzmSznUPSrVPCrnTDrSOSfTOizlTDrvoJnoqJ/pVkTmU0P5urH1p53mSTjjPiv7nZF0f4NZaGvpn5b9s6qDl5iira/+nI/jPirkPyz7lop+iYtleHzsnpT7raOTpqqqtbf4lovnSjf0lorylonpSDbnTDj5oZf2mIzlSDXkOyjIY1vrd2rrWEbZZ1zYQDLsTTroTz/lRjPalY7+///////j19fVSz7tTjvmTjntRjPialzZhH3sVkXsSzniRTTYQTDmSTbmTT3qb45jAAAAAWJLR0Q7OQ70bAAAAAd0SU1FB+QEDw4AEYzMSFoAAABvSURBVAjXY2BgZGJiZmFlZWNgYGDn4GTn4ubhBTJZ+PgFBIWERdgYRMXEJSSlpGVk5RjkFRSVlFVU1dTlGRg0NLW0dXT19JkZGNgMDI2MTUzNgNrMLSytrG1s7eyBbGYHRydnFwYwYHN1c/dgYAAAtKsKjnGo4BwAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjAtMDQtMTVUMTQ6MDA6MTctMDQ6MDAVi7z/AAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIwLTA0LTE1VDE0OjAwOjE3LTA0OjAwZNYEQwAAAABJRU5ErkJggg==";
for (var i = 0; i < snake.length; i++) {
if (!i) {
ctx.drawImage(img, snake[i].x * 10, snake[i].y * 10);
} else {
activeDot(snake[i].x, snake[i].y);
}
}

stopping setTimeout loop in my snake game?

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');
}

eventlistener javascript problems

I'm trying to learn Javascript and at the moment and I am working on AddEventListener.
What I'm trying to do is to add a new row and so far it works.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
.colorOrange {
background-color: orange;
}
.colorBlue {
background-color: blue;
}
.colorYellow {
background-color: yellow;
}
.colorGray {
background-color: gray;
}
.colorRed {
background-color: red;
}
.colorGreen {
background-color: green;
}
.colorWhite {
background-color: white;
}
#main {
margin: 0 auto;
width: 325px;
text-align: center;
background-color: gray;
}
.row {
width: 300px;
padding: 10px;
border: 1px solid black;
display: block;
}
.hideButton, .mainText, .deleteButton {
margin: 0 auto;
padding: 10px;
border: 1px solid black;
display: inline;
}
.btn {
}
</style>
</head>
<body>
<div id="main">
<div class="AddBtn btn">Add</div>
<input type="text" id="txtBox" name="text till ruta" />
</div>
<script>
var rownr = 0;
function addListeners() {
var addButton = document.getElementsByClassName('AddBtn');
for (var i = 0; i < addButton.length; i++) {
var addBtn = addButton[i];
addBtn.addEventListener('click', function () {
var elBtn = event.srcElement;
var valueBtn = elBtn.textContent;
alert(valueBtn);
hideOrShow();
addRow();
function addRow() {
switch (valueBtn) {
case "Add":
var input = document.getElementById('txtBox').value;
rownr++;
var div = document.createElement('div');
div.className = "row";
document.getElementById("main").appendChild(div);
var div2 = document.createElement('div');
div2.className = "hideButton colorGreen";
var tx = document.createTextNode("<");
div2.appendChild(tx);
div2.addEventListener('click', hideOrShow, false);
div.appendChild(div2);
var div3 = document.createElement("div");
if (input.toLowerCase() == "red") {
div3.className = "mainText colorRed";
}
else if (input.toLowerCase() == "orange") {
div3.className = "mainText colorOrange";
}
else if (input.toLowerCase() == "blue") {
div3.className = "mainText colorBlue";
}
else if (input.toLowerCase() == "yellow") {
div3.className = "mainText colorYellow";
}
else if (input.toLowerCase() == "gray") {
div3.className = "mainText colorGray";
} else {
div3.className = "mainText colorWhite";
}
tx = document.createTextNode(rownr + " " + input);
div3.appendChild(tx);
div.appendChild(div3);
var div4 = document.createElement("div");
div4.className = "deleteButton colorRed";
tx = document.createTextNode("X");
div4.appendChild(tx);
//div4.addEventListener('click', deleBtn, false);
div.appendChild(div4);
var linebreak = document.createElement("br");
div.appendChild(linebreak);
default:
}
}
So far everything works as I want it to do. But when I click on "<" it will go in to this function and find all tags with the hideButton class in it.
The first click it won't find anything, but the second time it will find the "<" value and an alert window will popup and show the value. Here is where I
get lost and can't get it to work. When you click the the third time it will
loop or whatever to call it - anyway it will show the alert window 2 times and
then if you repeat the same click it will do the same thing 3 times and so it goes.
function hideOrShow() {
var hideButton = document.getElementsByClassName('hideButton');
for (var j = 0; j < hideButton.length; j++) {
hideBtn = hideButton[j];
hideBtn.addEventListener('click', function () {
var hideElBtn = event.srcElement;
var valueHideBtn = hideElBtn.textContent;
alert(valueHideBtn);
}, false);
}
}
}, false);
}
}
window.onload = addListeners;
</script>
</body>
</html>
The goal with this exercise is that
when you click add button add the text from the input field and add that text to the new row.
and "<" shall hide the row and change it to ">" to show it again
and "X" shall just delete the row.
But what I need help with is finding the value part that I mentioned above.
Here is my rework of your javascript. I explained my solution in your comment, but it may be a bit more clear if illustrated.
In the addListeners function, I removed the hideOrShow call as it shouldn't be called in the add button.
Next, I removed the for loop in the hideOrShow method as you really are only after the caller. I also removed the addEventListener call in the same method as you already have an event listener on that element, so there's no need to add one again.
var rownr = 0;
function addListeners() {
var addButton = document.getElementsByClassName('AddBtn');
for (var i = 0; i < addButton.length; i++) {
var addBtn = addButton[i];
addBtn.addEventListener('click', function () {
var elBtn = event.srcElement;
var valueBtn = elBtn.textContent;
alert(valueBtn);
//hideOrShow();
addRow();
function addRow() {
switch (valueBtn) {
case "Add":
var input = document.getElementById('txtBox').value;
rownr++;
var div = document.createElement('div');
div.className = "row";
document.getElementById("main").appendChild(div);
var div2 = document.createElement('div');
div2.className = "hideButton colorGreen";
var tx = document.createTextNode("<");
div2.appendChild(tx);
div2.addEventListener('click', hideOrShow, false);
div.appendChild(div2);
var div3 = document.createElement("div");
if (input.toLowerCase() == "red") {
div3.className = "mainText colorRed";
}
else if (input.toLowerCase() == "orange") {
div3.className = "mainText colorOrange";
}
else if (input.toLowerCase() == "blue") {
div3.className = "mainText colorBlue";
}
else if (input.toLowerCase() == "yellow") {
div3.className = "mainText colorYellow";
}
else if (input.toLowerCase() == "gray") {
div3.className = "mainText colorGray";
} else {
div3.className = "mainText colorWhite";
}
tx = document.createTextNode(rownr + " " + input);
div3.appendChild(tx);
div.appendChild(div3);
var div4 = document.createElement("div");
div4.className = "deleteButton colorRed";
tx = document.createTextNode("X");
div4.appendChild(tx);
//div4.addEventListener('click', deleBtn, false);
div.appendChild(div4);
var linebreak = document.createElement("br");
div.appendChild(linebreak);
default:
}
}
function hideOrShow() {
var hideButton = document.getElementsByClassName('hideButton');
var hideElBtn = event.srcElement;
var valueHideBtn = hideElBtn.textContent;
alert(valueHideBtn);
}
}, false);
}
}
window.onload = addListeners;

Categories

Resources