We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Ok I did the Coding Challenge #10.1 - 10.4: Maze Generator with p5.js at , but now I want to move an object (pacman) through the maze. I have created the object(pacman) and it can move using the keyPressed function, but I want the object (pacman) to first check if there are walls blocking its movement. Something like if(!cell.walls(top) && keyCode === UP_ARROW) { move up. The issue I think i'm having is I do not understand how I can refer to the specific grid[] that my object is in and then have it check that specific grid for walls. My code so far is as follows:
var pacman;
var w = 40;
var cols, rows;
//width of each square is 40
var grid = [];
var current;
//the current cell being visited
var stack = [];
function setup() {
createCanvas(400, 400);
cols = floor(width / w);
rows = floor(height / w);
pacman = new Pacman(0, 0);
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 draw() {
background(0);
pacman.show();
pacman.borders();
for (var i = 0; i < grid.length; i++) {
grid[i].show();
}
current.visited = true;
var next = current.checkNeighbours();
if (next) {
next.visited = true;
stack.push(current);
removeWalls(current, next);
current = next;
} else if (stack.length > 0) {
current = stack.pop();
}
}
function keyPressed() {
if (keyCode === RIGHT_ARROW) {
pacman.moveh(1);
}
if (keyCode === LEFT_ARROW) {
pacman.moveh(-1);
}
if (keyCode === UP_ARROW) {
pacman.movev(-1);
}
if (keyCode === DOWN_ARROW) {
pacman.movev(1);
}
}
function Pacman(x, y) {
this.x = x + 20;
this.y = y + 20;
this.toDelete = false;
this.r = w;
this.top = false;
this.show = function() {
noStroke();
fill(255, 146, 0);
ellipseMode(CENTER);
ellipse(this.x, this.y, this.r, this.r);
}
this.moveh = function(dir) {
this.x += dir * w;
}
this.movev = function(dir) {
this.y += dir * w;
}
this.borders = function() {
if (this.x > width - 1) {
this.x = x + 20;
}
if (this.x < 0) {
this.x = width - 20;
}
if (this.y > height - 1) {
this.y = y + 20;
}
if (this.y < 0) {
this.y = height - 20;
}
}
}
function index(i, j) {
if (i < 0 || j < 0 || i > cols - 1 || j > rows - 1) {
return -1;
}
return i + j * cols;
}
function Cell(i, j) {
this.i = i;
this.j = j;
//i = column number
//j = row number
this.walls = [true, true, true, true];
//top, right, bottom, left
//if true you see that side of the wall of each cell, if false you do not see the wall
this.visited = false;
this.checkNeighbours = function() {
var neighbours = [];
` //top = walls[0]`
var top = grid[index(i, j - 1)];
var right = grid[index(i + 1, j)];
var bottom = grid[index(i, j + 1)];
var left = grid[index(i - 1, j)];
if (top && !top.visited) {
neighbours.push(top);
}
if (right && !right.visited) {
neighbours.push(right);
}
if (bottom && !bottom.visited) {
neighbours.push(bottom);
}
if (left && !left.visited) {
neighbours.push(left);
}
if (neighbours.length > 0) {
var r = floor(random(0, neighbours.length));
return neighbours[r];
} else {
return undefined;
}
}
this.show = function() {
var x = this.i * w;
var y = this.j * w;
stroke(255);
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);
}
}
}
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;
}
}
Answers
this is doing it, line 124.
that's using i and j-1, calculating the index into the grid for that square and returning the value of the grid at that point.
yes, but I don't know how to reference or to say:
The walls object within the grid says whether there's a wall in the given direction.
See line 156 etc
Yes, just like this, where cell is the grid item that you've looked up using the index.
Lines 115 and 116 are relevant here, you'll need to know which element of the array is which direction.
gives me this error
Uncaught TypeError: object is not a function
referring to the line:
if(!cell.walls(top) && keyCode === UP_ARROW)
That's because the object is not a function, it's an array. Which is where line 116 comes into it...
()
, it means we're using it as a function.this.walls = [true, true, true, true];
[]
instead of()
in order to access an indexed element from walls!Ok cool I get that... I think hah. so I've changed my line to:
if(!cell.walls[top] && keyCode === UP_ARROW)
I receive no error, but now I am unable to move up at all.
Three =
Use two
Still doesn't move at all.
What is 'top'?
Line 156...
top is the first object of the array walls, walls[0] walls [true, true, true, true] = walls [top, right, bottom, left]
Is top defined in your code? What value does it have?
My point being that
Isn't defined if top isn't defined. And if top isn't 0 then it'll return the wrong thing.
The rest of the code uses
directly. It's not great from a clarity point of view but you can always add a comment.
Define some kinda enumerable object at the top of the sketch:
Now, instead of
cell.walls[0]
, re-write it ascell.walls[Wall.TOP]
.For
cell.walls[3]
, go w/cell.walls[Wall.LEFT]
, and so on for the rest of the index constants. *-:)I did what you suggested
But I this line still has no affect:
Accordingly to your 1st posted sketch, cell is a setup()'s local variable.
It doesn't exist anywhere else within your sketch! @-)
Perhaps you've meant grid[] instead? :-??
you are correct, if I use
I get an error "Uncaught TypeError: Cannot read property '0' of undefined"
If I use
or run a loop and do grid[i], then I cannot move up.
You mean you cannot move up even though it shoulda been allowed? :-/
Yes sorry, that is what I meant. Perhaps, not that it shoulda been allowed, but I don't know where the error is that is not allowing it
Problem is you've carried on coding the original based sketch w/o checking out whether it was still working correctly. It'd help a lil' if you posted the code you're basing yours from. 8->
why === instead of ==
?
@Chrisir, why don't you look up JS' reference for it? It's such a treasure trove! ;;)
==
-> https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality_()===
-> https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity_strict_equality_()grid[] holds the entire grid, cell is a local variable (type Cell) holding the grid element at (x, y)
jan 19th
two steps:
i) look up the grid element according to the position
ii) check the walls for this grid element