Overlapping Elements and Collision Detector with this code - javascript

I'm trying to create a collision detector between the cart and the grey areas. When the cart hits a grey item, it should be sent back to the top: 450px and left: 620px. However, I keep getting a null value error that says 'Cannot read properties of null.' I was told that using an elementsOverlap function would do the trick, but I'm still getting this error. Is there a way to solve this?
document.addEventListener("keydown", move);
//cart.style.left = "620px";
//cart.style.top = "450px";
var block1 = document.getElementById("block1");
var block2 = document.getElementById("block2");
var block3 = document.getElementById("block3");
var block4 = document.getElementById("block4");
function elementsOverlap(el1, el2) {
const domRect1 = el1.getBoundingClientRect();
const domRect2 = el2.getBoundingClientRect();
return !(
domRect1.top > domRect2.bottom ||
domRect1.right < domRect2.left ||
domRect1.bottom < domRect2.top ||
domRect1.left > domRect2.right
);
}
console.log("...");
timer();
function timer(){
var time = 60;
interval = setInterval(()=>{
time--;
document.getElementById("countdown").innerHTML = time;
if(time <= 0){
document.getElementById("countdown").innerHTML = "You lose!"
}
}, 1000);
}
function move(e){
if(e.keyCode == 39 || e.keyCode == 68){
let cart = document.getElementById("cart");
let go = parseInt(cart.style.left) + 20;
let lives = 3;
cart.style.left = go;
console.log("...");
if(elementsOverlap(cart, block1)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block2)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block3)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block4)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
// if(parseInt(target.style.left) >= 1000){
// window.location.href = "../cutscene2/cutscene2.html";
// }
// check(redRing1Width, redRing1Left, redRing1Top, parseInt(target.style.left), parseInt(target.style.top));
// check(redRing2Width, redRing2Left, redRing2Top, parseInt(target.style.left), parseInt(target.style.top));
}
if(e.keyCode == 37 || e.keyCode == 65){
let cart = document.getElementById("cart");
let go = parseInt(cart.style.left) - 20;
cart.style.left = go;
console.log("...");
console.log(parseInt(cart.style.left));
if(elementsOverlap(cart, block1)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block2)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block3)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block4)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
// if(parseInt(target.style.left) >= 1000){
// window.location.href = "../cutscene2/cutscene2.html";
// }
// check(redRing1Width, redRing1Left, redRing1Top, parseInt(target.style.left), parseInt(target.style.top));
// check(redRing2Width, redRing2Left, redRing2Top, parseInt(target.style.left), parseInt(target.style.top));
}
if(e.keyCode == 38 || e.keyCode == 87){
let cart = document.getElementById("cart");
let go = parseInt(cart.style.top) - 20;
cart.style.top = go;
if(elementsOverlap(cart, block1)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block2)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block3)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block4)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
// if(parseInt(target.style.left) >= 1000){
// window.location.href = "../cutscene2/cutscene2.html";
// }
// check(redRing1Width, redRing1Left, redRing1Top, parseInt(target.style.left), parseInt(target.style.top));
// check(redRing2Width, redRing2Left, redRing2Top, parseInt(target.style.left), parseInt(target.style.top));
}
if(e.keyCode == 40 || e.keyCode == 83){
let cart = document.getElementById("cart");
let go = parseInt(cart.style.left) + 20;
cart.style.top = go;
console.log("...");
if(elementsOverlap(cart, block1)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block2)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block3)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
if(elementsOverlap(cart, block4)){
// ow.play();
console.log("...");
document.getElementById("cart").style.left = "620px";
document.getElementById("cart").style.top = "450px";
lives--;
document.getElementById("lives").innerHTML = lives--;
if(lives <= 0){
document.getElementById("countdown").innerHTML = "You lose!";
}
}
// if(parseInt(cart.style.left) >= 1000){
// window.location.href = "../cutscene2/cutscene2.html";
// }
}
}
function isTouching(x0, y0, x1, y1){
let a = Math.pow((x1 - x0), 2);
let b = Math.pow((y1 - y0), 2);
return Math.sqrt(a + b);
}

Related

Reuse button to trigger another function

