砖块破碎机 - 砖块没有出现

时间:2017-05-04 21:06:10

标签: javascript

我目前正在用JavaScript语言编写一个BrickBreaker游戏。它是我使用该语言的第一个项目之一,我遇到了一些困难。这是我的代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
    </style>
</head>
<body>

<canvas id="myCanvas" width="500" height="500"></canvas>

<script>

var canvas=document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius=10;
var a = {
    x: canvas.width/2,
    y: canvas.height-30};
var x=canvas.width/2;
var y=canvas.height-30;
var speed = [2, -2, 10];
var paddle = {
    paddleHeight: 10,
    paddleWidth: 75,
    };
var paddleX=(canvas.width-paddle.paddleWidth)/2;
var rightPressed= false;
var leftPressed=false;
var score = 0;
var brick = {
    brickRowCount: 3,
    brickColumnCount: 5,
    brickWidth: 75,
    brickHeight: 20,
    brickPadding: 10,
    brickOffsetTop: 30,
    brickOffsetLeft: 30};
var amountOfBricks = brick.brickRowCount*brick.brickColumnCount;
document.addEventListener("keydown",keyDownHandler,false);
document.addEventListener("keyup",keyUpHandler,false);
var wall = new Wall(5, 3 , 75, 70, 10, 30, 30);
wall.makeBricks();

function Brick(x, y, width, height, status) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.status = status;

    this.display = function() {
        if(this.status == 1) {
            ctx.beginPath();
            ctx.rect(this.x, this.y, this.width, this.height);
            ctx.fillStyle = "green";
            ctx.fill();
            ctx.closePath();
        }
    }
}

function Wall(numRows, numCols, bricksWidth, bricksHeight, bricksPadding, bricksOffsetTop, bricksOffsetLeft) {
    this.numRows = numRows;
    this.numCols = numCols;
    this.bricksWidth = bricksWidth;
    this.bricksHeight = bricksHeight;
    this.bricksPadding = bricksPadding;
    this.bricksOffsetTop = bricksOffsetTop;
    this.bricksOffsetLeft = bricksOffsetLeft;
    this.bricks = [];

    this.makeBricks = function() {
        for(c=0; c < this.numRows; c++) {
            this.bricks[c] = [];
            for(r=0; r < this.numCols; r++) {
                this.bricks[c][r] = new Brick(
                    (c*(this.bricksWidth + this.bricksPadding)+this.bricksOffsetLeft),
                    (r*(this.bricksHeight+this.bricksPadding)+this.bricksOffsetTop),
                    this.bricksHeight,
                    this.bricksWidth,
                    1)
            }
        }
    }

    this.display = function() {
        for(row of this.bricks) {
            for(brick of row) {
                console.log(brick);
                brick.display()
            }
        }
    }
}

function keyDownHandler(e){
    if(e.keyCode==39){

        rightPressed=true;

        }
        else if(e.keyCode==37){

        leftPressed=true;

        }

    }


function drawScore() {
    ctx.font = "16px Arial";
    ctx.fillStyle = "#0095DD";
    ctx.fillText("Score: "+score, 8, 20);
}
function keyUpHandler(e){

    if(e.keyCode==39){

        rightPressed=false;
    }
    else if(e.keyCode==37){

        leftPressed=false;

        }
    }

function drawBall(){
    ctx.beginPath();
    ctx.arc(x,y,ballRadius,0,2*Math.PI);
    ctx.fillstyle="#0033FF";
    ctx.fillStroke="#0033FF";
    ctx.Stroke="10"
    ctx.fill();
    ctx.closePath();
    }

function drawPaddle(){
    ctx.beginPath();
    ctx.rect(paddleX,canvas.height-paddle.paddleHeight,paddle.paddleWidth,paddle.paddleHeight);
    ctx.fillstyle="#0095DD";
    ctx.fill();
    ctx.closePath();
    }

function collisionDetection() {
    for(c=0; c<brick.brickColumnCount; c++) {
        for(r=0; r<brick.brickRowCount; r++) {
            var b = bricks[c][r];
            if(b.status == 1) {
                if(x > b.x && x < b.x+brick.brickWidth && y > b.y && y < b.y+brick.brickHeight) {
                    speed[1] = -speed[1];
                    b.status = 0;
                    score++;
                    if(score == amountOfBricks) {
                        alert("You Win");
                        document.location.reload()
                    }
                }
            }
        }
    }
}



