2

For some reason my code refuses to let me assign an x and y position to each block. Each block is 30 pixels wide and tall and will be colored according to which piece it is a part of. Gravity and a clear function haven't been implemented and the move left and move right function are so different because it wasn't working right and then recreated it as it is seen now in the left function and it works less...

Please help!

Edit: My apologies, i dont normally post anything. The part i cant get past now is function block/add block/typeSet/assigning the type. it assigns a random one pretty well but then when that type (such as square) goes to assign x and y values it gives an error.

<!DOCTYPE html>
<html>
    <head>
        <title>Tetris in Canvas</title>
        <style type="text/css">
            canvas {
                border: solid 1px black;
                margin: -8px;
            }
        </style>
        <script type="text/javascript">
            var canvas = null;
            var ctx = null;
            var blockArray = [];
            var board = [];
            var blockNum = 0;
            for (var s = 0; s < 14; s++) {
                board[s] = [27];
                for (var t = 0; t < 27; t++) {
                    board[s][t] = -1;
                }
            }

            document.onkeydown = function(event) {
                var keyCode;

                if(event == null)
                    keyCode = window.event.keyCode;
                else
                    keyCode = event.keyCode;

                switch(keyCode) {
                    case 37:
                        left(blockArray.length);
                        break;
                    case 38:
                        up(blockArray.length);
                        break;
                    case 39:
                        right(blockArray.length);
                        break;
                    case 40:
                        down(blockArray.length);
                        break;
                    default:
                        break;
                }
            }

            window.onload = function init() {
                canvas = document.getElementById('Canvas1');
                ctx = canvas.getContext("2d");

                blank();
                addBlock();
                animate();
            }

            function up(i) {
                blank();
                animate();
            }

            function down(i) {
                var u = 0;
                var p = 0;
                while(u<4) {
                    if (blockArray[i].y[u] + 1 > 26) {
                        u = 10;
                    }
                    else if ((board[blockArray[i].x[u]][blockArray[i].y[u] + 1]) == -1) {
                        u++;
                    }
                    else {
                        p = u;
                        for (var g = 0; ((g < 4) && (p = u)); g++) {
                            if ((blockArray[i].x[u] == blockArray[i].x[g]) && (blockArray[i].y[u] + 1 == blockArray[i].y[g])) {
                                u++;
                            }
                        }
                        if (p == u)
                            u = 10;
                    }
                }
                if (u < 10) {
                    for (var j=0; j<4; j++) {
                        blockArray[i].y[j] +=1;
                    }
                }
                else
                    addBlock();
                animate();
            }

            function right(i) {
                var u = 0;
                var p = 0;
                while(u<4) {
                    if (blockArray[i].x[u] + 1 > 13) {
                        u = 10;
                    }
                    else if ((board[blockArray[i].x[u] + 1][blockArray[i].y[u]]) == -1)
                        u++;
                    else {
                        p = u;
                        for (var g = 0; ((g < 4) && (p = u)); g++) {
                            if ((blockArray[i].x[u] + 1 == blockArray[i].x[g]) && (blockArray[i].y[u] == blockArray[i].y[g]))
                                u++;
                        }
                        if (p == u)
                            u = 10;
                    }
                }
                if (u < 10) {
                    for (var j=0; j<4; j++) {
                        blockArray[i].x[j] +=1;
                    }
                }
                else
                    addBlock();
                animate();
            }

            function left(i) {
                var u;
                var p = 14;
                for (var w = 0; w<4; w++) {
                    if (blockArray[i].x[w] < p) {
                        p = blockArray[i].x[w];
                        u = w;
                    }
                }
                if (p > 0) {
                    if ((board[blockArray[i].x[u] - 1][blockArray[i].y[u]]) == -1) {
                        for (var j=0; j<4; j++) {
                            blockArray[i].x[j] -=1;
                        }
                    }
                }
                animate();
            }           

            function block(x, y, type) {
                blockNum += 1;
                this.id = blockNum;
                this.x = [];
                this.y = [];
                this.landed = false;
                this.type = Math.floor(Math.random() * (6)) + 1;
                typeSet(this.type);
            }

            function addBlock() {
                blockArray[blockArray.length] = new block();
            }

            function typeSet(type) {
                i = blockArray.length;
                switch (type) {
                    case 1:
                        square(i);
                        break;
                    case 2:
                        elR(i);
                        break;
                    case 3:
                        elL(i);
                        break;
                    case 4:
                        line(i);
                        break;
                    case 5:
                        zeR(i);
                        break;
                    case 6:
                        zeL(i);
                        break;
                    default:
                        break;
                }
            }


            function animate() {
                fillBoard();
                colorBoard();
            }

            function fillBoard() {
                for (var i = 0; i < 14; i++) {
                    for (var q = 0; q < 27; q++) {
                        board[i][q] = -1;
                    }
                }
                for (var i=0; i<blockArray.length; i++) {
                    for (var q=0; q<4; q++) {
                        board[blockArray[i].x[q]][blockArray[i].y[q]] = blockArray[i].type;
                    }
                }
            }

            function colorBoard() {
                blank();
                ctx.strokeStyle = "white";
                for(var q=0; q<14; q++) {
                    for(var r=0; r<27; r++) {
                        switch (board[q][r]) {
                            case 1:
                                ctx.fillStyle = "green";
                                color(q,r);
                                break;
                            case 2:
                                ctx.fillStyle = "orange";
                                color(q,r);
                                break;
                            case 3:
                                ctx.fillStyle = "cyan";
                                color(q,r);
                                break;
                            case 4:
                                ctx.fillStyle = "black";
                                color(q,r);
                                break;
                            case 5:
                                ctx.fillStyle = "yellow";
                                color(q,r);
                                break;
                            case 6:
                                ctx.fillStyle = "brown";
                                color(q,r);
                                break;
                            default: 
                                break;
                        }
                    }
                }
            }

            function color(q,r) {
                ctx.fillRect(q*30,(r-4)*30,30,30);
                ctx.strokeRect(q*30,(r-4)*30,30,30);
            }

            function square(i) {
                blockArray[i].x[0] = 7;
                blockArray[i].y[0] = 0;
                blockArray[i].x[1] = 7;
                blockArray[i].y[1] = 1;
                blockArray[i].x[2] = 8;
                blockArray[i].y[2] = 0;
                blockArray[i].x[3] = 8;
                blockArray[i].y[3] = 1;
            }
            function elR(i) {
                blockArray[i].x[0] = 7;
                blockArray[i].y[0] = 0;
                blockArray[i].x[1] = 7;
                blockArray[i].y[1] = 1;
                blockArray[i].x[2] = 7;
                blockArray[i].y[2] = 2;
                blockArray[i].x[3] = 8;
                blockArray[i].y[3] = 2;
            }
            function elL(i) {
                blockArray[i].x[0] = 7;
                blockArray[i].y[0] = 0;
                blockArray[i].x[1] = 7;
                blockArray[i].y[1] = 1;
                blockArray[i].x[2] = 7;
                blockArray[i].y[2] = 2;
                blockArray[i].x[3] = 6;
                blockArray[i].y[3] = 2;
            }
            function line(i) {
                blockArray[i].x[0] = 7;
                blockArray[i].y[0] = 0;
                blockArray[i].x[1] = 7;
                blockArray[i].y[1] = 1;
                blockArray[i].x[2] = 7;
                blockArray[i].y[2] = 2;
                blockArray[i].x[3] = 7;
                blockArray[i].y[3] = 3;
            }
            function zeR(i) {
                blockArray[i].x[0] = 6;
                blockArray[i].y[0] = 0;
                blockArray[i].x[1] = 7;
                blockArray[i].y[1] = 0;
                blockArray[i].x[2] = 7;
                blockArray[i].y[2] = 1;
                blockArray[i].x[3] = 8;
                blockArray[i].y[3] = 1;
            }
            function zeL(i) {
                blockArray[i].x[0] = 8;
                blockArray[i].y[0] = 0;
                blockArray[i].x[1] = 7;
                blockArray[i].y[1] = 0;
                blockArray[i].x[2] = 7;
                blockArray[i].y[2] = 1;
                blockArray[i].x[3] = 6;
                blockArray[i].y[3] = 1;
            }

            function blank() {
                ctx.restore();
                ctx.fillStyle = "blue";
                ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
                ctx.save();
            }

            function blank2() {
                ctx.restore();
                ctx.fillStyle = "purple";
                ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
                ctx.save();
            }

            function rotateImgRight() {
                for(d = 0; d < 180; d++) {
                    setTimeout(rotateImg, 50);
                }
            }

            function rotateImgLeft() {
                for(d = 0; d < 180; d++) {
                    setTimeout(rotateImg2, 50);
                }
            }

            function rotateImg2() {
                degrees = degrees - 0.5;
                radian = (Math.PI / 180.0) * degrees;

                blank();
                ctx.translate(ctx.canvas.width/2, 700);
                ctx.rotate(radian);
                ctx.drawImage(srcImg, -srcImg.width/2,-srcImg.height/2);
                slide = (degrees / 90) % 4;
            }

            function rotateImg(x,y) {
                degrees = degrees + 0.5;
                radian = (Math.PI / 180.0) * degrees;

                ctx.translate(x,y);
                ctx.rotate(radian);
                ctx.drawImage(srcImg, -srcImg.width/2,-srcImg.height/2);
                slide = (degrees / 90) % 4;
            }
        </script>
    </head>
    <body>
        <div style="width: 100%; text-align:center">
            <canvas id="Canvas1" width="421" height="690">Your browser does not support canvas.</canvas>
        </div>
    </body>
