Responsive jQuery sketch application failing when div size is < 7px - javascript

I'm trying to build a responsive sketch application with jQuery. It works, except for when the size for the divs within the .box class become less than 7px. I tried to make a fiddle but I couldn't see any output. I'll just leave the code here and hope for the best!
var wide = 150;
$(document).ready(function() {
makeGrid(wide);
$('body').on('mousedown mouseup', function mouseState(e) {
if (e.type == "mousedown") {
$(".box").mouseenter(function() {
$(this).css("background-color", "black");
});
} else {
$(".box").unbind('mouseenter mouseleave');
}
});
});
var makeGrid = function(wide) {
var boxSide = calculateBoxSide(wide);
var boxRowNumber = calculateRowNumbers(boxSide);
var boxSideLength = boxSide + "px";
$("body").css("line-height", boxSideLength);
for (i = 0; i < wide; i++) {
for (j = 0; j < boxRowNumber; j++) {
$box = $('<div class="box">').appendTo(".sketchpad")
$box.css("width", boxSideLength);
$box.css("height", boxSideLength);
}
}
}
var calculateBoxSide = function(wide) {
return $(".sketchpad").width() / wide;
}
var calculateRowNumbers = function(boxSideLength) {
return Math.round($(".sketchpad").height() / boxSideLength);
}
.sketchpad {
margin: 0 auto;
width: 50%;
height: 500px;
text-align: center;
}
.box {
display: inline-block;
background-color: grey;
vertical-align: top;
}
.box:hover {
background-color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="sketchpad"></div>

Related

Why the div is not moving leftwards using "right" ? in third step

Here, I have code a program that revolves the targeted div in a rectangular path using CSS positions properties in setInterval() method.
Firstly, the div indeed moves rightwards (using left CSS property) and then downwards (using top CSS property) but when the thirds step comes it doesn't move leftwards (using CSS right property). Why is that so?
let a = 0;
let node = document.querySelector(".node");
let inter1 = setInterval(function() {
if (a == 260) {
clearInterval(inter1);
a = 0;
let inter2 = setInterval(function() {
if (a == 639) {
clearInterval(inter2);
a = 260;
let inter3 = setInterval(function() {
if (a == 0) {
clearInterval(inter3);
} else {
a -= 1;
node.style.right = a + "px";
}
}, 1)
} else {
a += 1;
node.style.top = a + "px";
}
}, 1)
} else {
a += 1;
node.style.left = a + "px";
}
}, 1)
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: serif;
}
body {
background: black;
color: white;
width: 100vw;
}
.node {
background: dodgerblue;
color: white;
display: inline-block;
width: 100px;
height: 100px;
position: absolute;
}
<div class="node"></div>
Like the user #JavaScript wrote, you should decide for one - left or right.
Therefor you could change right to left in the inter3 statement:
let inter3 = setInterval(function() {
if (a == 0) {
clearInterval(inter3);
} else {
a -= 1;
node.style.left = a + "px";
}
}, 1);
let a = 0;
let node = document.querySelector(".node");
let inter1 = setInterval(function() {
if (a == 260) {
clearInterval(inter1);
a = 0;
let inter2 = setInterval(function() {
if (a == 639) {
clearInterval(inter2);
a = 260;
let inter3 = setInterval(function() {
if (a == 0) {
clearInterval(inter3);
} else {
a -= 1;
node.style.left = a + "px";
}
}, 1)
} else {
a += 1;
node.style.top = a + "px";
}
}, 1)
} else {
a += 1;
node.style.left = a + "px";
}
}, 1)
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: serif;
}
body {
background: black;
color: white;
width: 100vw;
}
.node {
background: dodgerblue;
color: white;
display: inline-block;
width: 100px;
height: 100px;
position: absolute;
}
<div class="node"></div>

How to limit the number of total animated drop cubes and make them animate by their added order?

