Small issues with an interactive project in p5.js / javascript - javascript

I need help with an interactive project in p5.js.
Here are the things that are still missing:
the clock hands should rotate
when the puzzle is solved "won" should be displayed and the timer should stop (Here I have a code part in my program but it doesn´t work)
the "moves" don´t count up when you click somewhere - only at the specific field
at "Game Over" the picture and the clock should stop
Here is a picture of the puzzle: Slide Puzzle
I hope someone can help me. Thank you very much.
Here is the code:
let w = window.innerWidth/2;
let h = window.innerHeight/1.5;
let ground;
let plate = [];
let tiles = [];
let col = 4;
let row = 4;
let bubbles = [];
let timerValue = 160;
let moves = 0;
function setup() {
canvas = createCanvas(w, h);
ground = createGraphics(w, h);
w = width / col;
h = height / row;
textAlign(CENTER, CENTER);
setInterval(timeIt, 1000);
imag = loadImage('Mauszeiger.png');
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
let img = createImage(w, h);
let index = i + j * col;
plate.push(index);
let teil = new Tile(index, img);
tiles[index] = teil;
}
}
tiles.pop();
plate.pop();
plate.push(-1);
startViz();
simpleShuffle(plate);
}
function draw() {
background(100);
push();
scale(1, 0.9);
drawViz();
updateTiles();
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
let index = i + j * col;
let x = i * w;
let y = j * h;
let teileIndex = plate[index];
if (teileIndex > -1) {
let img = tiles[teileIndex].img;
image(img, x, y, w, h);
}
strokeWeight(5);
noFill();
rect(x, y, w, h);
}
}
pop();
if (isSolved()) {
console.log('SOLVED');
timerValue = 0;
text('Won', width/2, height/2);
}
if (timerValue < 10 || timerValue >= 10) {
textSize(15);
fill(255);
text(timerValue, width-30, height*0.95);
}
textSize(45);
if (timerValue == 0) {
text('Game Over', width/2, height/2);
draw = function(){}
}
textSize(15);
text('moves: ' + moves, width/2, height*0.95);
push();
noFill();
stroke(255);
ellipse(27, height*0.95, 40, 40);
imageMode(CENTER);
image(imag, 30, height*0.95, imag.width / 100, imag.height / 100);
pop();
}
function mousePressed() {
let i = floor(mouseX / w);
let j = floor(mouseY / h);
move(i, j, plate);
if (mousePressed) {
moves++;
}
}
function windowResized() {
w = window.innerWidth/2;
h = window.innerHeight/1.5;
resizeCanvas(w, h);
}
function timeIt() {
if (timerValue > 0) {
timerValue--;
}
}
function isSolved() {
for (let i = 0; i < plate.length - 1; i++) {
if (plate[i] !== tiles[i].index) {
return false;
}
}
return true;
}
function updateTiles() {
for (let i = 0; i < col; i++) {
for (let j = 0; j < row; j++) {
let x = j * w;
let y = i * h;
let index = i + j * col;
if (tiles[index]) tiles[index].img.copy(ground, x, y, w, h, 0, 0, w, h);
}
}
}
function swap(i, j, arr) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function randomMove(arr) {
let r1 = floor(random(col));
let r2 = floor(random(row));
move(r1, r2, arr);
}
function simpleShuffle(arr) {
for (let i = 0; i < 1000; i++) {
randomMove(arr);
}
}
function move(i, j, arr) {
let blank = findBlank();
let blankCol = blank % col;
let blankRow = floor(blank / row);
if (isNeighbor(i, j, blankCol, blankRow)) {
swap(blank, i + j * col, arr);
}
}
function isNeighbor(i, j, x, y) {
if (i !== x && j !== y) {
return false;
}
if (abs(i - x) == 1 || abs(j - y) == 1) {
return true;
}
return false;
}
function findBlank() {
for (let i = 0; i < plate.length; i++) {
if (plate[i] == -1) return i;
}
}
function startViz() {
for (let i = 0; i < 5; i++) {
bubbles.push(new Bubble());
}
}
function drawViz() {
ground.background(30);
for (let b of bubbles) {
b.update();
b.show();
b.show1();
}
}
class Bubble {
constructor() {
this.r = random(50, 80);
this.x = random(this.r, width - this.r);
this.y = random(this.r, height - this.r);
this.vx = random(-1 * (w*0.005), 3 * (w*0.005));
this.vy = random(-1 * (w*0.005), 3 * (w*0.005));
this.color = color(random(255), random(255), random(255));
}
show() {
ground.noFill();
ground.stroke(255);
ground.fill(this.color);
ground.strokeWeight(3);
ground.circle(this.x, this.y, this.r * 2 * (w*0.005));
}
show1() {
ground.line(this.x, this.y, this.x + this.r / 2 * (w*0.005), this.y + this.r / 2 * (w*0.005));
ground.line(this.x, this.y, this.x - this.r / 2 * (w*0.005), this.y + this.r / 2 * (w*0.005));
}
update() {
this.x += this.vx;
this.y += this.vy;
if (this.x > width - this.r || this.x < this.r) {
this.vx *= -1;
}
if (this.y > height - this.r || this.y < this.r) {
this.vy *= -1;
}
}
}
class Tile {
constructor(i, img) {
this.index = i;
this.img = img;
}
}

