(Javascript) Подпрыгивающие шарики зажимают в стену

document.addEventListener("DOMContentLoaded", function(event){
        var context,
                width = window.screen.availWidth - 120,
                height = window.screen.availHeight - 120,
                xTemp, 
                yTemp,
                x = [], 
                y = [], 
                dx = [0], 
                dy = [5], 
                gravity = [1],
                bounceTime = [1],
                canvas = document.getElementById("bouncingField"), 
                isSpawned = 0,
                image = new Image();
                
        document.getElementById("bouncingField").width = width;
        document.getElementById("bouncingField").height = height;
        
        //Image to use as ball texture
        image.src = "http://www.freeiconspng.com/uploads/soccer-ball-icon-14.png";
                
        //Run func init on page load
        window.onload = init;
        
        //Get 2d context and repaint every 10 milliseconds
        context = bouncingField.getContext('2d');
        setInterval(repaint, 10);
        
        canvas.onclick = function setSpawnTrue(){
                if(!isSpawned){
                        x[0] = xTemp;
                        y[0] = yTemp;
                } else{
                        x.push(xTemp);
                        y.push(yTemp);
                        dx.push(0);
                        dy.push(5);
                        gravity.push(1);
                        bounceTime.push(1);
                }
                
                isSpawned = 1;
        }
        
        //Draws the various entities
        function draw(){
                context = bouncingField.getContext('2d');
                for(var i = 0; i < x.length; i++){  
                        //context.beginPath();
                        //context.fillStyle = "#00ccff";
                        //Draw circles of r = 25 at coordinates x and y
                        //context.arc(x[i], y[i], 25, 0, Math.PI*2, true);
                        context.drawImage(image, x[i], y[i], 50, 50);
                        //context.closePath();
                        //context.fill();
                }
        }

        //Repaints entities, essentially animating them        
        function repaint(){
                for(var i = 0; i < x.length; i++){
                        context.clearRect(0, 0, 2000, 2000);
                        if(x[i] < 20 || x[i] > width) dx[i] *= -1;
                        if(y[i] < 20 || y[i] > height) {
                                dy[i] *= -1;
                                //We add bounceTime to dy so that it gradually loses speed
                                dy[i] += bounceTime[i];
                                //Inverting graviy to slow down on rise
                                gravity[i] *= -1;
                        }
                        
                        x[i] += dx[i];
                        //Gravity affects the ball bounce speed, that gradually slows down.
                        y[i] += dy[i] + gravity[i];
                        //bounceTime gradually reduces the amount of speed the ball has
                        gravity[i] += 0.2 * bounceTime[i];
                        bounceTime[i] += 0.01;
                        if(isSpawned){
                                draw();
                        }
                }
        }
        
        //Initializes Event.MOUSEMOVE to capture cursor coordinates
        function init(){
                if(window.Event){
                        document.captureEvents(Event.MOUSEMOVE);
                }
                document.onmousemove = getCoordinates;
        }
                
        //Gets mouse coordinates and puts them into xTemp and yTemp
        function getCoordinates(e){
                xTemp = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
                yTemp = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollRight ? document.documentElement.scrollRight : document.body.scrollRight);
                xTemp -= 14;
                yTemp -= 14;
        }
});
body{
        background-color: #555555;
}

#bouncingField{
        border-style: solid;
        border-width: 10px;
        border-color: white;
}
<HTML>
        <HEAD>
                <TITLE>
                        Wingin' it
                </TITLE>
                
                <script type="text/javascript" src="script.js"></script>
                
                <link href="style.css" rel="stylesheet" type="text/css">
        
        </HEAD>
        
        <BODY>
                <CANVAS id="bouncingField" width="0" height="0"></CANVAS>
        </BODY>
</HTML>

Я работаю над простым проектом JavaScript для создания прыгающих шаров, которые имитируют гравитацию и отскакивают от пола или стен. Проблема в том, что иногда они зажимаются в пол и «изрыгают», пока они не исчезнут с экрана. Почему? Я пытался понять это, добавив крошечный тайм-аут каждый раз, когда он сталкивается, но у JS нет сна, поэтому я просто запутался.

Заранее спасибо :)

javascript,physics,

0

Ответов: 1


0 принят

Надеюсь, это поможет. сложная часть делает убедительную «остановку».

function getCoordinates(event) { return { x: event.offsetX, y: event.offsetY }; }

function spawnBall(coords, x, y, dx, dy){
    x.push(coords.x);
    y.push(coords.y);
    dx.push(0);
    dy.push(2);
}

// =========================
// Draws the various entities
// =========================
function draw(canvas, image, x, y, width, height) {
    var context = canvas.getContext('2d');
    context.clearRect(0, 0, canvas.width, canvas.height);
    for(var i = 0; i < x.length; i++){ context.drawImage(image, x[i], y[i], width, height); }
}
// =========================

// =========================
// At the moment all this is concerned with is the "floor"
// =========================
function move(x, y, dx, dy, gravity, bounciness, floor){
    for(var i = 0; i < x.length; i++){
      // =========================
      // Ball is close to the floor and not moving very fast, set it to rest
      // otherwise it bounces forever.
      // =========================
      if (y[i] >= floor - 10 && Math.abs(dy[i]) <= 2 * gravity) {
          dy[i] = 0;
          y[i] = floor;
          continue;
      }
      // =========================

      // =========================
      // Update the speed and position
      // =========================
      dy[i] += gravity;
      y[i] += dy[i];
      // =========================

      // =========================
      // Simulate a bounce if we "hit" the floor
      // =========================
      if(y[i] > floor) {
          y[i] = floor - (y[i] - floor);
          dy[i] = -1.0 * bounciness * dy[i];
      }
      // =========================
  }
}
// =========================

document.addEventListener("DOMContentLoaded", function(event){
    var canvas = document.getElementById("bouncingField");
    canvas.width = window.innerWidth - 50;
    canvas.height = window.innerHeight - 50;

    //Image to use as ball texture
    var image = new Image();
    image.src = "http://www.freeiconspng.com/uploads/soccer-ball-icon-14.png";

    var gravity = 1;
    var ballSize = 50;
    var ballBounciness = 0.8;
    var floor = canvas.height - ballSize;

    var x = [];
    var y = [];
    var dx = [];
    var dy = [];

    // =========================
    // This can be done via requestAnimationFrame()
    // https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
    // =========================
    var isSpawned = false;
    setInterval(function(){
        if(!isSpawned){ return; }
        move(x, y, dx, dy, gravity, ballBounciness, floor)
        draw(canvas, image, x, y, ballSize, ballSize);
    }, 10);
    // =========================

    // =========================
    // Add a ball
    // =========================
    canvas.onclick = function(event) {
        isSpawned = true;
        var coords = getCoordinates(event);
        spawnBall(coords, x, y, dx, dy);
    }
    // =========================
});
body {
  background-color: #555555;
}
#bouncingField {
  border-style: solid;
  border-width: 10px;
  border-color: white;
}
<canvas id="bouncingField"></canvas>

JavaScript, физика,
Похожие вопросы
Яндекс.Метрика