</html>
Tom Prats
  • 7,364
  • 9
  • 47
  • 77
  • 4
    You should try rephrasing your question so we can help. What specific part is the problem? You can't expect any one of us to finish off the entire thing – soniiic Feb 08 '12 at 13:23
  • @sonniiic: "my code refuses to let me assign an x and y position to each block" – FMaz008 Feb 08 '12 at 13:25
  • 1
    So which part of your 358 line code sample is that? – soniiic Feb 08 '12 at 13:29
  • 1) Can you just draw a tetromino anywhere on your grid? 2) Can you draw a piece at 30,40? 3) When you press left, does the piece move? Which bit is the problem? – Rich Bradshaw Feb 08 '12 at 13:50
  • Yes, if i choose all the specifics, ie where it goes, but the pieces only move if i override the movement methods for just a specific piece. last time i did that the collision detection was wrong (contained in my let, right and down functions) so i worked on it to get it to the point of the left function. the problem now is that the add function is unable to assign a starting array of x's and y's. – Tom Prats Feb 08 '12 at 13:59

2 Answers2

4

Your function addBlock looks like this:

function addBlock() {
    blockArray[blockArray.length] = new block();
}

At any arbitrary point, your blockArray length could be anything. For now let's assume it's 25.

You're inserting a block to the 25th position in the array.

