저는 캔버스 태그를 사용하여 간단한 자바 스크립트 기반 게임을 진행하고 있습니다. 게임의 일환으로, 화면에 등장하는 캐릭터와 관련된 애니메이션이 포함 된 몇 개의 큰 스프라이트 시트 (예 : 2816x768 및 4096x4864)가 있습니다. 게임이 시작되면 게임에는 단순히 캐릭터의 유휴 애니메이션이 재생됩니다. 사용자가 공간을 누르면, 전적으로 다른 때로부터 다른 애니메이션을 재생하기 시작합니다.Chrome에서 처음으로 큰 이미지를 그리는 데 약간의 지연이 있음
는 사용자로부터 1.5 초 지연이Stage.prototype.loadImage = function(src)
{
var image = new Image();
this.incAssets();
var stage = this;
image.onload = function()
{
stage.decAssets();
}
image.src = src;
return image;
}
문제가된다 : 여기
Sprite.prototype.drawFrame = function(x, y)
{
ctx.drawImage(this.image,
x*this.width, y*this.height,
this.width, this.height,
this.position[0], this.position[1],
this.width, this.height);
};
그리고 이미지를로드하는 코드입니다 : 여기
는 스프라이트를 그리는 코드는 새 스프라이트 시트의 프레임이 실제로 그려지는 공간을 누른다. 이것은 한 번만 수행되며 다음 애니메이션의 매끄러움에 영향을 미치지 않습니다. 이미 스프라이트 시트가new Image
을 사용하여 미리로드되어 있고 게임이 모든 해당 image.onload 이벤트가 시작될 때까지 시작되지 않으므로 브라우저가로드 할 때까지 기다리지 않고 있음을 알 수 있습니다. Chrome 17.0에서 디버거를 사용하여 JavaScript를 단계별 실행하고
drawImage
호출에 대한 지연을 컨텍스트에서 좁혔습니다. 가장 불편한 점은 Firefox 10.0.2에는이 지연이 없으므로 Chrome과 관련된 문제입니다. 그것은 게임 플레이에 매우 혼란 스럽습니다.
내가 뭘 잘못하고 있니? Chrome에서이 지연을 줄일 수 있습니까?
편집 : 피터 위 샤트 (Peter Wishart)가 제안한대로로드하자마자 다음 프레임 전체를 그려 보았습니다.하지만 그 영향은 미미했습니다.
Stage.prototype.loadImage = function(src)
{
var image = new Image();
this.incAssets();
var stage = this;
image.onload = function()
{
ctx.drawImage(image, 0, 0);
stage.decAssets();
}
image.src = src;
return image;
};
이 너무 효과가 없었다 : 나는 또한 다음과 같이 loadImage
를 수정했습니다.
사실 솔루션을 찾았지만 대단히 비효율적입니다. 크롬이 해독 된 후 이미지 메모리로 똑똑한 작업을하려고했을 수도 있습니다. 이미지가 오래 동안 사용되지 않고 다시 추측되는 경우 Chrome은 메모리에서 디코딩 된 데이터를 삭제하고 다시 필요할 경우 다시 가져옵니다. 일반적으로 디코딩 프로세스에는 눈에 띄지 않는 시간이 걸리지 만 큰 이미지를 사용하면 성능이 크게 떨어집니다. 이것을 사용하여 draw loop를 바 꾸었습니다 :
function draw()
{
var currentTime = new Date().getTime();
var deltaTime = currentTime - lastTime;
lastTime = currentTime;
var dt = deltaTime/1000.0;
// The hack that keeps all decoded image data in memory is as following.
if (this.stage.nextStage != undefined)
this.stage.nextStage.draw(0); // The 0 here means the animations advance by 0 milliseconds, thereby keeping the state static.
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
if (stage != undefined && stage.loaded)
{
stage.draw(dt);
}
}
이 솔루션은 효과가 있지만, 말했듯이 이것은 끔찍한 낭비처럼 보입니다. 디코딩 된 데이터가 Chrome에서 오래되지 않도록하기 위해 다음 애니메이션 세트의 전체 프레임을 그려야합니다.
이 전략에 비해 덜 낭비적이고 덜 해킹 된 대안이 있습니까?