не удается получить обнаружение столкновения на массиве шарик-пол? - PullRequest
0 голосов
/ 02 октября 2019

Кажется, я не могу заставить обнаружение столкновений работать с массивом пола? Кажется, у меня проблема в функции ballMovement.
Мяч падает прямо через прямоугольники, образованные массивом.

  1. Массив пола (проблема)
  2. СтолкновениеОбнаружение

<html lang=en>
<head>
<meta charset=utf-8>
    <title>Javascript gravity</title>
    <link rel="stylesheet" href="game.css">
    </head>
    <body onload="init()">


<script>
    var canvas, ctx, container;
    canvas = document.createElement( 'canvas' );
    ctx = canvas.getContext("2d");
    var ball;
    var message = "Helloworld";

    // Velocity x
    var vx = 2.0;
    // Velocity y - randomly set
    var vy;

    var gravity = 0.5;  
    var bounce = 0.7; 
    var xFriction = 0.1;

    // Floor Array
    var floor = new Array();    

    //Rectagles
    Rectangle = function(x, y, w, h, color){

    if (x == null || y == null || w == null || h == null){

        alert("You must pass in all the veriables for a rectange: (x, y, width, height)");

        var errorMsg = "The following are not provided:";
        if (x == null)
            errorMsg += " 'x' ";
        if (y == null)
            errorMsg += " 'y' ";
        if (w == null)
            errorMsg += " 'width' ";
        if (h == null)
            errorMsg += " 'height'";

        alert(errorMsg);
        throw new Error(errorMsg);
    }

    this.x      = x;
    this.y      = y;
    this.width  = w;
    this.height = h;

    this.color = new Color();

    this.Contains = function(x, y){

        if (x >= this.x && x <= this.x + this.width &&
            y >= this.y && y <= this.y + this.height)
            return true;
        else 
            return false;
    };

    this.Draw = function(ctx){
        ctx.fillStyle = this.color.ToStandard();
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
};
    //Rectangle Colors
    Color = function(r, g, b, a){

    this.r = 255;
    this.g = 255;
    this.b = 255;
    this.a = 1;

    if (r != null)
        this.r = r;
    if (g != null)
        this.g = g;
    if (b != null)
        this.b = b;
    if (a != null)
        this.a = a;

    this.ToStandard = function(noAlpha){

        if (noAlpha == null || !noAlpha)
            return "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
        else
            return "rgb(" + this.r + "," + this.g + "," + this.b + ")";
    };
};


    function init(){
       setupCanvas();
        vy = (Math.random() * -5) + -5;
        ball = {x:canvas.width / 2, y:100, radius:10, status: 0,   color:"red"};

        floor.push(new Rectangle(0, 480, 500, 20));
        floor.push(new Rectangle(250, 350, 200, 20));
        //floor.push(new Rectangle(150, 300, 20, 20));
        //floor.push(new Rectangle(200, 250, 20, 20));
        //floor.push(new Rectangle(250, 200, 20, 20));
        //floor.push(new Rectangle(300, 150, 20, 20));
        //floor.push(new Rectangle(350, 100, 20, 20));
        //floor.push(new Rectangle(400, 50, 20, 20));
        for (var i = 0; i < floor.length; i++)floor[i].color = new Color(0, 0, 0, 1);

    }//end init method

    function draw() {
        ctx.clearRect(0,0,canvas.width, canvas.height); 

        for (var i = 0; i < floor.length; i++)
             floor[i].Draw(ctx);

        //display some text
           ctx.fillStyle = "red";
           ctx.font = "20px Arial";
           ctx.fillText(message, 20,20);    

             //draw cirlce
            ctx.beginPath();
            ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI*2, false);
            ctx.fillStyle = ball.color;
            ctx.fill();
            ctx.closePath();

        ballMovement();

    }

    setInterval(draw, 1000/35);     

    function ballMovement(){
        ball.x += vx;
        ball.y += vy;
        vy += gravity;

        //If either wall is hit, change direction on x axis
        if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0){
            vx *= -1;
        }

          // Ball hits the canvas floor
        if (ball.y + ball.radius > canvas.height){// ||

            // Re-positioning on the base
           ball.y = canvas.height - ball.radius;
            //bounce the ball
              vy *= -bounce;
            //do this otherwise, ball never stops bouncing
              if(vy<0 && vy>-2.1)
                         vy=0;
            //do this otherwise ball never stops on xaxis
             if(Math.abs(vx)<1.1)
                 vx=0;

             xF();

    }
    // Ball hits the rectangles
        if (ball.y + ball.radius > floor.width){// ||

            // Re-positioning on the base
           ball.y = floor.height - ball.radius;
            //bounce the ball
              vy *= -bounce;
            //do this otherwise, ball never stops bouncing
              if(vy<0 && vy>-2.1)
                         vy=0;
            //do this otherwise ball never stops on xaxis
             if(Math.abs(vx)<1.1)
                 vx=0;

             xF();

    }


}

    function xF(){
             if(vx>0)
                 vx = vx - xFriction;
             if(vx<0)
                 vx = vx + xFriction;
    }    


    function setupCanvas() {//setup canvas


    container = document.createElement( 'div' );
    container.className = "container";

    canvas.width = 500; 
    canvas.height = 500; 
    document.body.appendChild( container );
    container.appendChild(canvas);  

    ctx.strokeStyle = "red";
    ctx.lineWidth =1;   
}

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

1 Ответ

0 голосов
/ 07 октября 2019

Есть пара ошибок:

  1. Вы сравниваете положение шарика на оси Y ball.y с шириной полосы floor.width, это может быть ошибка ввода / редактирования.

  2. Вы должны заменить floor.width на floor.y, чтобы проверить, попадает ли мяч в штангу при падении.

  3. Но floorМассив Rectangle, он включает в себя планку и потенциальные кирпичи, которые можно сломать, если я думаю, это правильно. Таким образом, перед проверкой вам нужно перебрать floor, иначе floor.height равно undefined.

    for (let i = 0; i < floor.length; i += 1) {
        const rect = floor[i];
        // Ball hits the rectangle
        if (ball.y + ball.radius > rect.y) {
            // ...
        }
    }

Тогда floor не подходит для Array , который не содержит ' floor '.

Наконец, добавьте условие для обработки положения шара X (столкновения с перекладиной, кирпичи и т. Д.).

Рабочий пример: https://jsfiddle.net/nmerinian/3sokr512/22/

Хорошего дня

...