When we click this add button we will add a new cube which will drop immediately, but if we click it very quickly, there will be too many cubes dropping. I want to limit the number of the total animated dropping cube.
For example, even if we click the button very quickly and 10 cubes are added to the page, only two cubes are dropping, and others must wait until they finished.
For example, the 3rd and 4th cubes will start to drop when cube 1 and cube 2 finished.
I was thinking maybe we can have a global variable of the total animated cubes count, ++ and -- it when a new cube is starting and finishing animation, use setInterval to check if the variable is less than 2, but this can't make the animation based on the cubes created order. May I know how to solve this? Thank you so much!
var btn = document.getElementById('add');
var container = document.getElementById('cubes-container');
var cubeId = 0;
btn.addEventListener('click', addCube);
var currentAnimateCount = 0;
function dropCube(cube) {
var pos = 0;
let intervalId = setInterval(function() {
if (pos == 200) {
clearInterval(intervalId);
} else {
pos++;
cube.style.top = pos + "px";
}
}, 1);
}
function addCube() {
let cube = document.createElement('div');
let cubeContainer = document.createElement('div');
cube.className = 'cube';
cube.id = cubeId;
cube.innerHTML = cube.id;
cubeId++;
cubeContainer.className = 'cube-container';
cubeContainer.append(cube);
container.append(cubeContainer);
let pos = 0;
dropCube(cube)
}
#cubes-container {
display: grid;
grid-template-columns: repeat(10, 1fr);
}
.cube-container {
position: relative;
height: 30px;
}
.cube {
width: 30px;
height: 30px;
background-color: orange;
text-align: center;
display: grid;
align-items: center;
justify-items: center;
position: absolute;
}
<button id="add">add new</button>
<div id="cubes-container">
</div>
Consider the following example. It is using jQuery versus JavaScript. It could be similarly scripted.
$(function() {
function addCube(target) {
var i = $(".cube").length;
var container = $("<div>", {
class: "cube-container"
}).appendTo(target);
$("<div>", {
class: "cube",
id: "cube-" + i
}).html(i).appendTo(container);
return container;
}
function dropCube(cube) {
$(cube).addClass("falling").animate({
top: "200px"
}, 2000, function() {
$(cube).removeClass("falling");
if (cubes.length && $(".falling").length < 2) {
dropCube(cubes.shift());
}
});
}
var cubes = [];
$("#add").click(function() {
cubes.push(addCube("#cubes-container"));
if ($(".falling").length < 2) {
dropCube(cubes.shift());
}
});
});
/*
var btn = document.getElementById('add');
var container = document.getElementById('cubes-container');
var cubeId = 0;
btn.addEventListener('click', addCube);
var currentAnimateCount = 0;
function dropCube(cube) {
var pos = 0;
let intervalId = setInterval(function() {
if (pos == 200) {
clearInterval(intervalId);
} else {
pos++;
cube.style.top = pos + "px";
}
}, 1);
}
function addCube() {
let cube = document.createElement('div');
let cubeContainer = document.createElement('div');
cube.className = 'cube';
cube.id = cubeId;
cube.innerHTML = cube.id;
cubeId++;
cubeContainer.className = 'cube-container';
cubeContainer.append(cube);
container.append(cubeContainer);
let pos = 0;
dropCube(cube)
}
*/
#cubes-container {
display: grid;
grid-template-columns: repeat(10, 1fr);
}
.cube-container {
position: relative;
height: 30px;
}
.cube {
width: 30px;
height: 30px;
background-color: orange;
text-align: center;
display: grid;
align-items: center;
justify-items: center;
position: absolute;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add">add new</button>
<div id="cubes-container"></div>
Using an Array, you cna .shift() the first item of the array. Also adding a Class to the falling items allows you to keep a count of which ones are falling. I like to use Animate since it allows for a callback when the animation is done, so you can check for the next item.
Update for JavaScript
var btn = document.getElementById('add');
var container = document.getElementById('cubes-container');
var cubes = [];
btn.addEventListener('click', function(event) {
cubes.push(addCube());
if (document.getElementsByClassName("falling").length < 2) {
dropCube(cubes.shift());
}
});
function dropCube(cube) {
var pos = 0;
cube.classList.add("falling");
var intervalId = setInterval(function() {
if (pos == 200) {
clearInterval(intervalId);
cube.classList.remove("falling");
if (document.getElementsByClassName("falling").length < 2 && cubes.length) {
dropCube(cubes.shift());
}
} else {
pos++;
cube.style.top = pos + "px";
}
}, 1);
}
function addCube() {
let cube = document.createElement('div');
let cubeContainer = document.createElement('div');
cube.className = 'cube';
cube.id = document.getElementsByClassName("cube").length;
cube.innerHTML = cube.id;
cubeContainer.className = 'cube-container';
cubeContainer.append(cube);
container.append(cubeContainer);
return cubeContainer;
}
#cubes-container {
display: grid;
grid-template-columns: repeat(10, 1fr);
}
.cube-container {
position: relative;
height: 30px;
}
.cube {
width: 30px;
height: 30px;
background-color: orange;
text-align: center;
display: grid;
align-items: center;
justify-items: center;
position: absolute;
top: 0;
}
<button id="add">add new</button>
<div id="cubes-container"></div>

