在其他圆圈内保留一个圆圈(画布)

问题描述 投票:4回答:1

我正在制作游戏。我希望玩家不要离开圆形游戏区域。玩家不应越过红色圆圈。它应该保留在内部并且可以沿边界移动。

我编写了一个简单的功能来检测圆之间的碰撞。我也发现了一个错误。即使我在游戏区域内,我也会收到外面的console.log()消息。

[播放器在[x < 0]时发生。请帮帮我。

var Game = (function(window) {
  var canvas = document.getElementById("game"),
      ctx = canvas.getContext("2d");
  
  var SCREEN_WIDTH = window.innerWidth,
      SCREEN_HEIGHT = window.innerHeight;
  
  canvas.width = SCREEN_WIDTH;
  canvas.height = SCREEN_HEIGHT;
  
  var ROCK = "rock",
      PAPER = "paper",
      SCISSOR = "scissor";
  
  var BG_IMAGE = document.getElementById("bg");
  
  // this is the game area Radius
  var GAME_R = 500;
  
  var offsetX = 0,
      offsetY = 0;
  
  var player;
  
  // circle collision detection
  function checkCollision(x1, y1, r1, x2, y2, r2) {
    var x = x1-x2;
    var y = y1-y2;
    var d = Math.hypot(x, y);
    return d < r1 + r2;
  } 
  
  function start() {
    player = new Entity();
    addEventListener("mousemove", function(e) {
      var angle = Math.atan2(e.clientY - SCREEN_HEIGHT/2, e.clientX - SCREEN_WIDTH/2);
      player.setAngle(angle);
    }, true);
    animLoop();
  }
  
  function update() {
    offsetX = player.x - SCREEN_WIDTH/2;
    offsetY = player.y - SCREEN_HEIGHT/2;
    player.update();
  }
  
  function draw() {
    ctx.save();
    ctx.translate(-offsetX, -offsetY);
    
    // bg
    ctx.fillStyle = ctx.createPattern(BG_IMAGE, "repeat");
    ctx.fillRect(offsetX, offsetY, SCREEN_WIDTH, SCREEN_HEIGHT);
    
    // game area border
    ctx.beginPath();
    ctx.arc(0, 0, GAME_R, 0, Math.PI * 2);
    ctx.closePath();
    ctx.lineWidth = 5;
    ctx.strokeStyle = "red";
    ctx.stroke();
    
    // player
    player.draw();
    ctx.restore();
  }
  
  function gameLoop() {
    update();
    
    // here
    if(checkCollision(player.x, player.y, player.x, 0, 0, GAME_R)) {
      console.log("inside");
    } else {
      console.log("outside");
    }
    
    draw();
  }
  
  function animLoop() {
    window.requestAnimationFrame(animLoop);
    gameLoop();
  }
  
  // player
  function Entity() {
    var self = {
      x: 0,
      y: 0,
      r: 50,
      entityType: PAPER,
      angle: 0,
      speed: 5
    }
    
    self.setSpeed = function(speed) {
      this.speed = speed;
    }
    
    self.setAngle = function(angle) {
      this.angle = angle;
    }
    
    self.update = function() {
      this.x += this.speed * Math.cos(this.angle);
      this.y += this.speed * Math.sin(this.angle);
    }
    
    self.draw = function() {
      ctx.beginPath();
      ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
      ctx.closePath();
      ctx.fillStyle = "grey";
      ctx.fill();
      
      ctx.fillStyle = "#fff";
      ctx.font = "30px Arial";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.fillText(this.entityType, this.x, this.y);
    }
    
    return self;
  }
  
  start();
  
})(window);
<canvas id="game"></canvas>
<div style="display: none;">
  <img id="bg" src="https://i.imgur.com/9qjEwiz.png">
</div>
javascript canvas
1个回答
0
投票

这将检查内部圆是否位于外部圆内

 function checkCollision(cxInner, cyInner, rInner, cxOuter, cyOuter, rOuter) {
        return Math.sqrt(Math.pow(cxInner-cxOuter, 2) + Math.pow(cyInner-cyOuter, 2)) < rOuter - rInner;
 }

完整代码:

    var Game = (function(window) {
        var canvas = document.getElementById("game"),
            ctx = canvas.getContext("2d");

        var SCREEN_WIDTH = window.innerWidth,
            SCREEN_HEIGHT = window.innerHeight;

        canvas.width = SCREEN_WIDTH;
        canvas.height = SCREEN_HEIGHT;

        var ROCK = "rock",
            PAPER = "paper",
            SCISSOR = "scissor";

        var BG_IMAGE = document.getElementById("bg");

// this is the game area Radius
        var GAME_R = 500;

        var offsetX = 0,
            offsetY = 0;

        var player;

// circle collision detection
        function checkCollision(cxInner, cyInner, rInner, cxOuter, cyOuter, rOuter) {
            return Math.sqrt(Math.pow(cxInner-cxOuter, 2) + Math.pow(cyInner-cyOuter, 2)) < rOuter - rInner;
        }

        function start() {
            player = new Entity();
            addEventListener("mousemove", function(e) {
                var angle = Math.atan2(e.clientY - SCREEN_HEIGHT/2, e.clientX - SCREEN_WIDTH/2);
                player.setAngle(angle);
            }, true);
            animLoop();
        }

        function update() {
            offsetX = player.x - SCREEN_WIDTH/2;
            offsetY = player.y - SCREEN_HEIGHT/2;
            player.update();
        }

        function draw() {
            ctx.save();
            ctx.translate(-offsetX, -offsetY);

// bg
            ctx.fillStyle = ctx.createPattern(BG_IMAGE, "repeat");
            ctx.fillRect(offsetX, offsetY, SCREEN_WIDTH, SCREEN_HEIGHT);

// game area border
            ctx.beginPath();
            ctx.arc(0, 0, GAME_R, 0, Math.PI * 2);
            ctx.closePath();
            ctx.lineWidth = 5;
            ctx.strokeStyle = "red";
            ctx.stroke();

// player
            player.draw();
            ctx.restore();
        }

        function gameLoop() {
            update();

// here
            if(!checkCollision(player.x, player.y, player.r, 0, 0, GAME_R)) {
                player.back();
            }

            draw();
        }

        function animLoop() {
            window.requestAnimationFrame(animLoop);
            gameLoop();
        }

// player
        function Entity() {
            var self = {
                x: 0,
                y: 0,
                r: 50,
                entityType: PAPER,
                angle: 0,
                speed: 5
            };

            self.setSpeed = function(speed) {
                this.speed = speed;
            };

            self.setAngle = function(angle) {
                this.angle = angle;
            };

            self.update = function() {
                this.x += this.speed * Math.cos(this.angle);
                this.y += this.speed * Math.sin(this.angle);
            };
            self.back = function() {
                this.x -= this.speed * Math.cos(this.angle);
                this.y -= this.speed * Math.sin(this.angle);
            };

            self.draw = function() {
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
                ctx.closePath();
                ctx.fillStyle = "grey";
                ctx.fill();

                ctx.fillStyle = "#fff";
                ctx.font = "30px Arial";
                ctx.textAlign = "center";
                ctx.textBaseline = "middle";
                ctx.fillText(this.entityType, this.x, this.y);
            };

            return self;
        }

        start();

    })(window);
<canvas id="game"></canvas>
<div style="display: none;">
    <img id="bg" src="https://i.imgur.com/9qjEwiz.png">
</div>
© www.soinside.com 2019 - 2024. All rights reserved.