Ваш игрок пересекает границу на полпути, потому что координаты вашего игрока находятся в центре круга.Если любой из них равен нулю, это будет означать, что центр круга игрока будет вдоль оси.
Вместо этого вам следует проверить это.
if (player.x - player.radius < 0) { player.x = player.radius; }
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: black;
}
canvas {
display: block;
margin-top: 30px;
margin-left: auto;
margin-right: auto;
border: solid 1px white;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="application/javascript">
void function() {
"use strict";
var canvasWidth = 180;
var canvasHeight = 160;
function Player(x,y,r) {
this.x = x || 0;
this.y = y || 0;
this.r = r || 0;
this.up = false;
this.down = false;
this.left = false;
this.right = false;
}
Player.prototype = {
MOVE_SPEED: 3.0,
tick: function() {
// Movement updates
if (this.up) { this.y -= this.MOVE_SPEED; }
if (this.down) { this.y += this.MOVE_SPEED; }
if (this.left) { this.x -= this.MOVE_SPEED; }
if (this.right) { this.x += this.MOVE_SPEED; }
// Keep within canvas bounds
if (this.x - this.r < 0.0) {
this.x = this.r;
}
if (this.x + this.r > canvasWidth) {
this.x = canvasWidth - this.r;
}
if (this.y - this.r < 0.0) {
this.y = this.r;
}
if (this.y + this.r > canvasHeight) {
this.y = canvasHeight - this.r;
}
},
render: function(ctx) {
ctx.fillStyle = "darkred";
ctx.strokeStyle = "black";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(this.x + this.r,this.y);
ctx.arc(this.x,this.y,this.r,0.0,2.0 * Math.PI,false);
ctx.fill();
ctx.stroke();
}
};
var canvas = null;
var ctx = null;
var player = null;
onload = function() {
canvas = document.getElementById("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
ctx = canvas.getContext("2d");
player = new Player(90,80,10);
loop();
}
onkeydown = function(e) {
switch(e.key.toLowerCase()) {
case "w": player.up = true; break;
case "s": player.down = true; break;
case "a": player.left = true; break;
case "d": player.right = true; break;
}
}
onkeyup = function(e) {
switch(e.key.toLowerCase()) {
case "w": player.up = false; break;
case "s": player.down = false; break;
case "a": player.left = false; break;
case "d": player.right = false; break;
}
}
function loop() {
// Tick
player.tick();
// Render
ctx.fillStyle = "gray";
ctx.fillRect(0,0,canvasWidth,canvasHeight);
player.render(ctx);
//
requestAnimationFrame(loop);
}
}();
</script>
</body>
</html>