我正在编写/遵循蛇形游戏编码教程,似乎已经找到了一个我发现教师没有遇到过的错误,我似乎不明白问题的根源。
我甚至评论了每一行描述每行的功能,可能会帮助我找出问题,但我已经空白了。
明确指出了问题的界限。
Chrome控制台完全错误:
未捕获的TypeError:无法读取属性' x'未定义的 --at Snake.show(蛇:95)
- 画画(蛇:37)
--at p5.redraw(p5.js:17153)
--at p5。 (p5.js:12358)
具体问题线:
rect(this.tail [i] .x,this.tail [i] .y,scl,scl); //在最后绘制尾巴。
当我遇到边界墙或者向相反的方向撞到自己时,我最初进入的尾巴长度为3+,我得到了这个错误。 有人可以解释什么导致此错误?它必须与死亡方面有关。
完整代码:
<!DOCTYPE html>
<html>
<head>
<title>Snake Game</title>
<script src="http://sethjfreeman.com/resources/jquery-3.1.1.js"></script>
<script src="http://sethjfreeman.com/resources/P5/p5.js"></script>
<link href="http://sethjfreeman.com/projects/snake.css" rel="stylesheet" type="text/css">
</head>
<body>
<script> <!-- Uses p5.js Javascript Library -->
var s; // Snake Character.
var scl = 20; // Size Of Everything.
var food; // Food Items. Makes Em Grow When Eatin.
function setup() {
createCanvas($(window).width() - 10, $(window).height() - 10); // Creates De Canvas For Everything To Be In.
s = new Snake(); // Creates A New Snake | Calls Snake Function To Create A Snake |.
frameRate(10); // Sloooowwwssss Down The Game To Actully Be Able To Control The Snake.
pickLocation(); // Calls Pick Location To Pick A Location For The First Food Item To Be Placed.
}
function pickLocation() { // A Function To Control Where The Food Goes
var cols = floor(width / scl); // Creates An Imaginary Vertical Grid Every 20 Pixels. Floor Is Being Used To Prevent A Column From Being Placed At E.G: 40.6 Pixels.
var rows = floor(height / scl); // Creates An Imaginary Horizontal Gird Every 20 Pixels. Floor Is Being Used To Prevent A Column From Being Placed At E.G: 40.6 Pixels.
food = createVector(floor(random(cols)), floor(random(rows))); // Assigns Food To Being At The Random Location.
food.mult(scl); // Makes Sure The Food Vector Is Set In The 20 Pixels Guide Lines. Not The 20.5 Pixel Guide Lines.
}
function draw() { // Controls Everything That Is Being Drawn To The Canvas.
background(51); // Sets Background To Be A Grayscale Value.
if(s.eat(food)) { // Checks If Food Was Eatin, If True Picks A New Location For A Food Peice.
pickLocation(); // Calls Pick Locatoin Function.
}
s.death(); // Calls Death Function.
s.update(); // Calls Update Function.
s.show(); // Calls Show Function.
fill(255, 0, 100); // Sets Food's Background Color.
rect(food.x, food.y, scl, scl); // Creates A New Food Item.
}
function Snake() { // Controls Everything To Do With De Snake Character.
this.x = 0; // Holds The X Pos Of Player.
this.y = 0; // Holds The Y Pos Of The Player.
this.xspeed = 1; // Moves Player (X) Speed.
this.yspeed = 0; // Moves Player (X) Speed.
this.total = 0; // Holds The Amount Of Squares On Snake.
this.tail = []; // History For Where Each Part Of The Body Needs To Go.
this.dir = function(x, y) { // Controls The Direction Of The Snake.
this.xspeed = x; // Recives The Intput From keyPressed.
this.yspeed = y; // Recives The Intput From keyPressed.
}
this.eat = function(pos) { // Controls What Happens When A Food Item Was Eatin.
var d = dist(this.x, this.y, pos.x, pos.y); // Holds The Distance Between Two Points, In This Case, Between The Snake & The Food Item.
if(d < 1) { // If The Distance Is Less Than 1 Pixel From Food Item Add 1 To Total.
this.total++;
return true;
} else { // Else Go To Sleep.
return false;
}
}
this.death = function() { // Controls When The Player Dies.
for(var i = 0; i < this.tail.length; i++) { // Loops Through Snake Length. Loop Used For Checking If Snake Runs Into Self.
var pos = this.tail[i]; // Checks Position Of Each Square Of Tail
var d = dist(this.x, this.y, pos.x, pos.y); // Holds The Distance Between Two Points, In This Case, Between The Snake Head & The Particular Spot On The Tail Thats Being Hit.
if(d < 1) { // If The Pixel Between The Distance, Restart The Player.
total = 0; // Resets Total.
this.tail = []; // Resets Tail.
}
}
}
this.update = function() { // Updates Everything. Simple Right?
if(this.total === this.tail.length) {
for(var i = 0; i < this.tail.length - 1; i++) { // Loops Through Whole Snake Besides Head.
this.tail[i] = this.tail[i + 1]; // Shifts Each Body Square Location By 1.
}
}
this.tail[this.total - 1] = createVector(this.x, this.y);
this.x = this.x + this.xspeed * scl; // The X Cords Of Snake Changes Depending On X Speed * The Scale Of The Snake
this.y = this.y + this.yspeed * scl; // The Y Cords Of Snake Changes Depending On Y Speed * The Scale Of The Snake
this.x = constrain(this.x, 0, width - scl); // Constrains The Snake Between The Left Border And Right Border Of The Sceen
this.y = constrain(this.y, 0, height - scl); // Constrains The Snake Between The Top Border And Bottom Border Of The Sceen
}
/*
_____ _____ ____ ____ _ ______ __ __
| __ \| __ \ / __ \| _ \| | | ____| \/ |
| |__) | |__) | | | | |_) | | | |__ | \ / |
| ___/| _ /| | | | _ <| | | __| | |\/| |
| | | | \ \| |__| | |_) | |____| |____| | | |
|_| |_| \_\\____/|____/|______|______|_| |_|
*/
this.show = function() {
fill(255); // Draw The Tail White.
for(var i = 0; i < this.tail.length; i++) { // Draw The Tail.
rect(this.tail[i].x, this.tail[i].y, scl, scl); // Draw The Tail At The End.
}
rect(this.x, this.y, scl, scl);
}
}
function keyPressed() { // Checks Which Keys Were Pressed.
if(keyCode === UP_ARROW) { // If Up Arrow Was Pressed Move Snake Upwards.
s.dir(0, -1); // Because Direction Starts From Left & Top, -1 = Subtract From Top Pos. +1 = Add From Top Pos.
} else if(keyCode === DOWN_ARROW) { // If Down Arrow Was Pressed Move Snake Downwards.
s.dir(0, 1); // Because Direction Starts From Left & Top, -1 = Subtract From Top Pos. +1 = Add From Top Pos.
} else if(keyCode === RIGHT_ARROW) { // If Right Arrow Was Pressed Move Snake Right.
s.dir(1, 0); // Because Direction Starts From Left & Top, -1 = Subtract From Top Left. +1 = Add From Top Left.
} else if(keyCode === LEFT_ARROW) { // If Left Arrow Was Pressed Move Snake Left.
s.dir(-1, 0); // Because Direction Starts From Left & Top, -1 = Subtract From Top Left. +1 = Add From Top Left.
}
}
</script>
</body>
</html>
答案 0 :(得分:1)
您将需要debug您的计划。 (该教程适用于Processing,但基本思路是相同的。)
你知道你的问题就在这一行:
rect(this.tail[i].x, this.tail[i].y, scl, scl);
而且您知道您的错误是:Uncaught TypeError: Cannot read property 'x' of undefined
这告诉您this.tail[i]
未定义。这通常意味着您正在尝试访问this.tail
数组没有的索引(比如尝试访问仅包含10个项目的数组的索引100)。
但是只看你的代码,你只是循环到this.tail.length
,所以它不是那么简单。所以现在你必须调试你的代码才能找到一些东西:
this.tail.length
的价值是什么?i
的价值是什么?this.tail
索引的内容是什么?然后你将不得不进一步调试以确切地知道你何时改变this.tail
。您是否尝试使用调试器逐步执行代码,或者至少使用一张纸和一支铅笔进行描述?
您需要完成该过程,直到您完全了解正在发生的事情为止。如果您可以将其缩小到只有几行不符合预期的行,那么请发布MCVE我们将从那里开始。祝你好运。