Reputation: 255
So I'm making a Tetris game and right now I'm trying to clear a row when each square is filled by a tetromino piece. So far I am able to determine if that row is filled up using the every() method on the row. It looks like this
function checkForPoints() {
for(let r = 0; r < row; r++) {
if(board[r].every(squareCheck)) {
alert('yo');
board[r].every(clearSquare);
}
}
function squareCheck(sq) {
if(sq !== vacant) return true;
else return false;
}
function clearSquare(sq) {
sq = vacant;
}
}
If every square in the row is filled up then the condition is true and it should proceed to make all squares black or vacant in this case. However this doesn't happen. I have no clue why? My every() method works in determining if every square is not vacant, but that same method won't work in changing that array's elements to equal "black" or vacant?
// //create your globals
// const canvas = document.querySelector('#canvas');
// const ctx = canvas.getContext('2d');
// const row = 20;
// const col = 10;
// const sq = 40;
// const vacant = 'black';
// //-----------------------Why can't I initialize the tetrominos??
// //create and draw board
// let board = [];
// for(let r = 0; r < row; r++) {
// board[r] = [];
// for(let c = 0; c < col; c++) {
// board[r][c] = vacant;
// draw(c, r, board[r][c]);
// }
// }
// //define a function to draw to the canvas
// function draw(x, y, color) {
// ctx.fillStyle = color;
// ctx.fillRect(x * sq, y * sq, sq, sq);
// ctx.strokeStyle = 'white';
// ctx.strokeRect(x * sq, y * sq, sq, sq);
// }
// //create an object for the tetrominos
// function Tetromino(tetromino, color) {
// this.tetromino = tetromino;
// this.color = color;
// this.tetrominoN = 0;
// this.activeTetromino = this.tetromino[this.tetrominoN];
// this.x = 0;
// this.y = 0;
// }
// //create an array for the pieces
// const pieces = [
// [Z, 'red'],
// [S, 'limegreen'],
// [T, 'yellow'],
// [O, 'blue'],
// [L, '#b938ff'],
// [I, 'cyan'],
// [J, 'orange']
// ]
// //create a new instance of Tetromino
// function randomPiece() {
// let r = Math.floor(Math.random() * pieces.length);
// return new Tetromino(pieces[r][0], pieces[r][1]);
// }
// let p = randomPiece();
// //draw the piece
// function drawPiece(piece) {
// //loop through the tetromino
// for(let r = 0; r < piece.length; r++) {
// for(let c = 0; c < piece.length; c++) {
// //if the tetromino index is zero skip it
// if(!piece[r][c]) continue;
// //else draw it
// else draw(p.x + c, p.y + r, p.color);
// }
// }
// }
// //undrawdraw the piece
// function undrawPiece(piece) {
// //loop through the tetromino
// for(let r = 0; r < piece.length; r++) {
// for(let c = 0; c < piece.length; c++) {
// //if the tetromino index is zero skip it
// if(!piece[r][c]) continue;
// //else draw it
// else draw(p.x + c, p.y + r, vacant);
// }
// }
// }
// drawPiece(p.activeTetromino);
// //control the piece
// document.addEventListener('keydown', (event) => {
// if(event.keyCode === 37) p.moveLeft();
// else if (event.keyCode === 38) p.rotate();
// else if (event.keyCode === 39) p.moveRight();
// else if (event.keyCode === 40) p.moveDown();
// });
// Tetromino.prototype.moveDown = function() {
// if(!this.collision(0, 1, this.activeTetromino)) {
// undrawPiece(this.activeTetromino);
// this.y++;
// drawPiece(this.activeTetromino);
// } else {
// //lock piece and generate a new one
// this.lock();
// p = randomPiece();
// }
// }
// Tetromino.prototype.moveLeft = function() {
// if(!this.collision(-1, 0, this.activeTetromino)) {
// undrawPiece(this.activeTetromino);
// this.x--;
// drawPiece(this.activeTetromino);
// }
// }
// Tetromino.prototype.moveRight = function() {
// if(!this.collision(1, 0, this.activeTetromino)) {
// undrawPiece(this.activeTetromino);
// this.x++;
// drawPiece(this.activeTetromino);
// }
// }
// Tetromino.prototype.rotate = function() {
// let nextPattern = this.tetromino[(this.tetrominoN + 1) % 4];
// if(!this.collision(0, 0, nextPattern)) {
// if(this.tetromino.length > 1) {
// undrawPiece(this.activeTetromino);
// this.tetrominoN = (this.tetrominoN + 1) % 4; // take paranthesis off
// this.activeTetromino = this.tetromino[this.tetrominoN];
// drawPiece(this.activeTetromino);
// }
// }
// }
// //create a function to check for collisions
// Tetromino.prototype.collision = function(x, y, piece) {
// for(let r = 0; r < piece.length; r++) {
// for(let c = 0; c < piece.length; c++) {
// //skip index if it is 0
// if(!piece[r][c]) continue;
// //create vars for the future piece position
// let newX = this.x + c + x;
// let newY = this.y + r + y;
// //see if new position collides with border
// if(newX < 0 || newX >= col || newY >= row) return true;
// //see if there's a locked piece on the board
// if(board[newY][newX] !== vacant) return true;
// }
// }
// return false;
// }
// Tetromino.prototype.lock = function() {
// for(let r = 0; r < this.activeTetromino.length; r++) {
// for(let c = 0; c < this.activeTetromino.length; c++) {
// if(!this.activeTetromino[r][c]) continue;
// //if piece reaches the top its gameover
// if(this.y + r < 0) {
// gameover = true;
// alert('Game Over!');
// }
// //lock the piece by updating the board
// board[this.y + r][this.x + c] = this.color;
// }
// }
// }
// let dropStart = Date.now();
// //drop the piece every 1s
// function drop() {
// let now = Date.now();
// let delta = now - dropStart;
// //if delta is greater than 1s drop the piece
// if(delta > 800) {
// p.moveDown();
// dropStart = Date.now();
// }
// requestAnimationFrame(drop);
// }
// drop();
//declare globals
const col = 10;
const row = 20;
const sq = 40;
const vacant = 'black';
const cvs = document.querySelector('#canvas');
const ctx = cvs.getContext('2d');
let gameOver = false;
//create and draw the board
let board = [];
for(let r = 0; r < row; r++) {
board[r] = [];
for(let c = 0; c < col; c++) {
board[r][c] = vacant;
draw(c, r, board[r][c]);
}
}
//create a blueprint function to draw to the board
function draw(x, y, color) {
//set the drawing specifications
ctx.fillStyle = color;
ctx.fillRect(x * sq, y * sq, sq, sq);
ctx.strokeStyle = 'white';
ctx.strokeRect(x * sq, y * sq, sq, sq);
}
//create a blueprint object for the tetrominos
function Piece(tetromino, color) {
//create the properties
this.tetromino = tetromino;
this.color = color;
this.tetrominoN = 0;
this.activeTetromino = this.tetromino[this.tetrominoN];
this.x = 0;
this.y = -1;
if (this.tetromino === pieces[5][0]) this.y = -2;
}
//create an array to hold all of the tetrominos
const pieces = [
[Z, 'red'],
[S, 'limegreen'],
[T, 'yellow'],
[O, 'blue'],
[L, '#b938ff'],
[I, 'cyan'],
[J, 'orange']
]
function randomPiece() {
let r = Math.floor(Math.random()*pieces.length);
return new Piece(pieces[r][0], pieces[r][1]);
}
//grab a piece
let p = randomPiece();
//draw a piece to the board
// drawPiece(p.activeTetromino, p.color);
//create a blueprint function to draw tetrominos to the board
function drawPiece(piece, color) {
for(let r = 0; r < piece.length; r++) {
for(let c = 0; c < piece.length; c++) {
if (!piece[r][c]) continue;
draw(c + p.x, r + p.y, color);
}
}
}
//control the piece
document.addEventListener('keydown', (e) => {
//check user's input
if(e.keyCode === 37) p.moveLeft();
else if(e.keyCode === 38) p.rotate();
else if(e.keyCode === 39) p.moveRight();
else if (e.keyCode === 40) p.moveDown();
});
Piece.prototype.moveDown = function() {
if(!this.collision(0, 1, this.activeTetromino)) {
drawPiece(this.activeTetromino, vacant);
this.y++;
drawPiece(this.activeTetromino, this.color);
} else {
this.lockPiece(this.activeTetromino);
checkForPoints();
p = randomPiece();
}
}
Piece.prototype.moveLeft = function() {
if(!this.collision(-1, 0, this.activeTetromino)) {
drawPiece(this.activeTetromino, vacant);
this.x--;
drawPiece(this.activeTetromino, this.color);
}
}
Piece.prototype.moveRight = function() {
if(!this.collision(1, 0, this.activeTetromino)) {
drawPiece(this.activeTetromino, vacant);
this.x++;
drawPiece(this.activeTetromino, this.color);
}
}
Piece.prototype.rotate = function() {
let nextPattern = this.tetromino[(this.tetrominoN + 1) % 4];
let kick = 0;
if (this.collision(0, 0, nextPattern)) {
if(this.x < col/2) {
if(this.x === -2) {
kick = 2;
} else {
kick = 1; //kick from right
}
}
if(this.x > col/2) {
if(this.tetromino === pieces[5][0]) {
kick = -2;
} else {
kick = -1; //kick from left
}
}
}
if(!this.collision(kick, 0, nextPattern)) {
drawPiece(this.activeTetromino, vacant);
this.x += kick;
this.tetrominoN = (this.tetrominoN + 1) % 4;
this.activeTetromino = this.tetromino[this.tetrominoN];
drawPiece(this.activeTetromino, this.color);
}
}
Piece.prototype.collision = function(x, y, piece) {
for (let r = 0; r < piece.length; r++) {
for(let c = 0; c < piece.length; c++) {
if(!piece[r][c]) continue;
let newX = this.x + c + x;
let newY = this.y + r + y;
if(newX < 0 || newX >= col || newY >= row) return true;
if(board[newY][newX] !== vacant) return true;
}
}
return false;
}
Piece.prototype.lockPiece = function(piece) {
for (let r = 0; r < piece.length; r++) {
for(let c = 0; c < piece.length; c++) {
if(!piece[r][c]) continue;
if(this.y + r === 1) alert('yo');
if(this.y + r <= 0) {
alert('Game Over');
gameOver = true;
break;
}
board[this.y + r][this.x + c] = this.color;
}
}
}
function checkForPoints() {
for(let r = 0; r < row; r++) {
if(board[r].every(squareCheck)) {
alert('yo');
board[r].every(clearSquare);
}
}
function squareCheck(sq) {
if(sq !== vacant) return true;
else return false;
}
function clearSquare(sq) {
sq = vacant;
}
}
//start a time to set as a refrence for the dropstart
let dropStart = Date.now();
//create a blueprint function to drop the piece
function drop() {
//grab the current time
let now = Date.now();
//create a var to hold the difference of the current time
let delta = now - dropStart; //------Why can't these be switched------
if(delta > 800) {
dropStart = Date.now();
p.moveDown();
//------put request animation here------
}
if (!gameOver) requestAnimationFrame(drop);
}
drop();
<!-- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tetris</title>
<link href="https://fonts.googleapis.com/css?family=Orbitron&display=swap" rel="stylesheet">
</head>
<style>
body {
background-color: #595959;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow-y: hidden;
}
canvas {
outline: 1px solid white;
}
.canvas-wrap {
padding-left: 50px;
padding-top: 50px;
position: relative;
}
.num-top, .num-bottom {
position: absolute;
top: -1px;
left: 0;
}
.num-top {
width: 100%;
height: 50px;
}
.num-bottom {
height: 100%;
width: 50px;
}
.nb {
font-family: 'Orbitron';
color: white;
}
.num-wrap-t {
display: flex;
justify-content: space-around;
margin-left: 50px;
width: 400px;
}
.num-wrap-b {
display: flex;
flex-direction: column;
justify-content: space-around;
margin-top: 50px;
height: 800px;
}
.num-wrap-b .nb {
text-align: right;
margin-right: 3px;
}
.num-wrap-t .nb {
position: relative;
top: 31px;
}
</style>
<body>
<div class="canvas-wrap">
<div class="num-top">
<div class="num-wrap-t">
<div class="nb">0</div>
<div class="nb">1</div>
<div class="nb">2</div>
<div class="nb">3</div>
<div class="nb">4</div>
<div class="nb">5</div>
<div class="nb">6</div>
<div class="nb">7</div>
<div class="nb">8</div>
<div class="nb">9</div>
</div>
</div>
<canvas id="canvas" width="400" height="800"></canvas>
<div class="num-bottom">
<div class="num-wrap-b">
<div class="nb">0</div>
<div class="nb">1</div>
<div class="nb">2</div>
<div class="nb">3</div>
<div class="nb">4</div>
<div class="nb">5</div>
<div class="nb">6</div>
<div class="nb">7</div>
<div class="nb">8</div>
<div class="nb">9</div>
<div class="nb">10</div>
<div class="nb">11</div>
<div class="nb">12</div>
<div class="nb">13</div>
<div class="nb">14</div>
<div class="nb">15</div>
<div class="nb">16</div>
<div class="nb">17</div>
<div class="nb">18</div>
<div class="nb">19</div>
</div>
</div>
</div>
<script src="tetrominos.js"></script>
<script src="tetris.js"></script>
</body>
</html> -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tetris</title>
<link href="https://fonts.googleapis.com/css?family=Orbitron&display=swap" rel="stylesheet">
</head>
<style>
body, html {
padding: 0;
margin: 0;
}
body {
background-color: #595959;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
canvas {
outline: 1px solid white;
}
.canvas-wrap {
padding-left: 50px;
padding-top: 50px;
position: relative;
}
.num-top, .num-bottom {
position: absolute;
top: -1px;
left: 0;
}
.num-top {
width: 100%;
height: 50px;
}
.num-bottom {
height: 100%;
width: 50px;
}
.nb {
font-family: 'Orbitron';
color: white;
}
.num-wrap-t {
display: flex;
justify-content: space-around;
margin-left: 50px;
width: 400px;
}
.num-wrap-b {
display: flex;
flex-direction: column;
justify-content: space-around;
margin-top: 50px;
height: 800px;
}
.num-wrap-b .nb {
text-align: right;
margin-right: 3px;
}
.num-wrap-t .nb {
position: relative;
top: 31px;
}
</style>
<body>
<div class="canvas-wrap">
<div class="num-top">
<div class="num-wrap-t">
<div class="nb">0</div>
<div class="nb">1</div>
<div class="nb">2</div>
<div class="nb">3</div>
<div class="nb">4</div>
<div class="nb">5</div>
<div class="nb">6</div>
<div class="nb">7</div>
<div class="nb">8</div>
<div class="nb">9</div>
</div>
</div>
<canvas id="canvas" width="400" height="800"></canvas>
<div class="num-bottom">
<div class="num-wrap-b">
<div class="nb">0</div>
<div class="nb">1</div>
<div class="nb">2</div>
<div class="nb">3</div>
<div class="nb">4</div>
<div class="nb">5</div>
<div class="nb">6</div>
<div class="nb">7</div>
<div class="nb">8</div>
<div class="nb">9</div>
<div class="nb">10</div>
<div class="nb">11</div>
<div class="nb">12</div>
<div class="nb">13</div>
<div class="nb">14</div>
<div class="nb">15</div>
<div class="nb">16</div>
<div class="nb">17</div>
<div class="nb">18</div>
<div class="nb">19</div>
</div>
</div>
</div>
<script src="tetrominos.js"></script>
<script src="tetris.js"></script>
</body>
</html>
Upvotes: 0
Views: 76
Reputation: 1721
From documentation:
The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.
The passed function is a TEST function, I imagine that behind the scenes it creates a copy of your array element and activates the function on it.
Upvotes: -2
Reputation: 138267
JavaScript has call by sharing so if you do sq =
that will only affect the local sq
variable, not the value in the array. You have to directly assign the new value to the array, e.g. board[r][i] = vacant;
...
Additionally .every
is the wrong tool then, use .forEach
or for(let i = 0; i < board[r].length; i++)
, and then reassign the values.
Or could just create a new array and reassign it:
board[r] = new Array(board[r].length).fill(vacant);
that could also be done with .map
.
Upvotes: 4