简体   繁体   中英

Collision detection between bricks and ball (working with an array of numbers)

I want to detect a collision between my ball and my bricks with an array made of numbers. It works but not completely.

If you look at my code, you see an array made of numbers from 0 to 5. 0 means that there is no brick detected and the rest is made of a color. The problem is that my function only detects a collision with the color 1 (black) but not the rest. What is the problem?

var canvas = document.getElementById("mijnCanvas");
var mijnObject = canvas.getContext("2d");

var afbeelding = new Image();
var balkX = (canvas.width/2)-50;
var balkY = canvas.height-40;

var balX = canvas.width/2;
var balY = canvas.height-50;
var radius = 8;
var balNaarX = 5;
var balNaarY = 5;

function makenBalkKort() {
    mijnObject.drawImage(afbeelding, balkX, balkY, afbeelding.width, afbeelding.height);
}
afbeelding.src = "Afbeeldingen/BrickSmasher_Balk_Kort.png";

function makenBal() {
    mijnObject.beginPath();
    var mijnBalGradient = mijnObject.createRadialGradient(balX, balY, 0, balX, balY, 6);
    mijnBalGradient.addColorStop(0, "#000000");
    mijnBalGradient.addColorStop(1, "#FFFFFF");
    mijnObject.fillStyle = mijnBalGradient;
    mijnObject.strokeStyle = "#000000";
    mijnObject.arc(balX, balY, radius, 0, 2*Math.PI, false);
    mijnObject.fill();
    mijnObject.stroke();
    mijnObject.closePath();
}

function tekenenObjecten() {
    mijnObject.clearRect(0, 0, canvas.width, canvas.height);
    makenBalkKort();
    makenBal();
    makenMuur();
    collisieMetStenenX();

    setTimeout(function() {
        if(balX+balNaarX < radius || balX+balNaarX > canvas.width-radius) {
            balNaarX = -balNaarX;
        }

        if(balY+balNaarY < radius) {
            balNaarY = -balNaarY;
        }

        if(balY+balNaarY > balkY-radius) {
            if(balX+balNaarX >= balkX && balX+balNaarX <= balkX+afbeelding.width) {
                balNaarY = -balNaarY;
            }
            else {
                alert("Game over");
                document.location.reload(); 
            }
        }
        balX += balNaarX;
        balY += balNaarY;
    }, 1000);
}
setInterval(tekenenObjecten, 20);

window.addEventListener("keydown", function LinksOfRechts() {
    mijnObject.clearRect(balkX, balkY, canvas.width, canvas.height);
    var balkNaarX = 10;
    var code = event.which || event.keyCode;
    if(code == 37) {
        if(balkX > 0) {
            balkX -= balkNaarX;
        }
    }
    else if(code == 39) {
        if(balkX < canvas.width-afbeelding.width) {
            balkX += balkNaarX;
        }
    }
    mijnObject.drawImage(afbeelding, balkX, balkY, afbeelding.width, afbeelding.height);
});

canvas.addEventListener("click", function balkLangMaken() {
    mijnObject.clearRect(balkX, balkY, canvas.width, canvas.height);
    afbeelding.src = "Afbeeldingen/BrickSmasher_Balk_Lang.png";
    setTimeout(function() {
        mijnObject.clearRect(balkX, balkY, canvas.width, canvas.height);
        afbeelding.src = "Afbeeldingen/BrickSmasher_Balk_Kort.png";
    }, 3000);
});

var stenenPerRij = 27;                              
var steenHoogte = 20;
var steenBreedte = canvas.width/stenenPerRij;

var stenen = [
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
    [0,1,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1,0],
    [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,1,1,0,0,2,2,2,2,0,0,0,0,0,0,1,0,1,4,4,4,0,1,0,0,0,1],
    [1,0,0,1,0,2,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,1,1,0,0,1],
    [1,1,1,1,0,2,2,2,2,0,0,0,0,0,0,1,0,1,4,4,0,0,1,0,1,0,1],
    [1,0,0,1,0,2,0,2,0,0,0,1,0,0,0,1,0,1,0,0,0,0,1,0,0,1,1],
    [1,0,0,1,0,2,0,0,2,2,0,0,1,1,1,0,0,1,4,4,4,0,1,0,0,0,1],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
];

function makenMuur() {
    for(var i = 0; i < stenen.length; i = i+1) {
        for(var j = 0; j < stenen[i].length; j = j+1) {
            tekenenStenen(j,i,stenen[i][j]);
        }
    }
}

function tekenenStenen(x,y,stenen) {
    switch(stenen) {
        case 1:
            mijnObject.fillStyle = "#0d0d0d";
            break;
        case 2:
            mijnObject.fillStyle = "#333333";
            break;
        case 3:
            mijnObject.fillStyle = "#595959";
            break;
        case 4:
            mijnObject.fillStyle = "#808080";
            break;
        case 5:
            mijnObject.fillStyle = "#a6a6a6";
            break;
        default:
            mijnObject.clearRect(0, 0, steenBreedte, steenHoogte);
            break;
    }
    if(stenen) {
        mijnObject.beginPath();
        mijnObject.strokeStyle = "#000000";
        mijnObject.rect(x*steenBreedte, y*steenHoogte, steenBreedte, steenHoogte);
        mijnObject.fill();
        mijnObject.stroke();
        mijnObject.closePath();
    }
}

function collisieMetStenenX() {
    for(var i = 0; i < stenen.length; i = i+1) {
        for(var j = 0; j < stenen[i].length; j = j+1) {
            if(stenen[i][j] == true) {
                var steenX = j*steenBreedte;
                var steenY = i*steenHoogte;
                if((balX+balNaarX > steenX && balX+balNaarX < steenX+steenBreedte)
                && (balY+balNaarY > steenY && balY+balNaarY < steenY+steenHoogte)) {
                    balNaarY = -balNaarY;
                }
            }
        }
    }
}

Here is my HTML-code:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BrickSmasher</title>
<style>
    canvas {
        position: relative;
        margin-left: auto;
        margin-right: auto;
        display: block; 
    }
</style>
</head>

<body>
    <canvas id="mijnCanvas" width="1200" height="600" style="border: 1px solid black"></canvas>
    <script src="BrickSmasher.js"></script>
</body>
</html>

Replace this line:

 if(stenen[i][j] == true) {

with:

 if(stenen[i][j] > 0) {

or simply:

 if(stenen[i][j]) {

The reason is that when you compare with true , JavaScript needs to do a conversion. As one side of the equation is numeric, the boolean expression on the other side is converted to the numeric equivalent of true , which is 1. That means there is no equality when stenen[i][j] is 2, 3, ...

The last alternative works, because there the conversion is in the opposite sense: an if condition needs to resolve to a boolean value. So the numerical value is converted to boolean. And there any non-zero value will convert to true .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM