0

我的代码在下面,你可以在这里查看http://jsfiddle.net/ShaShads/S9Pc5/

$(document).ready(function() {

var canvas = $('canvas')[0]; // get the canvas element
var ctx = canvas.getContext('2d'); // create the canvas context
var engine = new engine(); // holds the game engine
var blockActive = false; // whether a block is actively dropping

function engine() {

    this.cellSize = 50; // the size of each side of a grid cell square

    this.cellX = canvas.width / this.cellSize; // the amount of columns along the x axis

    this.cellY = canvas.height / this.cellSize; // the amount of cells along the y axis

    this.totalCells = this.cellX * this.cellY; // the total amount of cells in the grid

    this.buildGrid = function() { // returns the grid which is dynamically built
        var arr = new Array(this.cellX); // array with the same length as number of cells on x axis
        for(var i = 0; i < arr.length; ++i) { // iterate over the array
            arr[i] = new Array(this.cellY); // each value of array contains an array to the length of cells on y axis
        }
        return arr;
    };

    this.grid = this.buildGrid(); // where the grid array is stored

    this.getGridX = function(x) { // returns the x coordinate of where an entity should be placed in the grid array
        return Math.ceil(x / this.cellSize);
    };

    this.getGridY = function(y) { // returns the y coordinate of where an entity should be placed in the grid array
        return Math.ceil(y / this.cellSize);
    };

    this.checkGridDown = function(x, y) { // check for collision on next block down
        if(y >= (canvas.height - this.cellSize)) { // block has hit bottom of canvas
            return true;
        }
        if(this.grid[this.getGridX(x)][this.getGridY(y) + 1]) { // block has landed on top of another block
            return true;
        }
        return false; // no collisions found
    };

    this.gridDraw = function() { // draws all the entities of the grid onto the canvas
        for(var i = 0; i < this.grid.length; ++i) { // for each array in grid
            for(var i2 = 0; i2 < this.grid[i].length; ++i2) { // for each array in array of grid
                if(this.grid[i][i2]) { // entity exists, paint it to the canvas
                    ctx.fillStyle = this.grid[i][i2].color;
                    ctx.fillRect(this.grid[i][i2].x, this.grid[i][i2].y, this.cellSize, this.cellSize);
                }
            }
        }
    };
}

function block() {

    this.xStart = function() { // returns a random location of where a block should be inserted onto the grid
        var x = Math.floor(Math.random() * (engine.cellX - 1 + 1)) + 1; // generates random number between 1 and max column of grid
        return (x - 1) * engine.cellSize; // returns the x coordinate for the block
    };

    this.x = this.xStart();

    this.y = 0 - engine.cellSize; // the y coordinate for the block

    this.velocity = 10; // the speed at which the block will travel

    this.generateColor = function() { // returns a random color for the given block
        var colors = ['blue', 'red', 'green', 'black', 'orange']; // the colors a block can be
        return colors[Math.floor(Math.random() * colors.length)];
    };

    this.color = this.generateColor(); // the color of the block

    this.draw = function() { // draws the block onto the canvas
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, engine.cellSize, engine.cellSize);
    };

    this.update = function() { // updates the blocks movements
        if(!engine.checkGridDown(this.x, this.y)) { // check for collision
            this.y += this.velocity;
        } else { // block has collided
            this.storeBlock(); // store the block in the allocated cell
            blockActive = false; // change the blockActive boolean
        }
    };

    this.storeBlock = function() { // stores the block in the required cell of the grid

        engine.grid[engine.getGridX(this.x)][engine.getGridY(this.y)] = blockActive;
    };
}

function clearCanvas() {
    ctx.fillStyle = '#eee';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function gameLoop() {
    clearCanvas(); // clear the canvas background
    engine.gridDraw(); // draw all of the blocks stored in the grid
    if(!blockActive) { // no block is actively dropping
        blockActive = new block(); // create new block
    } else { // block is actively dropping
        blockActive.draw(); // draw the block
        blockActive.update(); // update the block
    }
}

setInterval(gameLoop, 16); // run the game
});

您会注意到,在第一个盒子落地后,我已经成功地将盒子堆叠在一起,并且由于某种原因,第一个盒子被保存在网格数组中的错误单元格中。第一个盒子着陆方式的差异还取决于它的行进速度。

我已经尝试了 2 个小时来弄清楚,但我做不到。我才学了2天,如果很简单请见谅!

编辑

将速度更改为 20 可以更好地显示问题。

4

1 回答 1

1

您的问题出在更新方法中。

Even though your array says the new block has collided with the block underneath, the “Y coordinate” of the new block might not be exactly on top of the block underneath.

So if the array indicates a collision, be sure to adjust the new block’s “Y coordinate” so the new block sits flushly on top of the block it collided into.

Here is pseudocode to correct your problem:

this.update = function() { // updates the blocks movements
if(!engine.checkGridDown(this.x, this.y)) { // check for collision
    this.y += this.velocity;
} else { // block has collided

    // PROBLEM -- this newest colliding block might not have been
    // set exactly on top of the block underneath
    // PSEUDOCODE CORRECTION
    this.y = // the block underneath this block’s “Y coordinate” – cellSize;

    this.storeBlock(); // store the block in the allocated cell
    blockActive = false; // change the blockActive boolean
}

};

于 2013-02-23T18:29:19.257 回答