Столкновение Javascript (не обнаружение столкновений) - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь сделать платформерную игру, и я работаю над столкновением в течение последних 2 недель. Обнаружение столкновений работает, но само столкновение (например, удержание игрока вне фишки) - нет, что бы я ни пытался. Я пытался найти, как это сделать, но все, что я нахожу, это как сделать часть обнаружения, что я уже сделал. Что мне делать после обнаружения столкновения? Он был написан с нуля, а плеер прямоугольный, как и плитки. Вот основной код:

var Player = function(hue, x, y, xSize, ySize, health) {
    this.hue = hue;
    this.position = new PVector(x, y);
    this.originalPosition = new PVector(x, y);
    //this.previousPosition = new PVector(x, y);
    //this.ppp = new PVector(x, y);
    //this.virtualPosition = new PVector(x, y);
    //this.predictedPosition = new PVector(x, y);
    this.velocity = new PVector(0, 0);
    //this.predictedVelocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
}
/*Player.prototype.testCollision = function(tile) {
    if (this.predictedPosition.y < tile.position.y + tile.size.y && this.predictedPosition.y + this.size.y > tile.size.y && this.predictedPosition.x < tile.position.x + tile.size.x && this.predictedPosition.x + tile.size.x > tile.position.x) {
        return false;
    } else {
        return true;
    }
};*/
Player.prototype.ifColliding = function(tile) {
     if (this.position.x < tile.position.x + tile.size.x && this.position.x + tile.size.x > tile.position.x) {
        /*if (this.position.x + this.size.x > tile.position.x) {
            this.position.set(tile.position.x - this.size.x, this.position.y);
        } else if (this.position.x < tile.position.x + tile.size.x) {
            this.position.set(tile.position.x + tile.size.x, this.position.y);
        }*/
        this.velocity.set(0, this.velocity.y);
        //this.acceleration.set(0, this.acceleration.y);
        /*if (this.ppp.x < tile.position.x + tile.size.x && this.ppp.x + tile.size.x > tile.position.x) {
           if (this.ppp.x + this.size.x > tile.position.x) {
                this.position.set(tile.position.x - this.size.x, this.position.y);
            } else if (this.ppp.x < tile.position.x + tile.size.x) {
                this.position.set(tile.position.x + tile.size.x, this.position.y);
            } 
        } else if (this.previousPosition.x < tile.position.x + tile.size.x && this.previousPosition.x + tile.size.x > tile.position.x) {
            this.position.set(this.ppp.x, this.position.y);
        } else {
            this.position.set(this.previousPosition.x, this.position.y);
        }*/
    }
    if (this.position.y < tile.position.y + tile.size.y && this.position.y + this.size.y > tile.size.y) {
        this.velocity.set(this.velocity.x, 0);
        this.acceleration.set(this.acceleration.x, 0);
        this.yColliding = true;
        /*if (this.position.y + this.size.y > tile.position.y) {
            this.position.set(this.position.x, tile.position.y - this.size.y);
            rect(0, 20, 0, 0);
        } else if (this.position.y < tile.position.y + tile.size.y) {
            this.position.set(this.position.x, tile.position.y + tile.size.y);
            rect(20, 20, 0, 0);
        }*/
    }
}
Player.prototype.update = function(tiles) {
    //this.ppp.set(this.previousPosition.x, this.previousPosition.y);
    //this.previousPosition.set(this.position.x, this.position.y);
    this.velocity.add(this.acceleration);
    /*this.predictedVelocity.set(this.velocity.x, this.velocity.y);
    this.predictedVelocity.add(this.acceleration);
    this.virtualPosition.set(this.position.x, this.position.y);
    this.virtualPosition.add(this.velocity);
    this.predictedPosition.set(this.virtualPosition.x, this.virtualPosition.y);
    this.predictedPosition.add(this.predictedVelocity);
    var collDcted = false;
    for (var i = 0; i < tiles.length; i++) {
        if (this.testCollision(tiles[i], true) === false) {
             collDcted = false;
        }
    }*/
    //if (collDcted) {
    this.position.add(this.velocity);
    //}
}

Закомментированный код - неудачные попытки. Код без комментариев - самый близкий к работе.

1 Ответ

0 голосов
/ 05 декабря 2018

Это пример столкновения, которое я сделал:

<!DOCTYPE html>
<html>
    
    <body> 
        <p id="Health">Health</p>
