Reputation: 229
I am currently trying to build a snake game from a tutorial in JavaScript and Canvas. Currently I am a receiving an error on this line: grid.set(FOOD, randPos.x, randPos.y);
which is part of the setFood
function towards the bottom. I dont understand where the .x
is coming from because I dont see a X or Y defined within that scope. Would really appreciate it if someone could point me in the right direction so I can finish my first game!!! Thanks.
<script>
//CONSTANTS
var COLS=26;
var ROWS=26;
//ID's
var EMPTY=0;
var SNAKE=1;
var FOOD=2;
//Direction
var LEFT=0;
var UP=1;
var RIGHT=2;
var DOWN=3;
var grid = {
width: null,
height: null,
_grid: null,
init: function(d,c,r){
this.width = c;
this.height = r;
this._grid = [];
for(var x=0; x<c; x++){
this._grid.push([]);
for(var y=0; y < r; y++){
this._grid[x].push(d);
}
}
},
set: function(val,x,y){
this._grid[x][y] = val;
},
get: function(x,y){
this._grid[x][y];
}
}
var snake = {
direction: null,
last: null,
_queue: null,
init: function(d,x,y){
this.direction = d;
this._queue = [];
this.insert(x,y);
},
insert: function(x,y){
this._queue.unshift({x:x, y:y});
this.last = this._queue[0];
},
remove: function(){
return this._queue.pop();
}
}
function setFood(){
var empty = [];
for(var x=0; x<grid.width; x++){
for(var y=0; y<grid.height; y++){
if(grid.get(x,y)===EMPTY){
empty.push({x:x, y:y});
}
}
}
var randPos = empty[Math.floor(Math.random()*empty.length)];
console.log("working");
grid.set(FOOD, randPos.x, randPos.y);
console.log("working???")
}
//Game objects
var canvas, ctx, keystate, frames;
function main(){
canvas = document.createElement('canvas');
canvas.width = COLS*20;
canvas.height = ROWS*20;
ctx = canvas.getContext('2D');
document.body.appendChild(canvas);
frames = 0;
keystate = {};
init();
loop();
}
function init(){
grid.init(EMPTY, COLS, ROWS);
var sp = {x:Math.floor(COLS/2), y:ROWS-1};
snake.init(UP, sp.x, sp.y);
grid.set(SNAKE, sp.x, sp.y);
setFood();
}
function loop(){
update();
draw();
window.requestAnimationFrame(loop, canvas);
}
function update(){
frames++;
}
function draw(){
var tw = canvas.width/grid.width;
var th = canvas.height/grid.height;
for(var x=0; x<grid.width; x++){
for(var y=0; y<grid.height; y++){
switch(grid.get(x,y)){
case EMPTY:
ctx.fillStyle = "#fff";
break;
case SNAKE:
ctx.fillStyle = "#0ff";
break;
case FOOD:
ctx.fillStyle = "#f00";
break;
}
ctx.fillRect(x*tw, y*th, tw, th);
}
}
}
main();
</script>
Upvotes: 0
Views: 529
Reputation: 1725
New answer. Check out your function
get: function(x,y){
this._grid[x][y];
}
and compare it with the one in the video you linked
get: function(x,y){
return this._grid[x][y];
}
You need to add the return part, otherwise the function will return undefined
and the array called empty
won't get any content so your random number generator will suggest you use empty[0], which is undefined
.
Last answer was replacing randPos.x with randPos["x"] but as informed by bbill in the comments below, that's not it.
Upvotes: 0
Reputation: 5723
Take a look at the setFood
function. Few lines above the line where You get the error, there is a loop that fills the empty
collection with objects containing both x
and y
fields. One of those objects is than assigned to randPos
variable.
The error is caused probably by invalid assignment of the value to randPos
variable. It's undefined, so it does not contain required x
field.
UPDATE
It seems that You just missed the return
keyword in Your grid.get(x,y)
function, so it should look like this:
get: function(x,y){
return this._grid[x][y];
}
Please verify if adding it solves Your issue.
Upvotes: 2
Reputation: 2304
Let me help you debug:
grid.set(FOOD, randPos.x, randPos.y);
is giving you an error saying you're trying to get the x property from something that's undefined.
Okay, so randPos
is undefined.
randPos
comes from empty[Math.floor(Math.random()*empty.length)];
.
empty
is an array created inside a nested for loop: empty.push({x:x, y:y});
. Do you see where x
is coming from?
As Lukasz points out, there's only a specific case where an array dereference like that is undefined. What if you try doing something like
var a = [];
console.log(a[0]);
?
And the reason empty
is empty? No grid cell === EMPTY
.
get: function(x,y){
this._grid[x][y];
}
Because of a missing return
.
Upvotes: 1