我正在制作一个使用精灵表格的帆布游戏。
角色的尺寸为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 + "<br />");
}
// 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++;
}
}
// Right
if (game.keys[KEY.RIGHT]) {
player.direction = "R";
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 <= 0) { // Check Left Collision
player.x = 0;
}
// UP DOWN
if (player.y >= 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();
});
&#13;
body,
html {
position: relative;
}
canvas {
border: 1px solid black;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="700" height="500"></canvas>Use Arrow keys to move.
<p id="debug"><p>
&#13;
答案 0 :(得分:3)
问题似乎是你的player.x
是浮动的。这种方式很难说明像素完美的涂料。
player.x
上的drawImage()
轮次或使用velocity更新值时。
使用按位运算符,您只需执行:
player.x += player.velX | 0;