So I'm still practicing and learning and I'm creating a number guessing game and I was planning on re-using a existing button to trigger the reset of the game however for some reason it will reset however upon doing so-- resetGame() will reset variables but not start the checkGuess() like it's suppose to and only continue to randomize the randomNumber when 'submit' button is clicked..
I'm assuming that this must be bad practice and figure I shouldn't do this but wanted to ask why this wasn't re-starting the game as it should... what am I missing?
let randomNumber = Math.floor(Math.random() * 10) + 1;
let guessField = document.getElementById('guessField');
let enterButton = document.getElementById('userSubmit');
let lastResult = document.querySelector('.lastResult');
let lowOrHigh = document.querySelector('.lowOrHigh');
let guesses = document.querySelector('.guesses');
let guessRemaining = 5;
enterButton.addEventListener('click', checkGuess);
// function log() {
// console.log(Number(document.getElementById('guessField').value));
// }
function checkGuess() {
let userGuess = Number(guessField.value);
if (guessRemaining === 5) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.background = 'green';
gameOver();
} else if (guessRemaining < 1) {
lastResult.textContent = 'GAME OVER!';
gameOver();
} else {
lastResult.textContent = 'Wrong answer!';
lastResult.style.background = 'red';
lastResult.style.color = 'white';
if (userGuess < randomNumber) {
lowOrHigh.textContent = 'Too low!';
} else if (userGuess > randomNumber) {
lowOrHigh.textContent = 'Too high!';
}
}
guessRemaining--;
guessField.value = '';
guessField.focus();
}
function gameOver() {
guessField.disabled = true;
enterButton.setAttribute('value', 'Replay');
enterButton.addEventListener('click', resetGame);
}
function resetGame() {
randomNumber = Math.floor(Math.random() * 10) + 1;
// document.getElementById('userGuess').value = '';
lastResult.textContent = '';
guesses.textContent = '';
lowOrHigh.textContent = '';
guessField.disabled = false;
enterButton.setAttribute('value', 'Submit');
guessRemaining = 5;
}
The problem is that after you finish the game the resetGame callback is added as event listener and is triggered every time you click the userSubmit button. There are few possibilities how to solve this problem:
1. Check if the game is running
In this solution, you don't add the resetGame callback, but you call it within the checkGuess callback. To make this solution work you have to add a variable which represents if the game is running or not. This way if the game is still running the checkGuess callback will call the default behaviour, but after the gameOver is called, checkGuess will reset the game.
let randomNumber = Math.floor(Math.random() * 10) + 1;
let guessField = document.getElementById('guessField');
let enterButton = document.getElementById('userSubmit');
let lastResult = document.querySelector('.lastResult');
let lowOrHigh = document.querySelector('.lowOrHigh');
let guesses = document.querySelector('.guesses');
let guessRemaining = 5;
let isRunning = true;
enterButton.addEventListener('click', checkGuess);
function checkGuess() {
if (isRunning) { // Check if the game is running
let userGuess = Number(guessField.value);
if (guessRemaining === 5) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.background = 'green';
gameOver();
} else if (guessRemaining < 1) {
lastResult.textContent = 'GAME OVER!';
gameOver();
} else {
lastResult.textContent = 'Wrong answer!';
lastResult.style.background = 'red';
lastResult.style.color = 'white';
if (userGuess < randomNumber) {
lowOrHigh.textContent = 'Too low!';
} else if (userGuess > randomNumber) {
lowOrHigh.textContent = 'Too high!';
}
}
guessRemaining--;
guessField.value = '';
guessField.focus();
} else {
resetGame();
}
}
function gameOver() {
guessField.disabled = true;
enterButton.setAttribute('value', 'Replay');
isRunning = false;
// enterButton.addEventListener('click', resetGame); Move this line to the beggining
}
function resetGame() {
randomNumber = Math.floor(Math.random() * 10) + 1;
lastResult.textContent = '';
guesses.textContent = '';
lowOrHigh.textContent = '';
guessField.disabled = false;
enterButton.setAttribute('value', 'Submit');
guessRemaining = 5;
isRunning = true;
}
2. Remove the resetGame callback after reseting
Here you just remove the resetGame callback after it is called. First you add the resetGame (just like you have it now) after the game is finished, but remove the checkGuess as well so it doesn't trigger your logic. Next you remove the resetGame and add the guessCheck callbacks after the resetGame is called (you can see two lines at the end of resetGame function).
let randomNumber = Math.floor(Math.random() * 10) + 1;
let guessField = document.getElementById('guessField');
let enterButton = document.getElementById('userSubmit');
let lastResult = document.querySelector('.lastResult');
let lowOrHigh = document.querySelector('.lowOrHigh');
let guesses = document.querySelector('.guesses');
let guessRemaining = 5;
enterButton.addEventListener('click', checkGuess);
function checkGuess() {
let userGuess = Number(guessField.value);
if (guessRemaining === 5) {
guesses.textContent = 'Previous guesses: ';
}
guesses.textContent += userGuess + ' ';
if (userGuess === randomNumber) {
lastResult.textContent = 'Congratulations! You got it right!';
lastResult.style.background = 'green';
gameOver();
} else if (guessRemaining < 1) {
lastResult.textContent = 'GAME OVER!';
gameOver();
} else {
lastResult.textContent = 'Wrong answer!';
lastResult.style.background = 'red';
lastResult.style.color = 'white';
if (userGuess < randomNumber) {
lowOrHigh.textContent = 'Too low!';
} else if (userGuess > randomNumber) {
lowOrHigh.textContent = 'Too high!';
}
}
guessRemaining--;
guessField.value = '';
guessField.focus();
}
function gameOver() {
guessField.disabled = true;
enterButton.setAttribute('value', 'Replay');
enterButton.removeEventListener('click', checkGuess); // Remove checkGuess and add resetGame
enterButton.addEventListener('click', resetGame);
}
function resetGame() {
randomNumber = Math.floor(Math.random() * 10) + 1;
lastResult.textContent = '';
guesses.textContent = '';
lowOrHigh.textContent = '';
guessField.disabled = false;
enterButton.setAttribute('value', 'Submit');
guessRemaining = 5;
enterButton.removeEventListener('click', resetGame); // Remove resetGame and add checkGuess
enterButton.addEventListener('click', checkGuess);
}
How about a slightly improved approach?
You define a boolean variable named gameIsOver. When the game is over, you set the value to true and when you reset, set the value to false.
Then you update your enterButton's click event listener. If game is over, you call the resetGame() function, else you call checkGuess function.
let gameIsOver = false; // keep track if the game is over, initially its false
enterButton.addEventListener("click", function (e) {
if (gameIsOver) {
resetGame();
} else {
checkGuess();
}
});
function gameOver() {
/* your existing code */
gameIsOver = true;
}
function resetGame() {
/* your existing code */
gameIsOver = false;
}

