Skip to main content
Participating Frequently
December 8, 2023
Question

help!! tetris game in action script 3 didn't work

  • December 8, 2023
  • 2 replies
  • 233 views
// Import necessary classes for the Tetris game.
package {
	import flash.display.Sprite;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	import flash.events.KeyboardEvent;

	// The main class for the Tetris game, extends Sprite.
	public class Main extends Sprite {

		// Constant representing the size of a single tile (in pixels).
		private const TS: uint = 20;

		// Array to numerically represent the game field.
		private var fieldArray: Array;

		// DisplayObject to graphically render the game field.
		private var fieldSprite: Sprite;

		// Arrays to store different types of tetrominoes and their colors.
		private var tetrominoes: Array = new Array();
		private var colors: Array = new Array();

		// Sprite to represent the current tetromino.
		private var tetromino: Sprite;

		// Variables to store the current and next tetromino types, current rotation,
		// and the current position of the tetromino on the game field.
		private var currentTetromino: uint;
		private var nextTetromino: uint;
		private var currentRotation: uint;
		private var tRow: int;
		private var tCol: int;

		// Timer to control the falling speed of tetrominoes.
		private var timeCount: Timer = new Timer(2000);

		// Constructor function for the Main class.
		public function Main() {
			// Call functions to initialize the game.
			generateField();
			initTetrominoes();
			nextTetromino = Math.floor(Math.random() * 3);
			generateTetromino();
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onKDown);
		}

		/**
		 * Function to generate the initial game field.
		 * The field is represented numerically by a 2D array (fieldArray)
		 * and visually by a Sprite (fieldSprite) added to the stage.
		 */
		private function generateField(): void {
			// Define alternating colors for the game field tiles.
			var colors: Array = new Array("0x444444", "0x555555");

			// Initialize the fieldArray to store numerical representation of the game field.
			fieldArray = new Array;

			// Create a new Sprite to visually represent the game field and add it to the stage.
			var fieldSprite: Sprite = new Sprite;
			addChild(fieldSprite);

			// Set the line style for the graphics of the fieldSprite.
			fieldSprite.graphics.lineStyle(0, 0x000000);

			// Set the position of fieldSprite to specific coordinates.
			fieldSprite.x = 29.05;
			fieldSprite.y = 18.05;

			// Loop through rows and columns to initialize fieldArray and draw the game field.
			for (var i: uint = 0; i < 20; i++) {
				// Initialize a new array for each row in fieldArray.
				fieldArray[i] = new Array;

				for (var j: uint = 0; j < 10; j++) {
					// Initialize each element in fieldArray to 0.
					fieldArray[i][j] = 0;

					// Use alternating colors to create a checkerboard pattern in the game field.
					fieldSprite.graphics.beginFill(colors[j % 2 + i % 2 % 2]);

					// Draw a rectangle representing a tile in the game field.
					fieldSprite.graphics.drawRect(TS * j, TS * i, TS, TS);

					// End the fill for the current tile.
					fieldSprite.graphics.endFill();
				}
			}
		}


		// Function to initialize different types of tetrominoes and their colors.
		private function initTetrominoes(): void {
			// I
			tetrominoes[0] = [
				[
					[0, 0, 0, 0],
					[1, 1, 1, 1],
					[0, 0, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 0, 0],
					[0, 1, 0, 0],
					[0, 1, 0, 0],
					[0, 1, 0, 0]
				]
			];
			colors[0] = 0x00FFFF;

			// T
			tetrominoes[1] = [
				[
					[0, 0, 0, 0],
					[1, 1, 1, 0],
					[0, 1, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 0, 0],
					[1, 1, 0, 0],
					[0, 1, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 0, 0],
					[1, 1, 1, 0],
					[0, 0, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 0, 0],
					[0, 1, 1, 0],
					[0, 1, 0, 0],
					[0, 0, 0, 0]
				]
			];

			colors[1] = 0xAA00FF;

			// L
			tetrominoes[2] = [
				[
					[0, 0, 0, 0],
					[1, 1, 1, 0],
					[1, 0, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[1, 1, 0, 0],
					[0, 1, 0, 0],
					[0, 1, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 0, 1, 0],
					[1, 1, 1, 0],
					[0, 0, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 0, 0],
					[0, 1, 0, 0],
					[0, 1, 1, 0],
					[0, 0, 0, 0]
				]
			];

			colors[2] = 0xFFA500;

			// J
			tetrominoes[3] = [
				[
					[1, 0, 0, 0],
					[1, 1, 1, 0],
					[0, 0, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 1, 0],
					[0, 1, 0, 0],
					[0, 1, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 0, 0, 0],
					[1, 1, 1, 0],
					[0, 0, 1, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 0, 0],
					[0, 1, 0, 0],
					[1, 1, 0, 0],
					[0, 0, 0, 0]
				]
			];
			colors[3] = 0x0000FF;

			// Z
			tetrominoes[4] = [
				[
					[0, 0, 0, 0],
					[1, 1, 0, 0],
					[0, 1, 1, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 0, 1, 0],
					[0, 1, 1, 0],
					[0, 1, 0, 0],
					[0, 0, 0, 0]
				]
			];
			colors[4] = 0xFF0000;

			// S
			tetrominoes[5] = [
				[
					[0, 0, 0, 0],
					[0, 1, 1, 0],
					[1, 1, 0, 0],
					[0, 0, 0, 0]
				],
				[
					[0, 1, 0, 0],
					[0, 1, 1, 0],
					[0, 0, 1, 0],
					[0, 0, 0, 0]
				]
			];
			colors[5] = 0x00FF00;

			// O
			tetrominoes[6] = [
				[
					[0, 1, 1, 0],
					[0, 1, 1, 0],
					[0, 0, 0, 0],
					[0, 0, 0, 0]
				]
			];
			colors[6] = 0xFFFF00;
		}

		// Function to generate a new tetromino.
		private function generateTetromino(): void {
				currentTetromino = Math.floor(Math.random()*7);
				nextTetromino = Math.floor(Math.random()*3);
				drawNext();
				currentRotation = 0;
				if (tetrominoes[currentTetromino][0][0].indexOf(1) == -1) {
					tRow = -1;
				}
				tCol = 4;
				drawTetromino();
				timeCount.addEventListener(TimerEvent.TIMER, onTime);
				timeCount.start();
			}

		// Function to draw the preview of the next tetromino.
		//draws the next tetromino in the same way drawTetromino does, just in another place.
		private function drawNext(): void {
			if (getChildByName("next") != null) {
				removeChild(getChildByName("next"));
			}
			var next_t: Sprite = new Sprite();
			next_t.x = 390;
		    next_t.y = 62;
			next_t.name = "next";
			addChild(next_t);
			next_t.graphics.lineStyle(0, 0xb7b7b7);

			for (var i: int = 0; i < tetrominoes[nextTetromino][0].length; i++) {
				for (var j: int = 0; j < tetrominoes[nextTetromino][0].length; j++) {
					if (tetrominoes[nextTetromino][0] == 1) {
						next_t.graphics.beginFill(colors[nextTetromino]);
						next_t.graphics.drawRect(TS * j, TS * i, TS, TS);
						next_t.graphics.endFill();
					}
				}
			}
		}

		// Event handler for the TimerEvent.TIMER event.
		private function onTime(e: TimerEvent): void {
			if (canFit(tRow + 1, tCol, currentRotation)) {
				tRow++;
				placeTetromino();
			} else {
				landTetromino();
				generateTetromino();
			}
		}

		// Function to draw the current tetromino on the stage.
		private function drawTetromino(): void {
			var ct: uint = currentTetromino;
			tetromino = new Sprite();
			addChild(tetromino);
			tetromino.graphics.lineStyle(0, 0xCFCCF7);

			// Loop to draw the individual tiles of the current tetromino.
			for (var i: int = 0; i<tetrominoes[ct][currentRotation].length; i++) {
				for (var j: int = 0; j < tetrominoes[ct][currentRotation].length; j++) {
					if (tetrominoes[ct][currentRotation] == 1) {
						tetromino.graphics.beginFill(colors[ct]);
						tetromino.graphics.drawRect(TS * j, TS * i, TS, TS);
						tetromino.graphics.endFill();
					}
				}
			}

			// Place the tetromino on the game field.
			placeTetromino();
		}

		// Function to place the current tetromino at its current position.
		private function placeTetromino(): void {
			tetromino.x = tCol * TS;
			tetromino.y = tRow * TS;
		}

		// Event handler for the KeyboardEvent.KEY_DOWN event.
		private function onKDown(e: KeyboardEvent): void {
			switch (e.keyCode) {
				case 37:
					// Left arrow key
					if (canFit(tRow, tCol - 1, currentRotation)) {
						tCol--;
						placeTetromino();
					}
					break;

				case 38:
					// Up arrow key
					var ct: uint = currentRotation;
					var rot: uint = (ct + 1) % tetrominoes[currentTetromino].length;
					if (canFit(tRow, tCol, rot)) {
						currentRotation = rot;
						removeChild(tetromino);
						drawTetromino();
						placeTetromino();
					}
					break;

				case 39:
					// Right arrow key
					if (canFit(tRow, tCol + 1, currentRotation)) {
						tCol++;
						placeTetromino();
					}
					break;

				case 40:
					// Down arrow key
					if (canFit(tRow + 1, tCol, currentRotation)) {
						placeTetromino();
					} else {
						// Tetromino has landed, generate a new one.
						landTetromino();
						generateTetromino();
					}
					break;
			}
		}

		// Function to handle the landing of the tetromino on the game field.
		private function landTetromino(): void {
			// ... (landing tetromino code)
			var ct: uint = currentTetromino;
			var landed: Sprite;
			for (var i: int = 0; i < tetrominoes[ct][currentRotation].length; i++) {

				for (var j: int = 0; j < tetrominoes[ct][currentRotation].length; j++) {
					if (tetrominoes[ct][currentRotation] == 1) {
						landed = new Sprite();
						addChild(landed);
						landed.graphics.lineStyle(0, 0x000000);
						landed.graphics.beginFill(colors[currentTetromino]);
						landed.graphics.drawRect(TS * (tCol + j), TS * (tRow + i), TS, TS);
						landed.graphics.endFill();
						landed.name = "r" + (tRow + i) + "c" + (tCol + j);
						fieldArray[tRow + i][tCol + j] = 1;
					}
				}
			}

			removeChild(tetromino);
			checkForLines();
		}

		// Function to check for completed lines and clear them.
		private function checkForLines(): void {
			for (var i: int = 0; i < 20; i++) {
				//for loop literating through all 20 lines in the game field
				if (fieldArray[i].indexOf(0) == -1) {
					//since a line must be completely filled with tetrominoes pleces to be considered as completed,
					//the array must be filled by 1, there can't be any 0.
					for (var j: int = 0; j < 12; j++) {
						//if a line is completed, then we literate through all its tem colums to remove it.
						fieldArray[i][j] = 0;
						//this clears the game field bring back fieldArray[i][j] element at 0.
						removeChild(getChildByName("r" + i + "c" + j));
						//and this removes the corresponding displayObject, easily located by its name
					}

					for (j = i; j >= 0; j--) {
						//this is the most important loop
						//it ranges from i (the row we just cleared) back to zero.
						//we are scanning all rows above the row we just cleared
						for (var k: int = 0; k < 12; k++) {
							//this for loop iterates through all 10 elements in the j-th row
							if (fieldArray[j][k] == 1) {
								//checks if there is a tetrimino piese in the k-th column of the j-th row
								fieldArray[j][k] = 0;
								//sets the k-th colunn of the j-th row to 0
								fieldArray[j + 1][k] = 1;
								//sets the k-th column of the (j+1)th row to 1. 
								//we are shifting down an entire line
								getChildByName("r" + j + "c" + k).y += TS;
								//moves down the corresponding displayobject by TS pixels
								getChildByName("r" + j + "c" + k).name = "r" + (j + 1) + "c" + k;
								//changes the corresponding displayobject name according to its new position
							}
						}
					}
				}
			}
		}

		// Function to determine if the current tetromino can fit at a specific position and rotation.
		private function canFit(row: int, col: int, side: uint): Boolean {
			// ... (check if tetromino can fit at the specified position and rotation code)
			var ct: uint = currentTetromino;
			for (var i: int = 0; i < tetrominoes[ct][side].length; i++) {
				for (var j: int = 0; j < tetrominoes[ct][side].length; j++) {
					if (tetrominoes[ct][side] == 1) {
						// out of left boundary
						if (col + j < 0) {
							return false;
						}

						// out of right boundary
						if (col + j > 11) {
							return false;
						}

						// out of bottom boundary
						if (row + i > 19) {
							return false;
						}

						// out of top boundary
						if (row + i < 0) {
							return false;
						}

						// over another tetromino
						if (fieldArray[row + i][col + j] == 1) {
							return false;
						}
					}
				}
			}
			return true;
		}
	}
}
    This topic has been closed for replies.

    2 replies

    kglad
    Community Expert
    Community Expert
    December 9, 2023

    to start, the drawing code is wrong, but because so much of it looks well-coded, i suspect you copied the code from an unreliable source or you copied code that was never completed.

    Community Expert
    December 9, 2023

    @JoãoCésar17023019  could probably help, he is super good at coding.