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

あなたの問題はupdateメソッドにあります。

新しいブロックが下のブロックと衝突したと配列に示されていても、新しいブロックの「Y座標」が下のブロックの正確に上にない場合があります。

したがって、配列が衝突を示している場合は、新しいブロックが衝突したブロックの上にぴったりと収まるように、新しいブロックの「Y座標」を調整してください。

問題を修正するための擬似コードは次のとおりです。

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 に答える