How can I make different levels for a game? Would I have to make different classes?

I already have a sketch.js file with some gameStates.
var gameState = "wait";
I added conditional statements such as:
if(gameState == "wait"){
background(backgroundImg);
textSize(50);
fill("blue");
text("Project42 Own",250,400);
startButton.visible = true;
gun.visible = false;
backBoard.visible = false;
}
Below is the code that has level 1, wait, play and end gameState:
function draw() {
if(gameState == "wait"){
background(backgroundImg);
textSize(50);
fill("blue");
text("Project42 Own",250,400);
startButton.visible = true;
gun.visible = false;
backBoard.visible = false;
}
if(mousePressedOver(startButton)&& gameState == "wait"){
gunSound.play();
gunSound.setVolume(0)
gameState = "play";
}
if(gameState == "play"){
background("#BDA297")
fill("red");
textSize(30);
text("Score:" + score + " ",300,100);
fill("green");
text("Life:" + life + " ",800,100)
gun.y=mouseY
startButton.visible = false;
gun.visible = true;
backBoard.visible = true;
if(keyDown("SHIFT")){
shootBullets();
}
if (frameCount % 80 === 0) {
drawBlueBubble();
}
if (frameCount % 100 === 0) {
drawRedBubble();
}
if(blueBubbleGroup.collide(bulletGroup)){
handleBubbleCollision(blueBubbleGroup);
score +=5;
}
if(redBubbleGroup.collide(bulletGroup)){
handleBubbleCollision(redBubbleGroup);
score += 10;
}
if (blueBubbleGroup.collide(backBoard)){
handleGameover(blueBubbleGroup);
}
if (redBubbleGroup.collide(backBoard)) {
handleGameover(redBubbleGroup);
}
}
if (life == 0) {
gameState == "end"
}
if(gameState == "end"){
background(gameOverImg)
redBubbleGroup.hideEverything()
blueBubbleGroup.hideEverything();
}
drawSprites();
}
However, I now want to make level 2 in which there will be more obstacles. Also, I'm not a professional coder so please be clear in your answer.

