Question
help!! tetris game in action script 3 didn't work
// 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;
}
}
}