Collision detection using pure jQuery is not giving desired output

I am trying to develop a very simple game where the ship (red box) will move left-right when user clicks on playground.
There are some moving walls (black boxes) as obstacles that the ship should avoid colliding with.
If any collision happens, the walls will stop moving and a text will be printed out in console.
I have succeeded to get this as close as I can. But its working sometime, not always. You can see it in the code below, try to collide with wall. Sometime it will stop them and print text, sometime it will just ignore the collision as if nothing happens.
I have no clue why this is happening.
Here is the code.
$('document').ready(function() {
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
return $collide;
}
var $wallTimer = setInterval(function() {
$('.wall').each(function(i, obj) {
var $status = moveWall($(this));
if ($status == true) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision(wallObj) {
var $ship = $('.ship');
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
var $wall = wallObj;
var $wallWidth = wallObj.width();
var $wallHeight = wallObj.height();
var $wallLeft = wallObj.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = wallObj.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft >= $wallRight ||
$shipRight <= $wallLeft ||
$shipTop >= $wallBottom ||
$shipBottom <= $wallTop
) {
return false;
} else {
console.log("dhumm!");
return true;
}
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, 500, "linear");
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, 500, "linear");
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: red;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As freefomn-m already said.
Check for collision in the animation cycle of the ship, not the walls.
For this I use the second type of parameters for jQuery's .animate method
.animate( properties, options )
I use the "progress" option to check the collision in every movement cycle of the ship.
console.clear();
$('document').ready(function() {
var collided = false;
var collidedWith = null;
var $ship = $('.ship');
var $walls = $('.wall')
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
// var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
// return $collide;
}
var $wallTimer = setInterval(function() {
$walls.each(function(i, obj) {
moveWall($(this));
if (collided) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision() {
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
$('.wall').each(function(i) {
var $wall = $(this);
var $wallWidth = $wall.width();
var $wallHeight = $wall.height();
var $wallLeft = $wall.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = $wall.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft < $wallRight &&
$shipRight > $wallLeft &&
$shipTop < $wallBottom &&
$shipBottom > $wallTop
) {
console.log("dhumm!");
collided = true;
collidedWith = $wall
$wall.addClass('crashed')
$ship.addClass('crashed')
$ship.stop();
return false;
}
})
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .wall.crashed {
background: red;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: orange;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.outer .inner .ship.crashed {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As a recommendation how I would do this from scratch.
Use an update cycle that is called by either setInterval or setTimeout, or even better with requestAnimationFrame. The updatecycle would be responsible for the time progress and orchestrate the different objects. The structure would be like this.
jQuery(function($) { // same as $('document').ready()
var ship = ...;
var boundaries = ...;
var walls = ...;
var clickEvents = [];
document.addEventListener('click', function(e) {clickEvents.push(e)})
var handleEvents = function() {}
var setupWalls = function () {}
var setupShip= function () {}
var moveWalls = function () {}
var moveShip = function () {}
var checkCollision() {}
var setup = function() {
setupWalls();
setupShip();
// set the initial positions of the ships and the walls
}
var update = function() {
handleEvents();
moveWalls();
moveShips();
var collided = checkCollision();
if (!collided) {
setTimeout(update, 30);
}
}
setup();
update();
})

Need help to limit how many tiles and target spawn in this game

I got some simple bomberman game from code pen.For my study,i need to limit how many tiles and target.For tiles max 32 and target 7 (tiles grey & target red).
Here the source : codepen.io/Digiben/pen/oGYGrx
I dont understand how the script create the target and tiles with random algoritm.
Thanks for anyone who look this thread.
window.onload = function(){
//Map Kelas
class Map {
constructor (nbX, nbY, tileSize){
this.nbX = nbX;
this.nbY = nbY;
this.mapArray = new Array(this.nbX);
this.tileSize = tileSize;
this.map = document.getElementById('map');
}
init() {
console.log('Map size: ' + this.nbX * this.nbY);
let i = 0;
let j = 0;
let bool = null;
this.map.style.width = (this.tileSize * this.nbX) + 'px';
this.map.style.height = this.tileSize * this.nbY + 'px';
for (i = 0; i < this.nbX; i++) {
this.mapArray[i] = new Array(this.nbY);
for (j = 0; j < this.nbY; j++) {
bool = Math.random() >= 0.7 ? true : false;
if (bool) {
for (var z = Things.length - 1; i >= 0; i-) {
Things[i]
}
} else if (!bool) {
this.mapArray[i][j] = 1;
}
}
}
}
appendTile(i, j) {
let tile = document.createElement('div');
this.map.appendChild(tile);
tile.style.width = this.tileSize + 'px';
tile.style.height = this.tileSize + 'px';
tile.classList.add('tile');
tile.style.left = (i * this.tileSize) + 'px';
tile.style.top = (j * this.tileSize) + 'px';
}
getMapArray () {
return this.mapArray;
}
getMapSize () {
return {sizeX: this.nbX, sizeY:this.nbY}
}
}
//Create Target
class Target {
constructor (map, tileSize) {
this.mapArray = map.getMapArray();
this.playerSpace = map.getMapSize();
this.targetsArray = new Array();
this.possiblePositionToStartX = new Array();
this.possiblePositionToStartY = new Array();
this.tileSize = tileSize;
this.map = document.getElementById('map');
this.totalTargets = 0;
}
getTotalTargets(){
return this.totalTargets;
}
//Show Total Target
showTotalTargets () {
let totalDiv = document.querySelector('#score strong');
totalDiv.innerHTML = ' / ' + this.totalTargets;
}
showTargets(i, j) {
let tile = document.createElement('div');
this.map.appendChild(tile);
tile.classList.add('target');
tile.style.width = this.tileSize + 'px';
tile.style.height = this.tileSize + 'px';
// set attribute to identify the target when we need to remove it
tile.setAttribute('data-pos', i + ':' + j );
// positionning and styling
tile.style.left = (i * this.tileSize) + 'px';
tile.style.top = (j * this.tileSize) + 'px';
tile.style.backgroundColor = 'red';
tile.style.opacity = 0.5;
}
createTargets() {
//Target looping
for (var i = 1; i < this.playerSpace.sizeX-1; i++) {
//Maks Target 2D 10x10
this.targetsArray[i] = new Array();
if (i == 1) this.targetsArray[i-1] = new Array();
if (i == 8) this.targetsArray[i+1] = new Array();
for (var j = 1; j < this.playerSpace.sizeY-1; j++) {
this.targetsArray[i][j] = 1;
//Target aLgorithm
//Player dont Looping On red Zone
this.possiblePositionToStartX.push(i+1);
this.possiblePositionToStartY.push(j+1);
//Target Array if 0 to display Win on the End
this.targetsArray[i][j] = 0;
//Total Targets
this.totalTargets++;
//Show Target On map
this.showTargets(i, j);
}
}
}
//Show Total Targets
this.showTotalTargets();
}
// Start Player
getPossiblePosToStart() {
//Random Start PLayer
let xPos = this.possiblePositionToStartX[Math.floor(Math.random() * (this.possiblePositionToStartX.length))];
let yPos = this.possiblePositionToStartY[Math.floor(Math.random() * (this.possiblePositionToStartY.length))];
return {x: xPos, y: yPos}
}
//Player Array
getTargetsArray(){
return this.targetsArray;
}
}
//PLayer CLass
class Player {
constructor (mapArray, map, targets, tileSize) {
this.positionArray = mapArray;
this.position = {x: 0, y: 0}
this.playerDiv = document.getElementById('player');
this.playerDiv.style.left = 0;
this.playerDiv.style.top = 0;
this.playerDiv.style.right = 0;
this.playerDiv.style.bottom = 0;
this.playerDiv.style.width = tileSize + 'px';
this.playerDiv.style.height = tileSize + 'px';
this.playerSpace = map.getMapSize();
this.playerMap = map.getMapArray();
this.score = 0;
this.targetsArray = targets.getTargetsArray();
this.totalTargets = targets.getTotalTargets();
this.tileSize = tileSize;
}
//Record Posisition Player
recordPosition(mapArray){
this.positionArray = mapArray;
}
//Reset Score when Restart The game
static resetScore() {
let scoreSpan = document.querySelector('#score span'); scoreSpan.innerHTML = '0';
}
//Set Palyer
setPosition (position){
this.playerDiv.style.left = (position.x * this.tileSize) + 'px';
this.playerDiv.style.top = (position.y * this.tileSize) + 'px';
this.position.x = position.x;
this.position.y = position.y;
}
getPosition() {
return this.position;
}
//Limt Map
moveRight() {
if(this.position.x > this.playerSpace.sizeX-2) return false;
if(this.positionArray[this.position.x+1][this.position.y] != 0){
this.position.x++;
let nb = this.playerDiv.style.left.split('px');
this.playerDiv.style.left = (parseInt(nb[0]) + this.tileSize) + 'px';
console.log('Droite | X : ' + this.playerDiv.style.left);
console.log(this.position.x + ' : ' + this.position.y);
} else {
console.log('Not OK');
}
}
moveDown() {
if(this.position.y > this.playerSpace.sizeY-2) return false;
if(this.positionArray[this.position.x][this.position.y+1] != 0){
this.position.y++;
let nb = this.playerDiv.style.top.split('px');
this.playerDiv.style.top = (parseInt(nb[0]) + this.tileSize) + 'px';
console.log('Bas | Y : ' + this.playerDiv.style.top);
console.log(this.position.x + ' : ' + this.position.y);
} else {
console.log('Not OK');
}
}
moveLeft() {
if(this.position.x == 0) return false;
if(this.positionArray[this.position.x-1][this.position.y] != 0){
this.position.x--;
let nb = this.playerDiv.style.left.split('px');
this.playerDiv.style.left = (parseInt(nb[0]) - this.tileSize) + 'px';
console.log('Gauche | X : ' + this.playerDiv.style.left);
console.log(this.position.x + ' : ' + this.position.y);
} else {
console.log('Not OK');
}
}
moveUp() {
if(this.position.y <= 0) return false;
if(this.positionArray[this.position.x][this.position.y-1] != 0){
this.position.y--;
let nb = this.playerDiv.style.top.split('px');
this.playerDiv.style.top = (parseInt(nb[0]) - this.tileSize) + 'px';
console.log('Haut | Y : ' + this.playerDiv.style.top);
console.log(this.position.x + ' : ' + this.position.y);
} else {
console.log('Not OK');
}
}
//Update Score
updateScore () {
let scoreDiv = document.querySelector('#score span');
scoreDiv.innerHTML = this.score;
//Winner Message
if(this.score == this.totalTargets) document.querySelector ('#win').classList.add('show');
console.log('Score : ' + this.score);
}
//Update Target Array
updateTargetsArray (posx, posy){
this.targetsArray[posx][posy] = 1;
console.log('Array state : ');
console.log(this.targetsArray);
}
//Remove Target
removeTarget(posx, posy) {
let targetToRemove = document.querySelectorAll('.target');
let coords = posx + ':' + posy;
let attr = '';
//Loop To find Right Target accroding Coordinates Player
for (var i = 0; i< targetToRemove.length; i++) {
attr = targetToRemove[i].getAttribute('data-pos');
if(attr == coords) {
targetToRemove[i].remove();
//Update Score
this.score++;
this.updateScore();
}
}
//Remove Html node (Remove Array Target)
if(this.targetsArray[posx][posy] == 0){
this.targetsArray[posx][posy] == 1;
}
}
//Plant Bomb
plantBomb(){
//Make Child Bomb
let map = document.getElementById('map');
let bomb = document.createElement('div');
map.appendChild(bomb);
bomb.style.width = this.tileSize + 'px';
bomb.style.height = this.tileSize + 'px';
//Posision Bomb
bomb.classList.add('bomb');
bomb.style.left = (this.position.x * this.tileSize) + 'px';
bomb.style.top = (this.position.y * this.tileSize) + 'px';
//Variables
var posx = this.position.x;
var posy = this.position.y;
var that = this;
var timer = setInterval(bombTimer, 500, posx, posy, that);
var iter = 0;
//BombTimer
function bombTimer() {
switch (iter) {
case 1:
bomb.classList.add('waiting');
break;
case 2:
bomb.classList.add('before');
bomb.classList.remove('waiting');
break;
case 3:
bomb.classList.add('explode');
bomb.classList.remove('before');
break;
case 4:
clearInterval(timer);
bomb.remove();
that.updateTargetsArray(posx, posy);
that.removeTarget(posx, posy);
default:
break;
}
iter++;
}
}
}
//Game Class
class Game {
constructor (tileSize, mapX, mapY) {
//Create Map
var map = new Map(mapX,mapY, tileSize);
map.init();
//Create Target
var targets = new Target(map, tileSize);
targets.createTargets();
//Create PLayer
var player = new Player(map.getMapArray(), map, targets, tileSize);
//Place The player
player.setPosition(targets.getPossiblePosToStart());
//Keyboard Events
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
if (e.keyCode == '38') {
player.moveUp();
}
else if (e.keyCode == '40') {
player.moveDown();
}
else if (e.keyCode == '37') {
player.moveLeft();
}
else if (e.keyCode == '39') {
player.moveRight();
}
else if (e.keyCode == '32') {
player.plantBomb();
}
}
}
//Destroy Game
static destroy () {
let targets = document.querySelectorAll('.target');
let tiles = document.querySelectorAll('.tile');
Player.resetScore();
if(tiles){
targets.forEach(function(element) {
element.remove();
});
tiles.forEach(function(element) {
element.remove();
});
}
}
}
class Session {
constructor () {
this.totalTargets = 0;
this.players = {};
this.restartBtn = document.querySelector('#restart');
this.restartBtn.addEventListener('click', function() {
Session.restart();
});
}
static restart () {
Game.destroy();
var game = new Game(25, 10, 10);
}
}
var session = new Session();
};
#map {
width: 500px;
height: 500px;
background: lightgrey;
position: relative;
margin: auto;
}
#game {
width: 500px;
height: 500px;
position: relative;
margin: auto;
}
#map .tile {
width: 50px;
height: 50px;
background: grey;
position: absolute;
outline: 1px solid #eee;
}
#map .target {
width: 50px;
height: 50px;
background: red;
position: absolute;
outline: 1px solid #eee;
}
#map #player {
border-radius: 25%;
width: 50px;
height: 50px;
position: absolute;
background: #222222;
z-index: 1;
transition: 0.1s;
}
.bomb {
border-radius: 100%;
width: 50px;
height: 50px;
position: absolute;
background: #333;
z-index: 1;
transition: 0.3s ease;
}
.bomb.waiting {
animation: waiting 2s infinite;
}
.bomb.before {
animation: before 1s infinite;
}
.bomb.explode {
animation: explode 1s infinite;
}
#score p, #score span {
font-family: sans-serif;
color: #333;
font-size: 16px;
display: inline;
}
#keyframes waiting {
0% {
transform: scale(0.9);
}
100% {
transform: scale(1.1);
}
}
#keyframes before {
0% {
transform: scale(1.0);
background: orange;
}
100% {
transform: scale(1.2);
background: red;
}
}
#keyframes explode {
0% {
transform: scale(1.0);
background: red;
opacity: 1;
}
100% {
transform: scale(2);
background: yellow;
opacity: 0;
}
}
#keyframes win {
0% {
opacity: 0;
}
10% {
opacity: 1;
}
66% {
opacity: 1;
}
100% {
opacity: 0;
}
}
h4 {
font-family: sans-serif;
color: #333;
text-align: center;
}
p, strong {
font-family: sans-serif;
color: #333;
text-align: left;
font-size: 12px;
}
#win {
position: fixed;
left: 0;
right: 0;
top:0;
bottom: 0;
z-index: 9999999;
background: rgba(181, 181, 195, 0.1);
pointer-events: none;
opacity: 0;
}
#win p {
color: red;
font-size: 130px;
text-align: center;
font-family: sans-serif;
text-transform: uppercase;
height: 100%;
margin: 0;
top: 50%;
position: absolute;
left: 50%;
transform: translate(-50%, -25%);
right: 0;
bottom: 0;
font-weight: bold;
text-shadow: 5px 5px #333;
}
#win.show {
animation: win 4s ease;
}
#restart {
text-align: center;
padding: 10px 20px;
font-family: sans-serif;
color: #333;
outline: #ccc 1px solid;
display: table;
margin: auto;
margin-top: 20px;
cursor: pointer;
transition: 0.1s ease;
}
#restart:hover {
background: #eee;
}
<!DOCTYPE html>
<html>
<head>
<title>Bomberman</title>
<link href="bomber.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="1.js"></script>
</head>
<body>
<h4>Space bar to plant a bomb / Arrows to move </h4>
<div id="win"><p>WIN !</p></div>
<div id="restart"> RESTART </div>
<div id="score"><p>Score: </p><span>0</span><strong> / 0</strong></div>
<section id="game">
<div id="map">
<div id="player"></div>
</div>
</section>
</body>
</html>
I'm not certain I understand your question, but I think you're trying to debug the createTargets method in the Targets class. The problem there is an extra closing bracket (}) right before the line with //Show Total Targets.