Let's have a look at the block function:

function block(x, y, type) {
    blockNum += 1;
    this.id = blockNum;
    this.x = [];
    this.y = [];
    this.landed = false;
    this.type = Math.floor(Math.random() * (6)) + 1;
    typeSet(this.type);
}

What's this typeSet command? It doesn't look like it sets anything! Let's investigate:

function typeSet(type) {
    i = blockArray.length;
    switch (type) {
        case 1:
            square(i);
            break;
        // blah
    }
}

AHA! I've found the problem, square() goes to the blockArray at position i, which doesn't even exist yet as block() hasn't finished executing, and assigns loads of x and y variables all over the place. When block() finishes executing, it overwrites all the values that typeSet() has just written.

You need to refactor your typeSet() method so that it takes in the actual block object and sets the x and y values on that rather than trying to access the element within the array (which doesn't even exist yet):

typeSet(this, this.type);
soniiic
  • 2,664
  • 2
  • 26
  • 40
  • Thanks! That seemed to help a little bit. It's still having trouble either finding or assigning. It says: cannot read property "y" of undefined. it says the same thing for x to at one point in each of left, right, and down – Tom Prats Feb 08 '12 at 19:55
3

you can start by checking if the arrays actually contain the items you think they contain for example, in your left method, instead of this:

for (var w = 0; w<4; w++) {
    if (blockArray[i].x[w] < p) {
        p = blockArray[i].x[w];
        u = w;
    }
}

do this:

for (var w = 0; w<4; w++) {
    if ((blockArray[i]) && (blockArray[i].x[w])) {
        if (blockArray[i].x[w] < p) {
            p = blockArray[i].x[w];
            u = w;
        }
    }
}

it seems as though the array is not fully populated and only done so at runtime, this can lead to undefined references.

PS: i have not fully read the code; only part of it, as it is a lot to work through.

epoch
  • 16,396
  • 4
  • 43
  • 71
  • I have run into several undefined reference errors and slowly got around them. How would I ensure they're populated beforehand? – Tom Prats Feb 08 '12 at 13:52
  • you can either test if they contain blocks, or you can create 'empty' blocks when tetris initializes (ex: your left method test is `w < 4`, so you know you always have 3 blocks there.) – epoch Feb 08 '12 at 13:54