function draw(){
    ctx.clearRect(0,0,canvas.width,canvas.height);
    //drawBricks();
    drawBall();
    drawPaddle();
    drawScore();
    wall.display();
    collisionDetection();
 if(x + speed[0] > canvas.width-ballRadius || x + speed[0] < ballRadius) {
        speed[0] = -speed[0];
    }
    if(y + speed[1] < ballRadius) {
        speed[1] = -speed[1];
    }
    else if(y + speed[1] > canvas.height-ballRadius) {
        if(x > paddleX && x < paddleX + paddle.paddleWidth) {
             if(y= y-paddle.paddleHeight){
            speed[1] = -speed[1]  ;
             }
        }
        else {
            alert("GAME OVER");
            document.location.reload();
        }
    }
    if(rightPressed && paddleX<canvas.width-paddle.paddleWidth){

        paddleX+=7;
        }
     else if(leftPressed && paddleX>0 ){
         paddleX-=7;

         }

         x=x+speed[0];
         y=y+speed[1];
    }

setInterval(draw,10);

</script>
</body>
</html>

不幸的是,这会产生错误类型的砖块,因为它们应该是小而扁平的,而是变得大而且四四方方。此外,当球击中砖块时,它对它们没有影响,而它应该摆脱砖块并增加分数。任何人都可以看到我的代码出错的地方并指出要解决的问题以使游戏正常工作吗?

感谢。

1 个答案:

答案 0 :(得分:1)

使用前声明变量。

代码具有不声明循环变量的模式,这导致它们被创建为同名window对象的全局属性。如果在不同的函数中使用相同的循环变量,它们可能会相互干扰。这适用于标准和for...of循环使用。

通过代码,有四个问题(错误)阻止发布的代码工作或阻止它运行:

  1. rc设置为列对象而不是Wall对象中的行和列。 makeBricks方法:

    for(c=0; c < this.numRows; c++) {
        this.bricks[c] = [];
        for(r=0; r < this.numCols; r++) {
    

    应该{​​{1}}和numRows互换:

    numCols
  2. 仍然在for(var c=0; c < this.numCols; c++) { this.bricks[c] = []; for(var r=0; r < this.numRows; r++) { //... 函数中,调用makeBricks的倒数第二个参数的顺序错误,需要按顺序排列:

    new Brick
  3. 砖块对象属性:this.bricksWidth, this.bricksHeight, brickRowCount不属于那里,在构建墙时未设置。在碰撞检测中使用它们以及砖块计算量应该由Wall对象brickColumnCount的{​​{1}}和numRows属性替换。

    numCols
  4. wall需要定义循环变量,使用var wall = new Wall(5, 3 , 75, 70, 10, 30, 30); var amountOfBricks = wall.numRows*wall.numCols; 中的墙尺寸,以及使用collisionDetection数组。

    wall
  5. 修复那些和砖块开始采用分配给它们的尺寸,并在击球时消失:D

    更新

    另一个错误浮出水面,可能是最初阻止代码早期版本工作的错误。看看wall.bricks

    的定义
    function collisionDetection() {
        for(var c=0; c<wall.numCols; c++) {
            for(var r=0; r<wall.numRows; r++) {
                var b = wall.bricks[c][r];
                // ...
    

    它被brick的内部循环变量覆盖并设置为var brick = { brickRowCount: 3, brickColumnCount: 5, brickWidth: 75, brickHeight: 20, brickPadding: 10, brickOffsetTop: 30, brickOffsetLeft: 30}; 对象:

    Brick

    可以编写声明变量:

    Wall.display

    请注意, for(row of this.bricks) { for(brick of row) { // updates the value of global variable brick 个对象没有 for(var row of this.bricks) { for(var brick of row) { Brick属性。我的解决方案是删除brickWidth变量定义,声明brickHeight循环变量,并将brick中的brickbrick.brickWidth更改为brick.brickHeightcollisionDetection

    如此完整的循环:声明变量以避免引入微妙的错误。