Canvas drawImage被1 Pixel莫名其妙地抵消

我正在制作一个使用精灵表格的帆布游戏。
角色的尺寸为64px宽,128px高,每个动画10帧。
因此,单个动画的总宽度为640px宽,128px高。
但是,当我使用以下代码时,动画偏移1px,有时在按住移动键时闪烁。

player.width = 64; player.height = 128; player.x = canvas.width / 2; player.y = canvas.height / 2; ctx.drawImage( LoadedImages.player_sprite, 64, // This is offset by 1px when moving. 63px fixes it. 128, player.width, player.height, player.x, player.y, player.width, player.height ); 

这是发生了什么的图片:
该死的
将宽度更改为63似乎可以解决问题,但它并不能解释为什么它首先要做到这一点。

Codepen上提供完整代码
http://codepen.io/Codewoofy/pen/QNGLNj
雪碧表:
哦

完整代码:

 var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; window.requestAnimationFrame = requestAnimationFrame; // jQuery Objects var $canvas = $("#canvas"); var $debug = $("#debug"); var KEY = { W: 1, UP: 38, LEFT: 39, RIGHT: 37, SPACE: 32, SHIFT: 16 }; var COLOR = { DARKRED: "#9C1E33", WHITE: "#FFFFFF" } var MESSAGE = { UNDEFINED: "", PRELOAD_ATTEMPT: "Attempting to preload: ", ERROR_IMAGE_PRELOAD: "Unable to preload images.", SUCCESS_IMAGE_PRELOAD: "Images successfully preloaded." } // Images var Images = { player_sprite: "http://h.dropcanvas.com/30npe/Talia-Sheet-Fix.png", main_background: "http://h.dropcanvas.com/9kgs1/background_main.png" } var LoadedImages = {}; // Dictionaries. var game = {}; game.enviroment = {}; game.canvas = $canvas[0]; game.canvas.height = 500; game.canvas.width = 700; var ctx = game.canvas.getContext('2d'); var player = {}; // Debug game.debug = function(msg) { if (msg == "") msg = MESSAGE.UNDEFINED; $debug.prepend(msg + "
"); } // Preloader. game.loadImages = function() { LoadedImages = {}; Object.keys(Images).forEach(function(path) { game.debug(MESSAGE.PRELOAD_ATTEMPT + path); var img = new Image; img.onload = function() { LoadedImages[path] = img; if (Object.keys(LoadedImages).length == Object.keys(Images).length) { game.onImagesLoaded(); } } img.onerror = function() { game.onFailedPreload(); } img.src = Images[path]; }); } game.onFailedPreload = function() { game.debug(MESSAGE.ERROR_IMAGE_PRELOAD); } game.onImagesLoaded = function() { game.debug(MESSAGE.SUCCESS_IMAGE_PRELOAD); game.game_update(); } game.onLoad = function() { // Game settings game.keys = []; game.running = false; game.lastUpdate = 0; // Enviroment game.enviroment.gravity = 0.5; game.enviroment.friction = 0.9; // Player settings player.name = "Talia"; player.color = COLOR.DARKRED; player.direction = 'L'; player.width = 64; player.height = 128; player.speed = 4; player.walkspeed = 4; player.sprintspeed = 10; player.jumping = false; player.animation_frame = 0; player.velX = 0; player.velY = 0; player.x = 0; player.y = 0; // Player Stats player.health = 100; player.mana = 100; player.maxhealth = 100; player.maxmana = 100; game.loadImages(); } /* Update the game every frame */ game.game_update = function() { // Sprint if (game.keys[KEY.SHIFT]) { console.log(LoadedImages); player.speed = player.sprintspeed; } else { player.speed = player.walkspeed; } // Jump if (game.keys[KEY.UP] || game.keys[KEY.SPACE]) { if (!player.jumping) { player.jumping = true; player.velY = -player.walkspeed * 2; } } // Left if (game.keys[KEY.LEFT]) { player.direction = "L"; if (player.velX -player.speed) { player.velX--; } } // Gravity and Friction player.velX *= game.enviroment.friction; player.velY += game.enviroment.gravity; player.x += player.velX; player.y += player.velY; // Collisions // LEFT RIGHT if (player.x >= game.canvas.width - player.width) { // Check Right Collision player.x = game.canvas.width - player.width; } else if (player.x = game.canvas.height - player.height) { player.y = game.canvas.height - player.height; player.jumping = false; } // Draw Objects game.draw_background(); game.draw_player(); // Request next animation frame requestAnimationFrame(game.game_update); } game.draw_player = function() { ctx.beginPath(); ctx.drawImage(LoadedImages.player_sprite, 64, 128, player.width, player.height, player.x, player.y, player.width, player.height); /* if (player.direction == "R") { ctx.drawImage(LoadedImages.player_sprite, 65, 128, player.width, player.height, player.x, player.y, player.width, player.height); } else if (player.direction == "L") { ctx.drawImage(LoadedImages.player_sprite, 63, 0, player.width, player.height, player.x, player.y, player.width, player.height); } */ ctx.closePath(); } game.draw_background = function() { ctx.beginPath(); ctx.clearRect(0, 0, game.canvas.width, game.canvas.height); ctx.closePath(); } game.draw_UI = function() { ctx.beginPath(); ctx.closePath(); } /* Listeners */ document.body.addEventListener("keydown", function(e) { game.keys[e.keyCode] = true; }); document.body.addEventListener("keyup", function(e) { game.keys[e.keyCode] = false; }); /* Load Game */ window.addEventListener("load", function() { game.onLoad(); });
 body, html { position: relative; } canvas { border: 1px solid black; } 
  Use Arrow keys to move. 

问题似乎是你的player.x是一个浮动。 这种方式很难说明像素完美的涂料。

drawImage()上的圆形player.x或使用velocity更新值时。

使用按位运算符,您可以简单地执行:

player.x += player.velX | 0;