Toggle Individual Functions When an Event is Clicked - Javascript

I'd like to call a function that toggles on a node list of elements with the same class. I basically need to add the function within the if else statement, but the different variants of this seem to throw an error. When I put the code that is inside the two functions directly into the if else statement it works, but I want to do it with functions because this is a simplified version of what will be more complex style changes.
Codepen is here:https://codepen.io/emilychews/pen/GEEpqW?editors=1111
Code is below:
JS
var $mainMenuButton = document.getElementsByClassName('desktopmenubutton');
function newColor() {
e.currentTarget.style.background = "black";
}
function originalColor() {
e.currentTarget.style.background = "red";
}
for (h = 0; h < $mainMenuButton.length; h +=1) {
$mainMenuButton[h].addEventListener('click', function(e) {
if (e.currentTarget.style.backgroundColor === "red") {
newColor();
} else {
originalColor();
}
});
}
CSS
* {font-family: arial;}
.desktopmenubutton {
width: 150px;
height: 100px;
background-color: red;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
color: white
}
.button2 {
left: 300px;
}
HTML
<div class="desktopmenubutton button1">Button 1</div>
<div class="desktopmenubutton button2">Button 2</div>
Pass the element in the function that is inside the if statement.
var $mainMenuButton = document.getElementsByClassName('desktopmenubutton button1');
function newColor(element) {
element.currentTarget.style.backgroundColor = "black";
}
function originalColor(element) {
element.currentTarget.style.backgroundColor = "red";
}
for (h = 0; h < $mainMenuButton.length; h +=1) {
$mainMenuButton[h].addEventListener('click', function(e) {
if (e.currentTarget.style.backgroundColor === "red") {
newColor(e);
} else {
originalColor(e);
}
});
}
You forget to receive the event as a parameter on newColor and originalColor.
var $mainMenuButton =
document.getElementsByClassName('desktopmenubutton');
function newColor(e) {
e.currentTarget.style.background = "black";
}
function originalColor(e) {
e.currentTarget.style.background = "red";
}
for (h = 0; h < $mainMenuButton.length; h +=1) {
$mainMenuButton[h].addEventListener('click', function(e) {
if (e.currentTarget.style.backgroundColor === "red") {
newColor(e);
} else {
originalColor(e);
}
});
}
This should work.
You are not passing e(event) argument
Also note that Element.style.* reads inline css styles, not those styles which are assigned in CSS file/tag.
You could set red color initially in loop so that it could be accessed using Element.style.* property.
var $mainMenuButton = document.getElementsByClassName('desktopmenubutton');
function newColor(e) {
e.currentTarget.style.background = "black";
}
function originalColor(e) {
e.currentTarget.style.background = "red";
}
for (h = 0; h < $mainMenuButton.length; h += 1) {
$mainMenuButton[h].style.background = 'red';
$mainMenuButton[h].addEventListener('click', function(e) {
if (e.currentTarget.style.background == 'red') {
newColor(e);
} else {
originalColor(e);
}
});
}
* {
font-family: arial;
}
.desktopmenubutton {
width: 150px;
height: 100px;
background-color: red;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
color: white
}
.button2 {
left: 300px;
}
<div class="desktopmenubutton button1">Button 1</div>
<div class="desktopmenubutton button2">Button 2</div>

Categories