Stop auto type at last array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to stop erasing my "auto typed text" when the last array is reached.
I've been searching so for on Google but I can't find any solution.
const typedTextSpan = document.querySelector(".typed-text");
const cursorSpan = document.querySelector(".cursor");
const textArray = ["reconnaitre un talent ?", "détécter une opportunité ?"];
const typingDelay = 170;
const erasingDelay = 100;
const newTextDelay = 2000;
let textArrayIndex = 0;
let charIndex = 0;
function type() {
if (charIndex < textArray[textArrayIndex].length) {
if (cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent += textArray[textArrayIndex].charAt(charIndex);
charIndex++;
setTimeout(type, typingDelay);
} else {
cursorSpan.classList.remove("typing");
setTimeout(erase, newTextDelay);
}
}
function erase() {
if (charIndex > 0) {
if (!cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent = textArray[textArrayIndex].substring(0, charIndex - 1);
charIndex--;
setTimeout(erase, erasingDelay);
} else {
cursorSpan.classList.remove("typing");
textArrayIndex++;
if (textArrayIndex >= textArray.length) textArrayIndex = 0;
setTimeout(type, typingDelay + 1100);
}
}
document.addEventListener("DOMContentLoaded", function() {
if (textArray.length) setTimeout(type, newTextDelay + 250);
});
<div class="container" id="container">
<h1>Savez-vous <span class="typed-text" id="typed-text"></span><span class="cursor" id="cursor"> </span></h1>
</div>
Currently your functions keep calling each other without any signal to stop somewhere. You already keep track of where your index currently is in the textArray with textArrayIndex. Use that to see if the end has been reached in the else statement of your type function.
if (textArrayIndex < textArray.length - 1) {
setTimeout(erase, newTextDelay);
}
Here it checks if the current index is lower than the last index of the array. If it is, it will continue to call the erase function and increment textArrayIndex with 1 there. Otherwise when the index is not lower than the last index, meaning it's the last one, it will simply do nothing, thus breaking the loop.
const typedTextSpan = document.querySelector(".typed-text");
const cursorSpan = document.querySelector(".cursor");
const textArray = ["reconnaitre un talent ?", "détécter une opportunité ?"];
const typingDelay = 170;
const erasingDelay = 100;
const newTextDelay = 2000;
let textArrayIndex = 0;
let charIndex = 0;
function type() {
if (charIndex < textArray[textArrayIndex].length) {
if (cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent += textArray[textArrayIndex].charAt(charIndex);
charIndex++;
setTimeout(type, typingDelay);
} else {
cursorSpan.classList.remove("typing");
// Erase if the end has not yet been reached.
if (textArrayIndex < textArray.length - 1) {
setTimeout(erase, newTextDelay);
}
}
}
function erase() {
if (charIndex > 0) {
if (!cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent = textArray[textArrayIndex].substring(0, charIndex - 1);
charIndex--;
setTimeout(erase, erasingDelay);
} else {
cursorSpan.classList.remove("typing");
textArrayIndex++;
setTimeout(type, typingDelay + 1100);
}
}
document.addEventListener("DOMContentLoaded", function() {
if (textArray.length) setTimeout(type, newTextDelay + 250);
});
<div class="container" id="container">
<h1>Savez-vous <span class="typed-text" id="typed-text"></span><span class="cursor" id="cursor"> </span></h1>
</div>
You need to compare the textArrayIndex with the textArray length in erase function. Please check below code for this.
const typedTextSpan = document.querySelector(".typed-text");
const cursorSpan = document.querySelector(".cursor");
const textArray = ["reconnaitre un talent ?", "détécter une opportunité ?"];
const typingDelay = 170;
const erasingDelay = 100;
const newTextDelay = 2000;
let textArrayIndex = 0;
let charIndex = 0;
function type() {
if (charIndex < textArray[textArrayIndex].length) {
if (cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent += textArray[textArrayIndex].charAt(charIndex);
charIndex++;
setTimeout(type, typingDelay);
} else {
cursorSpan.classList.remove("typing");
setTimeout(erase, newTextDelay);
}
}
function erase() {
// Check index
if(textArrayIndex == textArray.length - 1) {
// Stop Erase
return false;
}
if (charIndex > 0) {
if (!cursorSpan.classList.contains("typing")) cursorSpan.classList.add("typing");
typedTextSpan.textContent = textArray[textArrayIndex].substring(0, charIndex - 1);
charIndex--;
setTimeout(erase, erasingDelay);
} else {
cursorSpan.classList.remove("typing");
textArrayIndex++;
if (textArrayIndex >= textArray.length) textArrayIndex = 0;
setTimeout(type, typingDelay + 1100);
}
}
document.addEventListener("DOMContentLoaded", function() {
if (textArray.length) setTimeout(type, newTextDelay + 250);
});
<div class="container" id="container">
<h1>Savez-vous <span class="typed-text" id="typed-text"></span><span class="cursor" id="cursor"> </span></h1>
</div>

Function used for calculating not functioning, and a snake that can't be longer than 2?

I'm making a snake clone, and I've got the head to the second segment working. The rest of the body checks should run through automatically, but it cuts off the body at the second segment without going through the rest of the segments, despite the fact that it should. My code is as follows:
var pixels = document.getElementsByClassName('pixel'); // 0 to 95
var dir = 'right';
var foodEat = true;
var dead = true;
var snakeLong = 1;
var headPos;
var foodPix;
var foodMake = function(){ // Create Food pixel (Not On Snake)
var tempnum = Math.ceil(Math.random() * (95 - 5) + 5);
var pixstate = window.getComputedStyle(pixels[tempnum]).getPropertyValue('--state');
if (pixstate == 'snake' || pixstate == 'snakeHead' || pixstate == 'snakeEnd'){
console.log('Repeating');
foodMake();
} else {
console.log('Food Made!');
$(pixels[tempnum]).css('--state','food');
}
}
var directSend = function(reference,direction){
if (direction == 'left'){
reference -=1;
return reference;
} else if (direction == 'up'){
reference -=12;
return reference;
} else if (direction == 'right'){
reference +=1;
return reference;
} else if (direction == 'down'){
reference +=12;
return reference;
}
}
var snakeMake = function(refer,tsnakel){ // Continue To Form Snake
if (tsnakel > 0){
var tempdir = $(pixels[refer]).css('--goFrom');
console.log(directSend(refer,tempdir));
if (tsnakel = 1){
$(pixels[directSend(refer,tempdir)]).css('--state','empty');
} else {
refer = directSend(refer,tempdir);
}
tsnakel -= 1;
snakeMake(refer,tsnakel);
}
}
var snakeHEF = function(){ // Form First Sections of Snake
var Pheadpos;
var tdir;
if (dir == 'left'){ // Previous Segment Position
Pheadpos = 1;
tdir = 'right';
} else if (dir == 'up'){
Pheadpos = 12;
tdir = 'down';
} else if (dir == 'right'){
Pheadpos = -1;
tdir = 'left';
} else if (dir == 'down'){
Pheadpos = -12;
tdir = 'up';
}
$(pixels[headPos]).css('--state','snakeHead');
$(pixels[headPos]).css('--snakePos','1');
$(pixels[headPos]).css('--goFrom',tdir);
if (snakeLong == 1){ // No Food Eaten
$(pixels[headPos+Pheadpos]).css('--state','empty');
}
if (snakeLong >= 2){ // One Food Eaten
var send;
$(pixels[headPos+Pheadpos]).css('--state','snake');
$(pixels[headPos+Pheadpos]).css('--snakePos','2');
var temppos = $(pixels[headPos+Pheadpos]).css('--goFrom');
if (temppos == 'left'){
$(pixels[headPos+Pheadpos-1]).css('--state','empty');
send = headPos+Pheadpos-1;
} else if (temppos == 'up'){
$(pixels[headPos+Pheadpos-12]).css('--state','empty');
send = headPos+Pheadpos-12;
} else if (temppos == 'right'){
$(pixels[headPos+Pheadpos+1]).css('--state','empty');
send = headPos+Pheadpos+1;
} else if (temppos == 'down'){
$(pixels[headPos+Pheadpos+12]).css('--state','empty');
send = headPos+Pheadpos+12;
}
if (snakeLong > 2){ // More Than 1 Food Eaten
snakeMake(send,snakeLong-2);
}
}
}
var Game = setInterval(function(){
$(document).keydown(function(keyPressed){
if (keyPressed.keyCode == 88){ // Reset Game [x]
for (s = 0; s < 96; s++){
var pixstate = $(pixels[s]).css('--state');
if (pixstate == 'food'){
$(pixels[s]).css('--state','empty');
}
if (pixstate == 'snake' || pixstate == 'snakeHead' || pixstate == 'snakeEnd'){
$(pixels[s]).css('--state','empty');
$(pixels[s]).css('--snakePos','not');
$(pixels[s]).css('--goFrom','none');
}
}
foodEat = true;
$(pixels[0]).css('--state','snakeHead');
$(pixels[0]).css('--snakePos','1');
$(pixels[0]).css('--goFrom','left');
dead = false;
snakeLong = 1;
headPos = 0;
dir = 'right';
} // Movement Set
if (keyPressed.keyCode == 37 && dir !== 'right'){ // [<-]
dir = 'left';
} else if (keyPressed.keyCode == 38 && dir !== 'down'){ // [^^]
dir = 'up';
} else if (keyPressed.keyCode == 39 && dir !== 'left'){ // [->]
dir = 'right';
} else if (keyPressed.keyCode == 40 && dir !== 'up'){ // [vv]
dir = 'down';
}
});
if (dead == false){ //Dead Check Then Do Game Calculations
if (dir == 'left'){ // Move Head
for (s = 0; s < 8; s++){
if (headPos == 0+(12*s)){
dead = true;
}
}
if (dead == false){
headPos -= 1;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
} else if (dir == 'up'){
if (headPos < 12){
dead = true;
}
if (dead == false){
headPos -= 12;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
} else if (dir == 'right'){
for (s = 0; s < 8; s++){
if (headPos == 11+(12*s)){
dead = true;
}
}
if (dead == false){
headPos += 1;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
} else if (dir == 'down'){
if (headPos > 83){
dead = true;
}
if (dead == false){
headPos += 12;
if (foodPix == headPos){
snakeLong += 1;
foodEat = true;
}
snakeHEF();
}
}
if (foodEat == true){ // Food generator
foodMake();
foodEat = false;
}
for (s = 0; s < 96; s++){
var tpixstate = $(pixels[s]).css('--state');
if (tpixstate == 'food'){
foodPix = s;
}
}
}
for (s = 0; s < 96; s++){ // Pixel Update
var pixstate = $(pixels[s]).css('--state');
if (pixstate == 'snake' || pixstate == 'snakeHead' || pixstate == 'snakeEnd'){
$(pixels[s]).css('background-color','rgb(0,170,0)');
} else if (pixstate == 'food'){
$(pixels[s]).css('background-color','rgb(270,0,0)');
} else if (pixstate == 'empty'){
$(pixels[s]).css('background-color','rgb(68,68,68)');
}
}
},750);
Edit: To reduce confusion, I have now given the entire code.
As it turns out, I was calling the code to remove the third body segment every time, (lines 76 thru 88) even when the body was supposed to be longer.(I changed it to one '--state' changer, in an if statement checking for a body length of 2) Additionally, an if statement (line 40) was using = instead of ==, causing it to count as true each time, cutting off the fourth body segment.

Won't let me set class name of a Javascript created div

I'm using a function to create a div element on the page. I want to assign a className but I get the error: cannot set property className of undefined.
But I did this in another function and it worked. Why is this one not working?
If I failed to provide the code relevant to the problem I apologize. I'm in a rush and included code that I thought might be relevant in order of relevancy.
** WORKING FUNCTION **
function makeBomb() {
if (player.ready && (player.hasBomb < player.maxBombs)) {
player.score -= 300;
player.hasBomb++;
player.bomb = document.createElement('div');
player.bomb.className = 'bomb'; //DOESN'T THROW ERROR ----
gameArea.appendChild(player.bomb);
player.bomb.x = player.x;
player.bomb.y = player.y;
player.bomb.style.left = player.bomb.x + 'px';
player.bomb.style.top = player.bomb.y + 'px';
player.ready = false;
setTimeout(function () {
player.ready = true;
}, 1000);
}
}
** NOT WORKING FUNCTION **
function makeBullet() {
if (player.enemy.bulletCount < player.enemy.maxBulletCount &&
player.enemy.bulletInterval == true)
player.enemy.bullet = document.createElement('div');
player.enemy.bullet.className = 'bullet'; //THROWS ERROR -----
gameArea.appendChild(player.enemy.bullet);
player.enemy.bullet.x = player.enemy.x;
player.enemy.bullet.y = player.enemy.y;
player.enemy.bullet.style.left = player.enemy.bullet.x +
(player.enemy.offsetWidth / 3) + 'px';
player.enemy.bullet.style.top = player.enemy.bullet.y +
(player.enemy.offsetHeight / 4) + 'px';
player.enemy.bulletCount++;
player.enemy.bulletInterval = false;
setInterval(function(){
player.enemy.bulletInterval = true;
}, 4000);
}
** STARTING CODE THAT MIGHT HAVE CONTEXT IDK**
function start() {
if (player.games === 1) {
gameArea.removeChild(finalScore);
}
gameMessage.style.display = 'none';
score.style.display = "inline-block";
scoreArea.style.display = "inline-block";
text.style.display = "inline-block";
player.inplay = true;
makeEnemy();
player.plane = document.createElement("div");
player.plane.setAttribute("class", "plane");
gameArea.appendChild(player.plane);
player.enemy.x = player.enemy.offsetLeft;
player.enemy.y = player.enemy.offsetTop;
player.x = player.plane.offsetLeft;
player.y = player.plane.offsetTop;
window.requestAnimationFrame(playGame);
}
** OTHER CODE THAT MIGHT HAVE CONTEXT **
function makeEnemy() {
player.enemy = document.createElement('div');
player.enemy.className = 'enemy';
player.enemy.style.left = Math.floor(Math.random() * .
gameArea.offsetWidth - 300) + 100 + 'px';
gameArea.appendChild(player.enemy);
player.enemy.x = player.enemy.offsetLeft;
}
** JUST IN CASE YOU NEED -- idk its hard for me to keep track of everything that might be related to the problem... sorry.. **
title.addEventListener("click", changeColor);
const gameArea = document.querySelector(".gameArea");
const game = document.querySelector(".game");
const scoreArea = document.querySelector(".scoreArea");
const score = document.querySelector(".score");
const text = document.querySelector(".text");
document.addEventListener('keydown', pressOn);
document.addEventListener('keyup', pressOff);
gameMessage.addEventListener('click', start);
let player = {
score: 2000,
speed: 5,
inplay: false,
ready: true,
maxBombs: 4,
hasBomb: 0,
hit: 0,
hitMax: 9,
games: 0,
enemy: {
x: 0
},
getHit: 0,
getHitMax: 20,
swing: false
}
let keys = {
space: false
}
** FULL JS FILE: BE WARNED IM VERY NEW AND THIS IS NOT GOOD CODE **
const title = document.querySelector(".title");
const gameMessage = document.querySelector(".gameMessage");
function changeColor() {
let newArray = ["darksalmon", "lightsalmon", "crimson", "red", "deeppink", "yellowgreen", "ghostwhite"];
let random = Math.floor(Math.random() * Math.floor(newArray.length - 1));
if (title.style.color != newArray[random]) {
title.style.color = newArray[random];
console.log(title.style.color);
} else {
changeColor();
}
}
title.addEventListener("click", changeColor);
const gameArea = document.querySelector(".gameArea");
const game = document.querySelector(".game");
const scoreArea = document.querySelector(".scoreArea");
const score = document.querySelector(".score");
const text = document.querySelector(".text");
document.addEventListener('keydown', pressOn);
document.addEventListener('keyup', pressOff);
gameMessage.addEventListener('click', start);
let player = {
score: 2000,
speed: 5,
inplay: false,
ready: true,
maxBombs: 4,
hasBomb: 0,
hit: 0,
hitMax: 9,
games: 0,
enemy: {
x: 0
},
getHit: 0,
getHitMax: 20,
swing: false
}
let keys = {
space: false
}
function start() {
if (player.games === 1) {
gameArea.removeChild(finalScore);
}
gameMessage.style.display = 'none';
score.style.display = "inline-block";
scoreArea.style.display = "inline-block";
text.style.display = "inline-block";
player.inplay = true;
makeEnemy();
player.plane = document.createElement("div");
player.plane.setAttribute("class", "plane");
gameArea.appendChild(player.plane);
player.enemy.x = player.enemy.offsetLeft;
player.enemy.y = player.enemy.offsetTop;
player.x = player.plane.offsetLeft;
player.y = player.plane.offsetTop;
window.requestAnimationFrame(playGame);
}
function playGame() {
if (player.inplay) {
moveBomb();
if(player.x < (gameArea.offsetWidth / 2)) {
console.log('WORKED');
makeBullet();
}
if (player.swing){
player.plane.style.backgroundImage ='url(guts1.png)';
player.swing = false;
//player.plane.style.width = 210 + 'px';
}
if (keys['x'] && player.enemy && isCollide(player.plane, player.enemy)) {
removeEnemy();
}
if (player.enemy) {
if (isCollide(player.plane, player.enemy)) {
player.getHit++;
if (player.getHit > player.getHitMax){
endGame();
}
} else {
player.getHit = 0;
}
if (player.x > player.enemy.x) {
player.enemy.x += 1;
}
if (player.x < player.enemy.x) {
player.enemy.x -= 1;
}
player.enemy.style.left = player.enemy.x + 'px';
}
if (player.hasBomb >= player.maxBombs && player.bomb.y > gameArea.offsetHeight - 20) {
endGame();
}
if (keys.space) {
makeBomb()
}
if (keys.ArrowUp && player.y > 0) {
player.y -= (player.speed + (player.speed * .5));
}
if (keys.ArrowDown && player.y < (gameArea.offsetHeight - player.plane.offsetHeight - 30)) {
player.y += (player.speed + (player.speed * .5));
}
if (keys.ArrowLeft && player.x > 0) {
player.x -= (player.speed + (player.speed * .5));
}
if (keys.ArrowRight && player.x < (gameArea.offsetWidth)) {
player.x += (player.speed - (player.speed * .5));
}
if (player.x == (gameArea.offsetWidth)) {
player.x = 0;
player.score -= 100;
if (!player.enemy) {
makeEnemy();
}
}
player.score -= .4;
if (player.score < 0) {
player.score = 0;
}
player.x += (player.speed * .5);
score.innerHTML = Math.floor(player.score) + ' Bombs left: ' + (player.maxBombs - player.hasBomb);
player.plane.style.left = player.x + 'px';
player.plane.style.top = player.y + 'px';
window.requestAnimationFrame(playGame);
}
}
function pressOn(e) {
e.preventDefault();
let tempKey = (e.key == " ") ? "space" : e.key;
keys[tempKey] = true;
if (keys['x'] && player.swing == false){
playerPlane = player.plane;
player.plane.style.backgroundImage ='url(guts2.png)';
setTimeout(function () {
player.swing = true;
}, 300);
//player.plane.style.width = 400 + 'px';
}
console.log(tempKey)
console.log(keys);
}
function pressOff(e) {
e.preventDefault();
let tempKey = (e.key== " ") ? "space" : e.key;
console.log(tempKey);
// if (keys['x'] && player.swing){
// playerPlane = player.plane;
// player.plane.style.backgroundImage ='url(guts1.png)';
// player.swing = false;
// //player.plane.style.width = 210 + 'px';
//
// }
if (keys['space'] || keys['x']) {
keys['space'] = 0;
keys['x'] = 0;
}
keys[tempKey] = false;
console.log(keys);
}
function moveBomb() {
let bombs = document.querySelectorAll('.bomb');
bombs.forEach(function (item) {
item.y += 10;
item.style.top = item.y + 'px';
if (item.y > gameArea.offsetHeight) {
item.parentNode.removeChild(item);
player.bomb = null;
}
if (player.enemy && player.bomb) {
if (isCollide(item, player.enemy)) {
player.hit++;
}
}
if (player.hit > player.hitMax) {
item.parentNode.removeChild(item);
player.bomb = null;
player.score += 2000;
player.hit = 0;
player.hasBomb -= 2
gameArea.removeChild(player.enemy);
player.enemy = null;
}
})
}
function makeEnemy() {
player.enemy = document.createElement('div');
player.enemy.className = 'enemy';
player.enemy.style.left = Math.floor(Math.random() * gameArea.offsetWidth - 300) + 100 + 'px';
gameArea.appendChild(player.enemy);
player.enemy.x = player.enemy.offsetLeft;
}
//function getLocationX(a){
// let aRect = a.getBoundingClientRect();
// let aX = aRect.x;
// return aX;
// //w console.log(aX);
//}
//
//function getLocationY(a){
// let aRect = a.getBoundingClientRect();
// let aY = aRect.y;
// return aY;
// // console.log(aY);
//}
function isCollide(a, b) {
let aRect = a.getBoundingClientRect();
let bRect = b.getBoundingClientRect();
return !(
(aRect.bottom < bRect.top) ||
(aRect.top > bRect.bottom) ||
(aRect.right < bRect.left) ||
(aRect.left > bRect.right)
)
}
function makeBomb() {
if (player.ready && (player.hasBomb < player.maxBombs)) {
player.score -= 300;
player.hasBomb++;
player.bomb = document.createElement('div');
player.bomb.className = 'bomb';
gameArea.appendChild(player.bomb);
player.bomb.x = player.x;
player.bomb.y = player.y;
player.bomb.style.left = player.bomb.x + 'px';
player.bomb.style.top = player.bomb.y + 'px';
player.ready = false;
setTimeout(function () {
player.ready = true;
}, 1000);
}
}
function makeBullet() {
if (player.enemy.bulletCount < player.enemy.maxBulletCount && player.enemy.bulletInterval == true)
player.enemy.bullet = document.createElement('div');
player.enemy.bullet.className = 'bullet';
gameArea.appendChild(player.enemy.bullet);
player.enemy.bullet.x = player.enemy.x;
player.enemy.bullet.y = player.enemy.y;
player.enemy.bullet.style.left = player.enemy.bullet.x + (player.enemy.offsetWidth / 3) + 'px';
player.enemy.bullet.style.top = player.enemy.bullet.y + (player.enemy.offsetHeight / 4) + 'px';
player.enemy.bulletCount++;
player.enemy.bulletInterval = false;
setInterval(function(){
player.enemy.bulletInterval = true;
}, 4000);
}
function endGame() {
if (player.enemy) {
gameArea.removeChild(player.enemy);
}
gameArea.removeChild(player.plane);
if (player.bomb){
gameArea.removeChild(player.bomb);
player.bomb = null;
}
score.style.display = 'none';
scoreArea.style.display = 'none';
text.style.display = 'none';
gameMessage.style.display = 'inline-block';
player.inplay = false;
player.hasBomb = 0;
finalScore = document.createElement('div');
finalScore.classList.add('finalScore');
finalScore.innerHTML = 'YOU SCORED: ' + Math.floor(player.score);
gameArea.appendChild(finalScore);
player.games = 1;
player.getHit = 0;
}
function removeEnemy() {
gameArea.removeChild(player.enemy);
player.enemy = null;
player.score += 2000;
}
function makeBullet() {
if (player.enemy.bulletCount < player.enemy.maxBulletCount &&
player.enemy.bulletInterval == true)
youre missing curly braces at the end of the if statement and i think its interpretting the next line as a part single line if statement
change to
function makeBullet() {
if (player.enemy.bulletCount < player.enemy.maxBulletCount &&
player.enemy.bulletInterval == true) {
...
...
...
}
}

Categories