Related

How to make a grid of moiré circles in p5.js?

I'm attempting to make a grid where every tile is filled with a single "moire-style" ellipse (a circle with circles inside).
function setup() {
createCanvas(500, 500);
ellipseMode(CENTER);
}
function draw() {
background(255);
noFill();
strokeWeight(3);
stroke(0);
let tilesX = 3;
let tilesY = tilesX;
let tileW = width / tilesX;
let tileH = height / tilesY;
for (let x = 0; x < tilesX; x++) {
for (let y = 0; y < tilesY; y++) {
moire(tilesX, tilesY, tileW);
}
}
function moire(x, y, size) {
for (var i = 1; i <= tileW; i = i + 8) {
ellipse(width / 2, height / 2, 2 * i, 2 * i);
translate(tilesX, tilesY);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
This is what I have in my p5.js sketch but the moire elements don't align to the tiles.
The following demo will create a grid of moire circles:
let _numRows = 3;
let _numCols = 3;
let _colGap = 30;
let _rowGap = 30;
function moire(x, y, size) {
for (var i = 1; i <= size; i = i + 8) {
ellipse(x, y, 2 * i, 2 * i);
translate(3, 3);
}
}
function setup() {
createCanvas(500, 500);
ellipseMode(CENTER);
}
function draw() {
background(255);
noFill();
strokeWeight(3);
stroke(0);
let _xOffset = width/5;
let _yOffset = height/5;
for (let j = 0; j < _numCols; j++) {
for (let k = 0; k < _numRows; k++) {
push();
moire(_xOffset + j * (100 + _colGap), _yOffset + k * (100 + _rowGap), 50);
pop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

Problems with translating c++ to javascript

I was trying to replicate this c++ code in javascript.
https://github.com/OneLoneCoder/videos/blob/master/OneLoneCoder_PathFinding_AStar.cpp
The code should draw a yellow line from the red point to the green point.
I checked my implementation multiple times but I still can't figure out why it is not working.
For some reason it won't set the parent for my objects correctly.
Which results in the path not getting drawn.
Could really need some help here.
width = 11;
height = 9;
s = 50;
c = document.createElement("canvas");
document.body.appendChild(c);
ctx = c.getContext("2d");
c.width = width * s;
c.height = height * s;
nodes = [];
for (x = 0; x < width; x++) {
row = [];
nodes.push(row);
for (y = 0; y < height; y++) {
row.push(new Node(x, y));
}
}
SetNeighbours();
function SetNeighbours() {
for (x = 0; x < width; x++) {
for (y = 0; y < height; y++) {
if (x > 0) {
nodes[x][y].neighbours.push(nodes[x - 1][y])
}
if (x < width - 1) {
nodes[x][y].neighbours.push(nodes[x + 1][y])
}
if (y > 0) {
nodes[x][y].neighbours.push(nodes[x][y - 1])
}
if (y < height - 1) {
nodes[x][y].neighbours.push(nodes[x][y + 1])
}
}
}
}
nodes[3][0].obstacle = true;
nodes[3][1].obstacle = true;
nodes[3][2].obstacle = true;
nodes[3][3].obstacle = true;
nodes[3][4].obstacle = true;
nodes[3][5].obstacle = true;
nodes[7][3].obstacle = true;
nodes[7][4].obstacle = true;
nodes[7][5].obstacle = true;
nodes[7][6].obstacle = true;
nodes[7][7].obstacle = true;
nodes[7][8].obstacle = true;
start = nodes[1][1];
end = nodes[9][7];
//end.parent = nodes[9][6];
//nodes[9][6].parent = nodes[9][5]
current = start;
start.localGlobal = 0;
start.globalGoal = heuristic(start, end);
notTested = [];
notTested.push(start);
while (notTested.length > 0 && current != end) {
notTested.sort(function(a, b) {
return a.globalGoal < b.globalGoal
});
while (notTested.length > 0 && notTested[0].visited) {
notTested.shift();
}
if (notTested.length == 0) {
break;
}
current = notTested[0];
current.visited = true;
for (let n of current.neighbours) {
if (!n.visited && !n.obstacle) {
notTested.push(n);
}
newGoal = current.localGoal + distance(current, n);
if (newGoal < n.localGoal) {
n.parent = current;
n.localGoal = newGoal;
n.globalGoal = n.localGoal + heurisitc(n, end);
}
}
}
DrawCanvas();
function DrawCanvas() {
for (x = 0; x < width; x++) {
for (y = 0; y < height; y++) {
for (let node of nodes[x][y].neighbours) {
ctx.beginPath();
ctx.moveTo(x * s + (s / 2), y * s + (s / 2));
ctx.lineTo(node.x * s + (s / 2), node.y * s + (s / 2));
ctx.lineWidth = 5;
ctx.strokeStyle = "navy";
ctx.stroke();
}
}
}
for (x = 0; x < width; x++) {
for (y = 0; y < height; y++) {
if (nodes[x][y] == start) {
ctx.fillStyle = "crimson";
} else if (nodes[x][y] == end) {
ctx.fillStyle = "green";
} else if (nodes[x][y].visited) {
ctx.fillStyle = "blue";
} else if (nodes[x][y].obstacle) {
ctx.fillStyle = "grey";
} else {
//ctx.fillStyle = x % 2 != y % 2 ? "lightgrey" : "darkgrey";
ctx.fillStyle = "navy";
}
ctx.fillRect(x * s + 5, y * s + 5, s - 10, s - 10);
}
}
}
if (end != null) {
p = end;
while (p.parent != null) {
ctx.beginPath();
ctx.moveTo(p.x * s + (s / 2), p.y * s + (s / 2));
ctx.lineTo(p.parent.x * s + (s / 2), p.parent.y * s + (s / 2));
ctx.lineWidth = 5;
ctx.strokeStyle = "yellow";
ctx.stroke();
p = p.parent;
}
}
function Node(x, y) {
this.obstacle = false;
this.visited = false;
this.globalGoal = 1000000;
this.localGoal = 1000000;
this.x = x;
this.y = y;
this.neighbours = [];
this.parent = null;
}
function distance(a, b) {
return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2)
}
function heuristic(a, b) {
return distance(a, b);
}
body
{
background: black;
}
In line where you set current variable you have a typo
There should be start.localGoal = 0; and not start.localGlobal = 0;
width = 11;
height = 9;
s = 50;
c = document.createElement("canvas");
document.body.appendChild(c);
ctx = c.getContext("2d");
c.width = width * s;
c.height = height * s;
nodes = [];
for (let x = 0; x < width; x++) {
nodes[x] = [];
for (let y = 0; y < height; y++) {
nodes[x].push(new Node(x, y));
}
}
SetNeighbours();
function SetNeighbours() {
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
if (x > 0) {
nodes[x][y].neighbours.push(nodes[x - 1][y])
}
if (x < width - 1) {
nodes[x][y].neighbours.push(nodes[x + 1][y])
}
if (y > 0) {
nodes[x][y].neighbours.push(nodes[x][y - 1])
}
if (y < height - 1) {
nodes[x][y].neighbours.push(nodes[x][y + 1])
}
}
}
}
nodes[3][0].obstacle = true;
nodes[3][1].obstacle = true;
nodes[3][2].obstacle = true;
nodes[3][3].obstacle = true;
nodes[3][4].obstacle = true;
nodes[3][5].obstacle = true;
nodes[7][3].obstacle = true;
nodes[7][4].obstacle = true;
nodes[7][5].obstacle = true;
nodes[7][6].obstacle = true;
nodes[7][7].obstacle = true;
nodes[7][8].obstacle = true;
start = nodes[1][1];
end = nodes[9][7];
//end.parent = nodes[9][6];
//nodes[9][6].parent = nodes[9][5]
start.localGoal = 0;
start.globalGoal = heuristic(start, end);
current = start;
notTested = [];
notTested.push(start);
while (notTested.length > 0 && current !== end) {
notTested.sort(function (a, b) {
return a.globalGoal < b.globalGoal
});
while (notTested.length > 0 && notTested[0].visited) {
notTested.shift();
}
if (notTested.length === 0) {
break;
}
const current = notTested[0];
current.visited = true;
for (let n of current.neighbours) {
if (!n.visited && !n.obstacle) {
notTested.push(n);
}
const newGoal = current.localGoal + distance(current, n);
if (newGoal < n.localGoal) {
n.parent = current;
n.localGoal = newGoal;
n.globalGoal = n.localGoal + heuristic(n, end);
}
}
}
DrawCanvas();
function DrawCanvas() {
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
for (let node of nodes[x][y].neighbours) {
ctx.beginPath();
ctx.moveTo(x * s + (s / 2), y * s + (s / 2));
ctx.lineTo(node.x * s + (s / 2), node.y * s + (s / 2));
ctx.lineWidth = 5;
ctx.strokeStyle = "navy";
ctx.stroke();
}
}
}
for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
if (nodes[x][y] === start) {
ctx.fillStyle = "crimson";
} else if (nodes[x][y] === end) {
ctx.fillStyle = "green";
} else if (nodes[x][y].visited) {
ctx.fillStyle = "blue";
} else if (nodes[x][y].obstacle) {
ctx.fillStyle = "grey";
} else {
//ctx.fillStyle = x % 2 != y % 2 ? "lightgrey" : "darkgrey";
ctx.fillStyle = "navy";
}
ctx.fillRect(x * s + 5, y * s + 5, s - 10, s - 10);
}
}
}
if (end != null) {
p = end;
while (p.parent != null) {
ctx.beginPath();
ctx.moveTo(p.x * s + (s / 2), p.y * s + (s / 2));
ctx.lineTo(p.parent.x * s + (s / 2), p.parent.y * s + (s / 2));
ctx.lineWidth = 5;
ctx.strokeStyle = "yellow";
ctx.stroke();
p = p.parent;
}
}
function Node(x, y) {
this.obstacle = false;
this.visited = false;
this.globalGoal = 1000000;
this.localGoal = 1000000;
this.x = x;
this.y = y;
this.neighbours = [];
this.parent = null;
}
function distance(a, b) {
return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2);
}
function heuristic(a, b) {
return distance(a, b);
}
body
{
background: black;
}

