在JavaScript中正确显示帧

在JavaScript中正确显示帧,javascript,Javascript,好的,我正在用JavaScript开发一个游戏。我在不同的JavaScript文件中组织了游戏的所有部分。这是Player.js文件,每次我在浏览器中运行它(当然是从html文件运行),我都会遇到这样一个问题:Player对象从图像闪烁到透明矩形:代码如下: function Player() { this.frames = []; this.right = true; this.currentFrame = 0; this.currentAction = "WALKING"; this.ima

好的,我正在用JavaScript开发一个游戏。我在不同的JavaScript文件中组织了游戏的所有部分。这是Player.js文件,每次我在浏览器中运行它(当然是从html文件运行),我都会遇到这样一个问题:Player对象从图像闪烁到透明矩形:代码如下:

function Player() {
this.frames = [];
this.right = true;
this.currentFrame = 0;
this.currentAction = "WALKING";
this.image = new Image();
this.x = 0;
this.y = 0;

this.setPosition = function(x, y) {
    this.x = x;
    this.y = y;
};
this.setVector = function(x, y) {
    this.x += x;
    this.y += y;
};
this.setAction = function(action) {
    this.currentAction = action;
};
this.setRight = function(bool) {
    this.right = bool;
}
this.draw = function(context) {
    if(this.right == true) {
        if(this.currentAction == "WALKING") {
            this.frames = [ "res/playerRight.png" ];
        }
    } else if(this.right == false) {
        if(this.currentAction == "WALKING") {
            this.frames = [ "res/playerLeft.png" ];
        }
    }
    if(this.currentFrame < this.frames.length) {
        this.currentFrame += 1;
        this.image.src = this.frames[this.currentFrame - 1];
        context.drawImage(this.image, this.x,
            this.y, 32, 32);
    } else {
        this.currentFrame = 0;
    }
};
函数播放器(){
this.frames=[];
这是正确的;
此.currentFrame=0;
this.currentAction=“WALKING”;
this.image=新图像();
这个.x=0;
这个。y=0;
this.setPosition=函数(x,y){
这个.x=x;
这个。y=y;
};
this.setVector=函数(x,y){
这个.x+=x;
这个.y+=y;
};
this.setAction=函数(操作){
这个.currentAction=动作;
};
this.setRight=函数(bool){
this.right=bool;
}
this.draw=函数(上下文){
if(this.right==true){
if(this.currentAction==“行走”){
this.frames=[“res/playerRight.png”];
}
}else if(this.right==false){
if(this.currentAction==“行走”){
this.frames=[“res/playerLeft.png”];
}
}
if(this.currentFrame
}

以下是它的一些图像:

您如何预加载所有图像,并根据您的情况选择正确的图像。当前,每次设置源时,图像都会重新加载,并且在准备就绪之前绘制图像

// you can improve this part for your needs
var image1Loaded = false;
var image2Loaded = false;

this.preLoadImages = function (){
    this.image1.onload = function (){
         image1Loaded = true;
    }
    this.image2.onload = function (){
         image2Loaded = true;
    }
    this.image1.src = "res/playerRight.png";
    this.image2.src = "res/playerLeft.png";
}
现在,您可以在绘制方法中直接使用图像:

this.draw = function(context) {
    var currentImage = "image1";
    if(this.right == true) {
        if(this.currentAction == "WALKING") {
            currentImage = "image1";
        }
    } else if(this.right == false) {
        if(this.currentAction == "WALKING") {
             currentImage = "image2";
        }
    }
    if(this.currentFrame < this.frames.length) {
        this.currentFrame += 1;
        var image = this[currentImage];
        context.drawImage(image, this.x,
            this.y, 32, 32);
    } else {
        this.currentFrame = 0;
    }
};
this.draw=函数(上下文){
var currentImage=“image1”;
if(this.right==true){
if(this.currentAction==“行走”){
currentImage=“image1”;
}
}else if(this.right==false){
if(this.currentAction==“行走”){
currentImage=“image2”;
}
}
if(this.currentFrame
在使用图像在画布上绘制之前,请确保已加载图像

if(this.currentFrame < this.frames.length) {
    this.currentFrame += 1;
    context.drawImage(); // <---------------- draw an image
} else {
    this.currentFrame = 0; // <-------------- draw nothing!
}
结果:闪烁!如果帧长为2,它将闪烁33%的时间,如果帧长为3,它将闪烁25%的时间等

正确的处理方法是:

this.currentFrame += 1;
if(this.currentFrame >= this.frames.length) {
    this.currentFrame = 0;
}
this.image.src = this.frames[this.currentFrame]; // **
context.drawImage();

// **note: no need for -1 because currentFrame here is always
//         less than frame.length
或者,如果你是数学爱好者:

this.currentFrame = (this.currentFrame + 1) % this.frames.length;
this.image.src = this.frames[this.currentFrame];
context.drawImage();

这可能是因为加载图像时图像未准备就绪。图像已加载,如果对象加载图像本身,则图像将自动加载,因为主javascript文件调用该对象。如果是在图像未加载的情况下,然后图像将根本不显示。@UnhandyFir9:如果图像未加载,浏览器将下载图像并显示它,这就是为什么您会看到闪烁-浏览器需要绘制一些东西,但它仍在等待图像文件从网络到达。@slebetman图像不在线,它是本地的。我明白你的意思,但我认为闪烁与帧速率有关:在setInterval()处,我有setInterval(draw,1000/5);我把它改为setInterval(draw,1000/30);它闪烁得更快。等等,这部分毫无意义:
this.frames=[“res/playerRight.png”]
。为什么要创建一个只有一个元素的数组?图像已预加载。这就是为什么它会显示在屏幕上。我知道Javascript对象是如何工作的,我以前从未使用过一系列图像源,但我见过有人这样做。我不记得是谁,也不记得怎么做了。我明白你的意思,但你在代码中使用了这个:
this.image.src='…'
这会再次重新加载你的图像,这就是为什么你的图像不会显示的原因。我制作一个图像数组怎么样(),并在我调用它们之前分别设置源。这行吗?非常感谢!我还没有完全尝试过这个,但我读了你说的,我修改了代码,它工作时没有闪烁。非常感谢!
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
this.image.src = this.frames[this.currentFrame];
context.drawImage();