0

So I'm trying to make a Tetris game but when I open it in my browser I get Uncaught TypeError: Cannot read property 'length' of undefined. Tetris.html:245 in the JavaScript console. Then I go and take a look at it and it looks right so I posted it on Stackoverflow because I can't figure out what's wrong. Line 245 is in the checkMove(xpos, ypos, newState) function this is what the code for that line is. for (var r = 0, len = curPiece.states[newState].length; r < len; r++) {//code goes here} Here's the whole HTML/

<!DOCTYPE HTML>
<HTML lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="description" content="null">
		<meta name="author" content="null">
		<meta name="title" content="Tetris Clone">
		<title title="Tetris - HTML5">
			Tetris - HTML5
		</title>
		<link rel="apple-touch-icon" href="null">
		<link rel="shortcut icon" href="null">
		<link rel="stylesheet" type="text/css" href="css/tetris.css">
		<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.js"></script>
		<script type="text/javascript" src="http://gigaboywebdesigns.com/ClassStyles.js"></script>
		<script type="text/javascript" src="js/style.js"></script>
	</head>
	<body class = "body">
		<center>
			<div id = "gameboard">
				<canvas id = "gameCanvas" class = "gameCanvas" width = "320" height = "640"></canvas>
			</div>
			
			<div id = "score" class = "score">
				<p>Lines: <span id = "lines" class = "lines"></span></p>
			</div>
		</center>
		
		<script type = "text/javascript" src = "js/pieces.js"></script>
		<script type = "text/javascript" src = "js/BulkImageLoader.js"></script>
		
		<script type = "text/javascript">
			var ROWS = 20;
			var COLS = 10;
			var SIZE = 32;
			
			var canvas
			var ctx;
			var blockImg;
			var bgImg;
			var gameOverImg;
			var curPiece;
			var gameData;
			var imgLoader;
			var prevTime;
			var curTime;
			var isGameOver;
			var lineSpan;
			var curLines;
			
			window.onload = onReady;
			
			function onReady() {
				imgLoader = new BulkImageLoader();
				imgLoader.addImage("blocks.png", "blocks");
				imgLoader.addImage("bg.png", "bg");
				imgLoader.addImage("over.png", "gameover");
				imgLoader.onReadyCallback = onImagesLoaded;
				imgLoader.loadImages();
				
				canvas = document.getElementById("gameCanvas");
				ctx = canvas.getContext("2d");
				lineSpan = document.getElementById("lines");
				
				prevTime = curTime = 0;
				
				document.onkeydown = getInput;
			}
			
			function getInput(e) {
				
			}
			
			function onImagesLoaded(e) {
				blockImg = imgLoader.getImageAtIndex(0);
				bgImg = imgLoader.getImageAtIndex(1);
				gameOverImg = imgLoader.getImageAtIndex(2);
				initGame();
			}
			
			function initGame() {
				var r, c;
				curLines = 0;
				isGameOver = false;
				
				if (gameData == undefined) {
					gameData = new Array();
					
					for (r = 0; r < ROWS; r++) {
						gameData[r] = new Array();
						
						for (c = 0; c < COLS; c++) {
							gameData[r].push(0);
						}
					}
				} else {
					for (r = 0; r < ROWS; r++) {
						for (c = 0; c < COLS; c++) {
							gameData[r][c] = 0;
						}
					}
				}
				
				curPiece = getRandomPiece();
				lineSpan.innerHTML = curLines.toString();
				
				var requestAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
				
				window.requestAnimationFrame = requestAnimFrame;
				
				requestAnimationFrame(update);
			}
			
			function update() {
				curTime = new Date().getTime();
				
				if (curTime - prevTime > 500) {
					if (checkMove(curPiece.gridx, curPiece.gridy + 1, curPiece.curState)) {
						curPiece.gridy += 1;
					} else {
						copyData(curPiece);
						curPiece = getRandomPiece();
					}
					
					prevTime = curTime;
				}
				
				ctx.clearRect(0, 0, 320, 640);
				drawBoard();
				drawPiece(curPiece);
				
				if (isGameOver == false) {
					requestAnimationFrame(update);
				} else {
					ctx.drawImage(gameOverImg, 0, 0, 320, 640, 0, 0, 320, 640);
				}
			}
			
			function copyData(p) {
				var xpos = p.gridx;
				var ypos = p.gridy;
				var state = p.curState;
				
				for (var r = 0, len = p.states[state].length; r < len; r++) {
					for (var c = 0, len2 = p.states[state][r].length; c < len2; c++) {
						if (p.states[state][r][c] == 1 && ypos >= 0) {
							gameData[ypos][xpos] = (p.color + 1);
						}
						
						xpos += 1;
					}
					
					xpos = p.gridx;
					ypos += 1;
				}
				
				checkLines();
				
				if (p.gridy < 0) {
					isGameOver == true;
				}
			}
			
			function checkLines() {
				var lineFound = false;
				var fullRow = true;
				var r = ROWS - 1;
				var c = COLS -1;
				
				while(r >= 0) {
					while(c >= 0) {
						if (gameData[r][c] == 0) {
							fullRow = false;
							c = -1;
						}
						c--;
					}
					
					if (fullRow == true) {
						zeroRow(r);
						r++;
						lineFound = true;
						curLines++;
					}
					
					fullRow = true;
					c = COLS - 1;
					r--;
				}
			}
			
			function zeroRow(row) {
				var r = row;
				var c = 0;
				
				while (r >= 0) {
					while (c < COLS) {
						if (r > 0) {
							gameData[r][c] = gameData[r-1][c];
						} else {
							gameData[r][c] = 0;
						}
						c++;
					}
					
					c = 0;
					r--;
				}
			}
			
			function drawBoard() {
				ctx.drawImage(bgImg, 0, 0, 320, 640);
				
				for (var r = 0; r < ROWS; r++) {
					for (var c = 0; c < COLS; c++) {
						ctx.drawImage(blockImg, (gameData[r][c] - 1) * SIZE, 0, SIZE, SIZE, c * SIZE, r * SIZE, SIZE);
					}
				}
			}
			
			function drawPiece(p) {
				var drawX = p.gridx;
				var drawY = p.gridy;
				var state = p.curState;
				
				for (var r = 0, len = p.states[state].length; r < len; r++) {
					for (var c = 0, len2 = p.states[state][r].length; c < len2; c++) {
						if (p.states[state][r][c] == 1 && drawY >= 0) {
							ctx.drawImage(blockImg, p.color * SIZE, 0, SIZE, SIZE, drawX * SIZE, drawY * SIZE, SIZE, SIZE);
						}
						
						drawX += 1;
					}
					
					drawX = p.gridx;
					drawY += 1;
				}
			}
			
			function checkMove(xpos, ypos, newState) {
				var result = true;
				var newx = xpos;
				var newy = ypos;
				
				for (var r = 0, len = curPiece.states[newState].length; r < len; r++) {
					for (var c = 0, len2 = curPiece.states[newState][r].length; c < len2; c++) {
						if (newx < 0 || newx >= COLS) {
							result = false;
							c = len2
							r = len;
						}
						
						if (gameData[newy] != undefined && gameData[newy][newx] != 0 && curPiece.states[newState][r] != undefined && curPiece.states[newState[r][c]] != 0) {
							result = false;
							c = len2;
							r = len;
						}
						
						newx += 1;
					}
					
					newx = xpos;
					newy += 1;
					
					if (newy > ROWS) {
						r = len;
						result = false;
					}
				}
				
				return result;
			}
		</script>
	</body>
</HTML>

JS file if you need it.

2
  • The question is too long, and lacks pieces.js code which would make it longer. What debugging have you attempted? console logging of the typeof arguments and their values is often a good way to start. Commented Feb 24, 2016 at 23:02
  • Did you make any progress? Commented Feb 26, 2016 at 3:46

1 Answer 1

1

Well in short, curPiece.states[newState] is undefined. The code you put there is a lot to look through, but you should answer the question as to why that is undefined. It could be that newState is not correct, or it could be that states is undefined altogether. Perhaps the order of operations is wrong and it hasn't been created yet.

Do some debugging on what the value of curPiece.states is right before that for loop. Also check what newState is. Then report back with an update so people can help you further if needed.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.