Why does it undefined when it should have defined it?

After the maze is generated, if you move your player around a bit, soon it'll say "No cell found", which happens whenever the cell is undefined. I don't know why the cell is not in the check array. I really don't know what to do to fix this, or why it's not being added to the array. Also sometimes you can't move a certain direction your supposed to move, and you can move through walls. I think this is because some cells are added twice. My full program is underneath.
var cols, rows;
var diffeculty = 0;
var w = 50;
var grid = [];
var stack = [];
var current;
var check = []
var k = 0;
var m = 0;
var won = false;
function setup() {
//frameRate(10)
createCanvas(600, 400);
cols = floor(width / w)
rows = floor(height / w)
for (var j = 0; j < rows; j++) {
for (var i = 0; i < cols; i++) {
var cell = new Cell(i, j)
grid.push(cell)
}
}
current = grid[0];
}
function index(i, j) {
if (i < 0 || j < 0 || i > cols - 1 || j > cols - 1) {
return -1;
}
return i + j * cols
}
function Cell(i, j) {
this.visited = false;
this.i = i;
this.j = j;
this.walls = [true, true, true, true];
this.checkNeighbors = function() {
var neighbors = []
var top = grid[index(i, j - 1)]
var right = grid[index(i + 1, j)]
var left = grid[index(i - 1, j)]
var bottom = grid[index(i, j + 1)]
var Wall = this.walls;
var wall=[]
wall.push(i,j,Wall)
if (top && !top.visited) {
neighbors.push(top);
}
if (right && !right.visited) {
neighbors.push(right);
}
if (bottom && !bottom.visited) {
neighbors.push(bottom);
}
if (left && !left.visited) {
neighbors.push(left);
}
if (neighbors.length > 0) {
var r = floor(random(0, neighbors.length))
return neighbors[r];
} else {
return undefined;
}
}
this.highlight = function() {
var x = this.i * w;
var y = this.j * w;
noStroke();
fill(0, 0, 255, 100)
rect(x, y, w, w);
}
this.show = function() {
var x = this.i * w;
var y = this.j * w;
stroke(255);
noFill();
if (this.walls[0]) {
line(x, y, x + w, y);
}
if (this.walls[1]) {
line(x + w, y, x + w, y + w);
}
if (this.walls[2]) {
line(x + w, y + w, x, y + w);
}
if (this.walls[3]) {
line(x, y + w, x, y);
}
if (this.visited) {
fill(255, 0, 255, 100);
noStroke();
rect(x, y, w, w);
}
}
};
function removeWalls(a, b) {
var x = a.i - b.i;
if (x === 1) {
a.walls[3] = false;
b.walls[1] = false;
} else if (x === -1) {
a.walls[1] = false;
b.walls[3] = false;
}
var y = a.j - b.j;
if (y === 1) {
a.walls[0] = false;
b.walls[2] = false;
} else if (y === -1) {
a.walls[2] = false;
b.walls[0] = false;
}
}
function draw() {
background(51);
for (var i = 0; i < grid.length; i++) {
grid[i].show()
}
//Step One
current.visited = true;
current.highlight();
var next = current.checkNeighbors()
if (next) {
next.visited = true;
//Step 2
stack.push(current);
check.push(current)
//Step 3
removeWalls(current, next)
{}
//Step 4
current = next;
} else if (stack.length > 0) {
current = stack.pop();
}
if (stack[0] === undefined) {
fill(0, 105, 100)
rect(0, 0, w, w)
rect(width - w, height - w, w, w)
frameRate(8)
var c = check.find(cell => cell.i == ~~(k/w) && cell.j == ~~(m/w));
if(c===undefined){
console.log('no cell found');
}else{
console.log('i',c.i,'j', c.j,'walls', c.walls);
}
if(keyIsDown(UP_ARROW)&&!c.walls[0]) {
k -= w
}
if (keyIsDown(RIGHT_ARROW)&&!c.walls[1]) {
m += w
}
if (keyIsDown(DOWN_ARROW)&&!c.walls[2]) {
k += w
}
if (keyIsDown(LEFT_ARROW)&&!c.walls[3]) {
m -= w
}
fill(0, 255, 255, 100)
rect(m, k, w, w)
if (m < 0) {
m = 0
}
if (k < 0) {
k = 0
}
if (m > width - w) {
m = width - w
}
if (k > height - w) {
k = height - w
}
if (k === height - w && m === width - w || won === true) {
won = true
background(0)
textSize(40)
text("You Win", width / 2, height / 2)
}
}
}
I can spot a couple of problems with function index(i, j):
if i is cols and j is rows, then if you if statement, you should check i > rows - 1 instead of i > cols - 1
you probably want to return cols-1 instead of cols:
return i + j * cols-1;

