2

出于某种原因,我的代码拒绝让我为每个块分配 x 和 y 位置。每个块的宽度和高度为 30 像素,并将根据它所在的部分进行着色。重力和清除功能尚未实现,左移和右移功能如此不同,因为它无法正常工作,然后重新创建它,就像现在在左功能中看到的那样,它的工作量更少......

请帮忙!

编辑:对不起,我通常不发布任何内容。我现在无法通过的部分是功能块/添加块/typeSet/分配类型。它很好地分配了一个随机值,但是当该类型(例如正方形)分配 x 和 y 值时,它会给出错误。

<!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>
4

2 回答 2

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);
于 2012-02-08T15:23:30.427 回答
3

您可以首先检查数组是否实际上包含您认为它们包含的项目,例如,在您的左侧方法中,而不是这样:

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

做这个:

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;
        }
    }
}

似乎数组没有完全填充并且仅在运行时才填充,这可能会导致undefined引用。

PS:我还没有完全阅读代码;只是其中的一部分,因为它有很多工作要做。

于 2012-02-08T13:49:18.563 回答