<canvas id="gameCanvas" width="600" height="480" style = "border:1px solid gray"></canvas>
<script>
    // Adding keyboard evt listener
    document.addEventListener("keydown", keyPressed);
    document.addEventListener("keyup", keyReleased);
    
    //defining canvas
    var canvas;
    var canvasContext;
    
    //defining Player variables
    var PLAYER_X = 100;
    var PLAYER_Y = 100;
    var PLAYER_WIDTH = 20;
    var PLAYER_HEIGHT = 20;            
    var PLAYER_HEALTH = 100;
    
    //defining keypress codes
    var KEY_LEFT = 37;
    var KEY_RIGHT = 39;
    var KEY_UP = 38;
    var KEY_DOWN = 40;
    
    //variables used to test movement
    var keyHeld_Up = false;
    var keyHeld_Down = false;
    var keyHeld_Left = false;
    var keyHeld_Right = false;

    //Keypress?
    
      function keyPressed(evt) {
          
        if(evt.keyCode == KEY_UP) {          
            keyHeld_Up = true;
        }
          
        if(evt.keyCode == KEY_DOWN) {
 
            keyHeld_Down = true;
        }
          
        if(evt.keyCode == KEY_LEFT) {
          keyHeld_Left = true;
        }
          
        if(evt.keyCode == KEY_RIGHT) {
          keyHeld_Right = true;
        }
          
          //prevents page from scrolling when arrow keys are pressed
          evt.preventDefault();
      }
          
      //Key Released?   
    
      function keyReleased(evt) {
          
        if(evt.keyCode == KEY_UP) {          
            keyHeld_Up = false;
        }
          
        if(evt.keyCode == KEY_DOWN) {
 
            keyHeld_Down = false;
        }
          
        if(evt.keyCode == KEY_LEFT) {
          keyHeld_Left = false;
        }
          
        if(evt.keyCode == KEY_RIGHT) {
          keyHeld_Right = false;
        }
          
      }
    
    //Initialize Canvas and Game Loop
       
    window.onload = function() {
    console.log("Is this thing on?");
        canvas = document.getElementById('gameCanvas');
        canvasContext = canvas.getContext('2d');
        
        var framesPerSecond = 30;
        setInterval(function() {
            
            drawObjects();
            movePlayer();
            damageTest();
            
        }, 1000/framesPerSecond);
    
    }        
    
   // Drawing function 
    
   function colorRect(x,y, width,height, color, health) {
       this.width = width;
       this.height = height;
       this.x = x;
       this.y = y;
       this.color = color;
       this.health = health;
       
       this.update = function() {
           this.draw();
       }
       
       this.draw = function() {
          canvasContext.beginPath();
          canvasContext.rect(this.x, this.y, this.width, this.height);
          canvasContext.fillStyle = this.color;
          canvasContext.fill();
          canvasContext.closePath();
       }
    };
     
    // Creating Objects
    var Screen = new colorRect( 0, 0, 600, 480, 'black', 0);
    var Player = new colorRect( PLAYER_X, PLAYER_Y, PLAYER_WIDTH, PLAYER_HEIGHT, 'red', PLAYER_HEALTH);
    var Box = new colorRect( 200, 200, 30, 30, 'green', 0);
    var Spike = new colorRect( 300, 300, 25, 25, 'white', 0);

    // Drawing Objects
    
    function drawObjects() {
            Screen.update();
            Spike.update();
            Player.update();
            Box.update();
            
    }

    //Collision Test
    
    function collides( a, b ) {
     return a.x < b.x + b.width && 
            a.x + a.width > b.x &&
            a.y < b.y + b.height &&
            a.y + a.height > b.y;
    }

    //Movement based on keypress events
    
   function movePlayer() { 

      if(collides( Player, Box ) === false) {
         if(keyHeld_Up) {      
            Player.y -= 2;            
      }
       
       
          if(keyHeld_Down) {
             Player.y += 2;
      }
                    
          if(keyHeld_Left) {
             Player.x -= 2;
      }
             
          if(keyHeld_Right) {
             Player.x += 2;
      } 

      }
       
   

   }
    
    //Testing Collision for damage
    
    function damageTest() {
        
        if(collides( Player, Spike ) === true) {
            Player.health -= 1; 
        }
        
        //Displaying Health in <body>
        
        document.getElementById("Health").innerHTML = "Health: " + Player.health; 
    }
   
    

</script>
        

</body>

</html>

Код, который я сделал, полностью останавливает игрока на его дорожках при попадании в поле, но вы можете создать отдельные обстоятельства столкновения, когда объекты сталкиваются с каждой стороны другого объекта, и использовать их для обнаружения столкновения.

Надеюсь, это помогло! Если у вас есть какие-либо вопросы относительно этого кода, просто спросите! (Чтобы запустить фрагмент кода, вы можете перейти на полный экран и щелкнуть внутри canvas)

...