Итак, я пытаюсь сделать игру Tetris, но когда я открываю ее в своем браузере, я получаю Uncaught TypeError: Cannot read property 'length' of undefined. Tetris.html:245
в консоли JavaScript. Затем я пойду и посмотрю на него, и он выглядит правильно, поэтому я разместил его на Stackoverflow, потому что не могу понять, что случилось. Строка 245 находится в функции checkMove(xpos, ypos, newState)
, это код для этой строки. for (var r = 0, len = curPiece.states[newState].length; r < len; r++) {//code goes here}
Вот весь HTML/Uncaught TypeError: Невозможно прочитать свойство 'length' undefined [JavaScript]
<!DOCTYPE HTML>
<HTML lang="en">
\t <head>
\t \t <meta charset="UTF-8">
\t \t <meta name="description" content="null">
\t \t <meta name="author" content="null">
\t \t <meta name="title" content="Tetris Clone">
\t \t <title title="Tetris - HTML5">
\t \t \t Tetris - HTML5
\t \t </title>
\t \t <link rel="apple-touch-icon" href="null">
\t \t <link rel="shortcut icon" href="null">
\t \t <link rel="stylesheet" type="text/css" href="css/tetris.css">
\t \t <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.js"></script>
\t \t <script type="text/javascript" src="http://gigaboywebdesigns.com/ClassStyles.js"></script>
\t \t <script type="text/javascript" src="js/style.js"></script>
\t </head>
\t <body class = "body">
\t \t <center>
\t \t \t <div id = "gameboard">
\t \t \t \t <canvas id = "gameCanvas" class = "gameCanvas" width = "320" height = "640"></canvas>
\t \t \t </div>
\t \t \t
\t \t \t <div id = "score" class = "score">
\t \t \t \t <p>Lines: <span id = "lines" class = "lines"></span></p>
\t \t \t </div>
\t \t </center>
\t \t
\t \t <script type = "text/javascript" src = "js/pieces.js"></script>
\t \t <script type = "text/javascript" src = "js/BulkImageLoader.js"></script>
\t \t
\t \t <script type = "text/javascript">
\t \t \t var ROWS = 20;
\t \t \t var COLS = 10;
\t \t \t var SIZE = 32;
\t \t \t
\t \t \t var canvas
\t \t \t var ctx;
\t \t \t var blockImg;
\t \t \t var bgImg;
\t \t \t var gameOverImg;
\t \t \t var curPiece;
\t \t \t var gameData;
\t \t \t var imgLoader;
\t \t \t var prevTime;
\t \t \t var curTime;
\t \t \t var isGameOver;
\t \t \t var lineSpan;
\t \t \t var curLines;
\t \t \t
\t \t \t window.onload = onReady;
\t \t \t
\t \t \t function onReady() {
\t \t \t \t imgLoader = new BulkImageLoader();
\t \t \t \t imgLoader.addImage("blocks.png", "blocks");
\t \t \t \t imgLoader.addImage("bg.png", "bg");
\t \t \t \t imgLoader.addImage("over.png", "gameover");
\t \t \t \t imgLoader.onReadyCallback = onImagesLoaded;
\t \t \t \t imgLoader.loadImages();
\t \t \t \t
\t \t \t \t canvas = document.getElementById("gameCanvas");
\t \t \t \t ctx = canvas.getContext("2d");
\t \t \t \t lineSpan = document.getElementById("lines");
\t \t \t \t
\t \t \t \t prevTime = curTime = 0;
\t \t \t \t
\t \t \t \t document.onkeydown = getInput;
\t \t \t }
\t \t \t
\t \t \t function getInput(e) {
\t \t \t \t
\t \t \t }
\t \t \t
\t \t \t function onImagesLoaded(e) {
\t \t \t \t blockImg = imgLoader.getImageAtIndex(0);
\t \t \t \t bgImg = imgLoader.getImageAtIndex(1);
\t \t \t \t gameOverImg = imgLoader.getImageAtIndex(2);
\t \t \t \t initGame();
\t \t \t }
\t \t \t
\t \t \t function initGame() {
\t \t \t \t var r, c;
\t \t \t \t curLines = 0;
\t \t \t \t isGameOver = false;
\t \t \t \t
\t \t \t \t if (gameData == undefined) {
\t \t \t \t \t gameData = new Array();
\t \t \t \t \t
\t \t \t \t \t for (r = 0; r < ROWS; r++) {
\t \t \t \t \t \t gameData[r] = new Array();
\t \t \t \t \t \t
\t \t \t \t \t \t for (c = 0; c < COLS; c++) {
\t \t \t \t \t \t \t gameData[r].push(0);
\t \t \t \t \t \t }
\t \t \t \t \t }
\t \t \t \t } else {
\t \t \t \t \t for (r = 0; r < ROWS; r++) {
\t \t \t \t \t \t for (c = 0; c < COLS; c++) {
\t \t \t \t \t \t \t gameData[r][c] = 0;
\t \t \t \t \t \t }
\t \t \t \t \t }
\t \t \t \t }
\t \t \t \t
\t \t \t \t curPiece = getRandomPiece();
\t \t \t \t lineSpan.innerHTML = curLines.toString();
\t \t \t \t
\t \t \t \t var requestAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
\t \t \t \t
\t \t \t \t window.requestAnimationFrame = requestAnimFrame;
\t \t \t \t
\t \t \t \t requestAnimationFrame(update);
\t \t \t }
\t \t \t
\t \t \t function update() {
\t \t \t \t curTime = new Date().getTime();
\t \t \t \t
\t \t \t \t if (curTime - prevTime > 500) {
\t \t \t \t \t if (checkMove(curPiece.gridx, curPiece.gridy + 1, curPiece.curState)) {
\t \t \t \t \t \t curPiece.gridy += 1;
\t \t \t \t \t } else {
\t \t \t \t \t \t copyData(curPiece);
\t \t \t \t \t \t curPiece = getRandomPiece();
\t \t \t \t \t }
\t \t \t \t \t
\t \t \t \t \t prevTime = curTime;
\t \t \t \t }
\t \t \t \t
\t \t \t \t ctx.clearRect(0, 0, 320, 640);
\t \t \t \t drawBoard();
\t \t \t \t drawPiece(curPiece);
\t \t \t \t
\t \t \t \t if (isGameOver == false) {
\t \t \t \t \t requestAnimationFrame(update);
\t \t \t \t } else {
\t \t \t \t \t ctx.drawImage(gameOverImg, 0, 0, 320, 640, 0, 0, 320, 640);
\t \t \t \t }
\t \t \t }
\t \t \t
\t \t \t function copyData(p) {
\t \t \t \t var xpos = p.gridx;
\t \t \t \t var ypos = p.gridy;
\t \t \t \t var state = p.curState;
\t \t \t \t
\t \t \t \t for (var r = 0, len = p.states[state].length; r < len; r++) {
\t \t \t \t \t for (var c = 0, len2 = p.states[state][r].length; c < len2; c++) {
\t \t \t \t \t \t if (p.states[state][r][c] == 1 && ypos >= 0) {
\t \t \t \t \t \t \t gameData[ypos][xpos] = (p.color + 1);
\t \t \t \t \t \t }
\t \t \t \t \t \t
\t \t \t \t \t \t xpos += 1;
\t \t \t \t \t }
\t \t \t \t \t
\t \t \t \t \t xpos = p.gridx;
\t \t \t \t \t ypos += 1;
\t \t \t \t }
\t \t \t \t
\t \t \t \t checkLines();
\t \t \t \t
\t \t \t \t if (p.gridy < 0) {
\t \t \t \t \t isGameOver == true;
\t \t \t \t }
\t \t \t }
\t \t \t
\t \t \t function checkLines() {
\t \t \t \t var lineFound = false;
\t \t \t \t var fullRow = true;
\t \t \t \t var r = ROWS - 1;
\t \t \t \t var c = COLS -1;
\t \t \t \t
\t \t \t \t while(r >= 0) {
\t \t \t \t \t while(c >= 0) {
\t \t \t \t \t \t if (gameData[r][c] == 0) {
\t \t \t \t \t \t \t fullRow = false;
\t \t \t \t \t \t \t c = -1;
\t \t \t \t \t \t }
\t \t \t \t \t \t c--;
\t \t \t \t \t }
\t \t \t \t \t
\t \t \t \t \t if (fullRow == true) {
\t \t \t \t \t \t zeroRow(r);
\t \t \t \t \t \t r++;
\t \t \t \t \t \t lineFound = true;
\t \t \t \t \t \t curLines++;
\t \t \t \t \t }
\t \t \t \t \t
\t \t \t \t \t fullRow = true;
\t \t \t \t \t c = COLS - 1;
\t \t \t \t \t r--;
\t \t \t \t }
\t \t \t }
\t \t \t
\t \t \t function zeroRow(row) {
\t \t \t \t var r = row;
\t \t \t \t var c = 0;
\t \t \t \t
\t \t \t \t while (r >= 0) {
\t \t \t \t \t while (c < COLS) {
\t \t \t \t \t \t if (r > 0) {
\t \t \t \t \t \t \t gameData[r][c] = gameData[r-1][c];
\t \t \t \t \t \t } else {
\t \t \t \t \t \t \t gameData[r][c] = 0;
\t \t \t \t \t \t }
\t \t \t \t \t \t c++;
\t \t \t \t \t }
\t \t \t \t \t
\t \t \t \t \t c = 0;
\t \t \t \t \t r--;
\t \t \t \t }
\t \t \t }
\t \t \t
\t \t \t function drawBoard() {
\t \t \t \t ctx.drawImage(bgImg, 0, 0, 320, 640);
\t \t \t \t
\t \t \t \t for (var r = 0; r < ROWS; r++) {
\t \t \t \t \t for (var c = 0; c < COLS; c++) {
\t \t \t \t \t \t ctx.drawImage(blockImg, (gameData[r][c] - 1) * SIZE, 0, SIZE, SIZE, c * SIZE, r * SIZE, SIZE);
\t \t \t \t \t }
\t \t \t \t }
\t \t \t }
\t \t \t
\t \t \t function drawPiece(p) {
\t \t \t \t var drawX = p.gridx;
\t \t \t \t var drawY = p.gridy;
\t \t \t \t var state = p.curState;
\t \t \t \t
\t \t \t \t for (var r = 0, len = p.states[state].length; r < len; r++) {
\t \t \t \t \t for (var c = 0, len2 = p.states[state][r].length; c < len2; c++) {
\t \t \t \t \t \t if (p.states[state][r][c] == 1 && drawY >= 0) {
\t \t \t \t \t \t \t ctx.drawImage(blockImg, p.color * SIZE, 0, SIZE, SIZE, drawX * SIZE, drawY * SIZE, SIZE, SIZE);
\t \t \t \t \t \t }
\t \t \t \t \t \t
\t \t \t \t \t \t drawX += 1;
\t \t \t \t \t }
\t \t \t \t \t
\t \t \t \t \t drawX = p.gridx;
\t \t \t \t \t drawY += 1;
\t \t \t \t }
\t \t \t }
\t \t \t
\t \t \t function checkMove(xpos, ypos, newState) {
\t \t \t \t var result = true;
\t \t \t \t var newx = xpos;
\t \t \t \t var newy = ypos;
\t \t \t \t
\t \t \t \t for (var r = 0, len = curPiece.states[newState].length; r < len; r++) {
\t \t \t \t \t for (var c = 0, len2 = curPiece.states[newState][r].length; c < len2; c++) {
\t \t \t \t \t \t if (newx < 0 || newx >= COLS) {
\t \t \t \t \t \t \t result = false;
\t \t \t \t \t \t \t c = len2
\t \t \t \t \t \t \t r = len;
\t \t \t \t \t \t }
\t \t \t \t \t \t
\t \t \t \t \t \t if (gameData[newy] != undefined && gameData[newy][newx] != 0 && curPiece.states[newState][r] != undefined && curPiece.states[newState[r][c]] != 0) {
\t \t \t \t \t \t \t result = false;
\t \t \t \t \t \t \t c = len2;
\t \t \t \t \t \t \t r = len;
\t \t \t \t \t \t }
\t \t \t \t \t \t
\t \t \t \t \t \t newx += 1;
\t \t \t \t \t }
\t \t \t \t \t
\t \t \t \t \t newx = xpos;
\t \t \t \t \t newy += 1;
\t \t \t \t \t
\t \t \t \t \t if (newy > ROWS) {
\t \t \t \t \t \t r = len;
\t \t \t \t \t \t result = false;
\t \t \t \t \t }
\t \t \t \t }
\t \t \t \t
\t \t \t \t return result;
\t \t \t }
\t \t </script>
\t </body>
</HTML>
JS файл, если вам это нужно.
Вопрос слишком длинный, и отсутствует код 'pieces.js', который сделает его более длинным. Какую отладку вы пытались сделать? консольное ведение журналов 'typeof' и их значения часто являются хорошим способом запуска. – traktor53
Прошли ли вы? – Macainian