Need help to draw a X for Tic Tac Toe in p5.js

I was following a tutorial on Youtube (The Coding Train) which was making a minesweeper game. I followed the video until I had make a X.
I want to make to lines that cross each other and form a big x like this:
The board with a X
The problem I have is that I do not know how to that with each cell.
I have a Cell class:
function Cell(x, y, w) {
this.x = x;
this.y = y;
this.w = w;
this.busy = true;
this.player = true;
this.computer = true;
}
Cell.prototype.show = function() {
stroke(0);
noFill();
rect(this.x, this.y, this.w, this.w);
if (true) {
line(0, 0, 100, 100);
line(0, 100, 100, 0);
}
}
And the main code is:
function make2DArray(cols, rows) {
var arr = new Array(cols);
for (var i = 0; i < arr.length; i++) {
arr[i] = new Array(rows);
}
return arr;
}
var grid;
var rows;
var cols;
var w = 100;
function setup() {
createCanvas(300, 300);
cols = floor(width/w);
rows = floor(width/w);
grid = make2DArray(cols, rows);
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
grid[i][j] = new Cell(i * w, j * w, w);
}
}
}
function draw() {
background(255);
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
grid[i][j].show();
}
}
}
I want to be able to call a X when a player clicks on a cell, and display it. The line needs to be in the Cell class in Show object.
The coordinate of the top left corner of each Cell is stored in the x and y properties. The width is stored in w.
So a cross over the entire Cell can be draw by:
line(this.x, this.y, this.x+this.w-1, this.y+this.w-1);
line(this.x, this.y+this.w-1, this.x+this.w-1, this.y);
To draw a cross in a Cell dependent on a click into the cell, you have to init the player property by false:
function Cell(x, y, w) {
.......
this.player = false;
}
Draw the cross it the Cell dependent on the player property:
Cell.prototype.show = function() {
stroke(0);
noFill();
rect(this.x, this.y, this.w-1, this.w-1);
if (this.player) {
line(this.x, this.y, this.x+this.w-1, this.y+this.w-1);
line(this.x, this.y+this.w-1, this.x+this.w-1, this.y);
}
}
Create a function which checks if a point is in the Cell and set the player property true, if the test succeeds:
Cell.prototype.testX = function(px, py) {
if (px >= this.x && px < this.x+this.w && py >= this.y && py < this.y+this.w ) {
this.player = true;
}
}
Add a mousePressed event, and call the test function testX for each Cell. if the mouse position is in a cell, then the player property of the Cell will become true and a cross will appear in the Cell at the next draw:
function mousePressed() {
if (mouseButton == LEFT) {
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
grid[i][j].testX(mouseX, mouseY);
}
}
}
}
function Cell(x, y, w) {
this.x = x;
this.y = y;
this.w = w;
this.busy = true;
this.computer = true;
this.player = false;
}
Cell.prototype.show = function() {
stroke(0);
noFill();
rect(this.x, this.y, this.w-1, this.w-1);
if (this.player) {
line(this.x, this.y, this.x+this.w-1, this.y+this.w-1);
line(this.x, this.y+this.w-1, this.x+this.w-1, this.y);
}
}
Cell.prototype.testX = function(px, py) {
if (px >= this.x && px < this.x+this.w && py >= this.y && py < this.y+this.w ) {
this.player = true;
}
}
function mousePressed() {
if (mouseButton == LEFT) {
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
grid[i][j].testX(mouseX, mouseY);
}
}
}
}
function make2DArray(cols, rows) {
var arr = new Array(cols);
for (var i = 0; i < arr.length; i++) {
arr[i] = new Array(rows);
}
return arr;
}
var grid;
var rows;
var cols;
var w = 100;
function setup() {
createCanvas(300, 300);
cols = floor(width/w);
rows = floor(width/w);
grid = make2DArray(cols, rows);
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
grid[i][j] = new Cell(i * w, j * w, w);
}
}
}
function draw() {
background(255);
for (var i = 0; i < cols; i++) {
for (var j = 0; j < rows; j++) {
grid[i][j].show();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>

JavaScript Brick Breaker, Bricks in array aren't being spliced?

I'm having trouble with how I remove bricks. The bricks are part of an array, and the ball continuously runs a for loop checking to see if it's hit any bricks. If it does, it splices that brick from the array. But the bricks don't disappear!
//Helper Functions
function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
return ax < bx+bw && ay < by+bh && bx < ax+aw && by < ay+ah;
}
var ball = {
//A few of the basic variables called by the upcoming function
update: function() {
this.x += this.vel.x;
this.y += this.vel.y;
if (0 > this.y) {
var offset = 0 - this.y;
this.y += 2*offset;
this.vel.y *= -1;
}
if (this.y+this.height > HEIGHT) {
this.serve();
}
if (0 > this.x || this.x+this.size > WIDTH) {
var offset = this.vel.x < 0 ? 0 - this.x : WIDTH - (this.x+this.size);
this.x += 2*offset;
this.vel.x *= -1;
}
if (AABBIntersect(this.x, this.y, this.size, this.size, player.x, player.y, player.width, player.height)) {
var offset = player.y - (this.y+this.size);
this.y += 2*offset;
var n = (this.x+this.size - player.x)/(player.width+this.size);
var phi = 0.25*pi*(2*n - 1);
var smash = Math.abs(phi) > 0.2*pi ? 1.5 : 1;
this.vel.x = smash*this.speed*Math.sin(phi);
this.vel.y = smash*-1*this.speed*Math.cos(phi);
}
for (var i = 0; i < bricks.length; i++) {
var b = bricks[i];
if (AABBIntersect(this.x, this.y, this.width, this.height, b.x, b.y, b.width, b.height)) {
bricks.splice(i, 1);
i--;
bricks.length--;
continue;
}
}
}
}
var bricks = [];
function main() {
canvas = document.createElement("canvas");
canvas.width = WIDTH;
canvas.height = HEIGHT;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
keystate = {};
document.addEventListener("keydown", function(evt) {
keystate[evt.keyCode] = true;
});
document.addEventListener("keyup", function(evt) {
delete keystate[evt.keyCode];
} );
init();
var loop = function() {
update();
draw();
window.requestAnimationFrame(loop, canvas);
};
window.requestAnimationFrame(loop, canvas);
}
function init() {
var cols = WIDTH / 40;
player.x = (WIDTH - player.width) / 2;
player.y = HEIGHT - (player.height * 2);
ball.x = (WIDTH - ball.size) / 2;
ball.y = player.y - ball.size;
ball.width = ball.size;
ball.height = ball.size;
ball.serve();
for (var i = 0; i < 7; i++) {
for (var j = 0; j < cols; j++) {
bricks.push({
color: "#f00",
x: 2 + j*40,
y: 2 + i*20,
w: 36,
h: 16
});
}
}
}
function update() {
frames++;
player.update();
ball.update();
}
function draw() {
ctx.fillRect(0, 0, WIDTH, HEIGHT);
ctx.save();
ctx.fillStyle = "#fff";
player.draw();
ball.draw();
for (var i = 0; i < bricks.length; i++) {
ctx.fillStyle = bricks[i].color;
ctx.fillRect(bricks[i].x, bricks[i].y, bricks[i].w, bricks[i].h);
}
ctx.restore();
}
main();
A few issues:
The brick objects do not have width or height properties, but w and h;
The splice should not happen on a brick element (b), but on the array of bricks (bricks);
The length of bricks should not be decremented after the splice, as that operation already reduces the length.
So use this loop:
for (var i = 0; i < bricks.length; i++) {
var b = bricks[i];
if (AABBIntersect(this.x, this.y, this.width, this.height, b.x, b.y, b.w, b.h)) {
bricks.splice(i, 1);
i--;
}
}

Categories

Resources