简体   繁体   中英

Javascript make circle hit canvas borders properly

I'm currently working on a little game but I can't get the circle to hit the left and top canvas border properly. It hits the right and the bottom side correctly.

The circle can be moved with WASD and must hit all borders of the canvas properly

This is the code: http://jsfiddle.net/tumy8kbh/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JS Game</title>
    <link rel="stylesheet" href="css/style.css" type="text/css" />
    <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
</head>
<body>

<canvas id="myCanvas" width="1200" height="800"></canvas>

<script>
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    var dx = 2;
    var dy = -2;
    var playerRadius = 80;
    var playerX = (canvas.width-playerRadius)/2;
    var playerY = (canvas.height-playerRadius);
    var rightPressed = false;
    var leftPressed = false;
    var upPressed = false;
    var downPressed = false;

    document.addEventListener("keydown", keyDownHandler, false);
    document.addEventListener("keyup", keyUpHandler, false);

    function keyDownHandler(e) {
        if(e.keyCode == 87) {
            upPressed = true;
        }
        else if(e.keyCode == 83) {
            downPressed = true;
        }
        else if(e.keyCode == 68) {
            rightPressed = true;
        }
        else if(e.keyCode == 65) {
            leftPressed = true;
        }
    }
    function keyUpHandler(e) {
        if(e.keyCode == 87) {
            upPressed = false;
        }
        else if(e.keyCode == 83) {
            downPressed = false;
        }
        else if(e.keyCode == 68) {
            rightPressed = false;
        }
        else if(e.keyCode == 65) {
            leftPressed = false;
        }
    }

    function drawPlayer(){
        ctx.beginPath();
        ctx.arc(playerX, playerY, playerRadius, 0, Math.PI*2);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
    }

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

        if(rightPressed && playerX < canvas.width-playerRadius) {
            playerX += 7;
        }
        else if(leftPressed && (playerX - playerRadius) > 0) {
            playerX -= 7;
        }
        else if(upPressed && (playerY - playerRadius) > 0) {
            playerY -= 7;
        }
        else if(downPressed && playerY < canvas.height-playerRadius) {
            playerY += 7;
        }

        if(playerX >= canvas.width){
            leftPressed = false;
        }
    }

    setInterval(draw, 10);

</script>


</body>
</html>

If you need some more info please say so.

It has to do with the way you check if the ball can move. you check if X - radius > 0, then move left by 7. if the ball is 1 pixel away from the left edge, it can move, but it will end up 6 pixels off to the left. after calculating the new X position, check again that X - radius isn't LESS than 0 ... adjust X accordingly ... you'll need to do the same for all directions (bottom and right will stop working if you fix top and left and move to top/left then bottom right – Jaromanda X

Sample code: even though you figured it out from the comment

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

    if(rightPressed && playerX < canvas.width-playerRadius) {
        playerX += 7;
        if (playerX > canvas.width-playerRadius) {
            playerX = canvas.width-playerRadius;
        }
    }
    else if(leftPressed && (playerX - playerRadius) > 0) {
        playerX -= 7;
        if (playerX - playerRadius < 0) {
            playerX = playerRadius;
        }
    }
    else if(upPressed && (playerY - playerRadius) > 0) {
        playerY -= 7;
        if (playerY - playerRadius < 0) {
            playerY = playerRadius;
        }
    }
    else if(downPressed && playerY < canvas.height-playerRadius) {
        playerY += 7;
        if (playerY > canvas.height-playerRadius) {
            playerY = canvas.height-playerRadius;
        }
    }
}

This is not the most efficient way of dealing with it, but it shows the problem and how to fix it (I think)

There may be slight inaccuracies (you may need to +/- 1 in some of the "fixups" - I didn't check properly

You don't need a setInterval with true and false vars for this type of task, you could refresh the scene in every keydown event. I've modified your code, here you have:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var playerRadius = 80;
var playerX = (canvas.width - playerRadius) / 2;
var playerY = (canvas.height - playerRadius);

document.addEventListener("keydown", keyDownHandler, false);

var moves = {
  87: {x: 0, y: -7},
  83: {x: 0, y: 7},
  68: {x: 7, y: 0},
  65: {x: -7, y: 0}
};

function keyDownHandler(e) {

  if( moves.hasOwnProperty(e.keyCode) ) {

    playerX += moves[e.keyCode].x;
    playerY += moves[e.keyCode].y;

    if(playerX < playerRadius) playerX = playerRadius;
    if(playerX > canvas.width - playerRadius) playerX = canvas.width - playerRadius;
    if(playerY < playerRadius) playerY = playerRadius;
    if(playerY > canvas.height - playerRadius) playerY = canvas.height - playerRadius;

    drawPlayer();

  }

}

function drawPlayer(){
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(playerX, playerY, playerRadius, 0, Math.PI*2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
}

drawPlayer();

jsfiddle

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