精灵未在画布上加载

时间:2015-08-11 20:44:21

标签: javascript html5 canvas sprite

我试图用精灵动画创建游戏,但我似乎无法同时加载动画精灵和画布。当画布加载时,控制台中没有错误,但我无法在画布上看到精灵。当我稍微改变代码时(例如在渲染函数中调用" Sprites()"),动画精灵会出现,但画布的其余部分是空白的。

以下是我认为错误所在的代码区域:

app.js

/*
    Sonic class creates the player's character, Sonic the Hedgehog
    Parameters -
        x and y are the player's initial coordinates
        sprites passes in a sprite object to add animation
        speed is the pace of the game based on level
*/
var Sonic = function(x, y) {
    // set initial sprite/image
    this.sprite = Sprites;

    this.x = x;
    this.y = y;

    // set initial score to 0
    this.score = 0;

    // set initial life count to 3
    this.lives = 3;

    // initialize sonic as alive
    this.alive === false;
};

/*
    Update sonic's sprite to give the appearance of movement
    Parameter - dt, the time delta between loops
*/
Sonic.prototype.update = function(dt) {

    // Sprites();

};

/*
    Draw the player character on the screen in canvas' context
*/
Sonic.prototype.render = function() {
    // ctx.drawImage(Resources.get(this.sprite), 30, 250);
};

// create new instance of sonic
var sonic = new Sonic(30, 250);

sprites.js

var Sprites = (function(global) {

    var sonicSprite,
        soniceSpriteImg;

    // update and render sprite at same speed as browser redraws
    function gameLoop() {
        window.requestAnimationFrame(gameLoop);
        ctx.clearRect(0, 0, 760, 608);
        sonicSprite.update();
        sonicSprite.render();
    }

    function sprite(options) {

        var obj = {},
            // current frame
            frameIndex = 0,
            // number of updates since current frame was displayed
            tickCount = 0,
            // number of updates until next frame should be displayed
            ticksPerFrame = options.ticksPerFrame || 0;
            // number of frames in sprite sheet
            numberOfFrames = options.numberOfFrames || 1;

        obj.context = options.context;  
        obj.width = options.width;
        obj.height = options.height;
        obj.image = options.image;

        obj.update = function() {
            tickCount += 1;

            // reset tickCount once it is surpasses ticks per frame
            if (tickCount > ticksPerFrame) {
                tickCount = 0;

                // increase frameIndex if it is less than number of frames
                if (frameIndex < numberOfFrames - 1) {
                    // go to next frame
                    frameIndex += 1;
                } else {
                    // reset frameIndex to loop if out of frames
                    frameIndex = 0;
                }
            }
        };

        obj.render = function() {
            // clear the canvas
            // obj.context.clearRect(0, 0, obj.width, obj.height);

            // draw animation
            obj.context.drawImage(
                obj.image,
                frameIndex * obj.width / numberOfFrames,
                0,
                obj.width / numberOfFrames,
                obj.height,
                0,
                0,
                obj.width / numberOfFrames,
                obj.height);
        };

        // obj.render();

        return obj;
    }

    sonicSpriteImg = new Image();

    sonicSprite = sprite({
        context: ctx,
        width: 408.8,
        height: 117,
        image: sonicSpriteImg,
        numberOfFrames: 4,
        ticksPerFrame: 3
    });

    // start game loop as soon as sprite sheet is loaded
    sonicSpriteImg.addEventListener("load", gameLoop);
    sonicSpriteImg.src = "images/sonicrunningsheet.png";
}());

这个项目的完整源代码在这里(请原谅杂乱的部分,这仍然在进行中)https://github.com/alexxisroxxanne/sonicvszombies

它的实时页面位于:http://alexxisroxxanne.github.io/sonicvszombies/

任何帮助将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:0)

在Sonic构造函数中,将this.sprite分配给Sprites IIFE的结果。

var Sonic = function(x, y) {
    // set initial sprite/image
    this.sprite = Sprites;
    ...

Sprites IIFE并没有返回任何东西,所以Sprites总是未定义的。 我想你想在那里返回sonicSpriteImg。

    ...
    sonicSpriteImg = new Image();

    sonicSprite = sprite({
        context: ctx,
        width: 408.8,
        height: 117,
        image: sonicSpriteImg,
        numberOfFrames: 4,
        ticksPerFrame: 3
    });

    // start game loop as soon as sprite sheet is loaded
    sonicSpriteImg.addEventListener("load", gameLoop);
    sonicSpriteImg.src = "images/sonicrunningsheet.png";

    return sonicSpriteImg;
}());

在Sonic渲染功能中,您可以从资源中获取精灵。资源仅在那里返回undefined。原因是因为this.sprite不是像其他对象(Zombie,Nyancat等)那样的img url,而是一个img对象。所以你不必从资源中获取它。

Sonic.prototype.render = function() {
    // ctx.drawImage(Resources.get(this.sprite), 30, 250);
    ctx.drawImage(this.sprite, 30, 250);
};

答案 1 :(得分:0)

当我将变量sonicSprite和sonicSpriteImg移动到Sprites函数之外并进入全局上下文时,我的问题得到修复,然后在app.js中调用sonicSprite.update();在Sonic.prototype.update()中并调用sonicSprite.render();在Sonic.prototype.render()