【问题标题】:Sprites not loading on canvas精灵未加载到画布上
【发布时间】:2015-08-11 20:44:21
【问题描述】:

我正在尝试使用精灵动画创建游戏,但我似乎无法同时加载动画精灵和画布。当画布加载时,控制台中没有错误,但我看不到画布上的精灵。当我稍微更改代码时(例如,在渲染函数中调用“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/

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

【问题讨论】:

  • 欢迎来到 SO! :) 请在您的问题中添加您的代码,而不是链接到某个地方(可能是 404 --- 这是这里的规则,在最坏的情况下,这可以被标记为垃圾邮件并删除。)
  • 还尝试找出问题可能出在代码中的位置。大多数人不会阅读 1000 行代码。
  • 感谢您的提示,感谢您的建议! :)
  • 要筛选 Alexxis 的代码很多——对于 Stackoverflow 问题来说可能太多了!无论如何,听起来您需要知道何时执行您的绘图方法(以及它们是否无法执行)。您熟悉 F12 工具吗?您可以编码console.log('I just executed the sprite draw method'),该消息将显示在 F12 控制台窗口中。如果您的精灵绘图代码甚至正在执行,这将使您了解。将console.log 消息放在应用程序的重要位置,以查看浏览器如何执行您的代码。
  • 我为这里的代码量道歉 - 这是我的第一个问题,所以我还不完全熟悉如何格式化这些!最近没用那个技巧调试,谢谢提醒!我知道它在其他项目中有所帮助,我会尝试使用它来查明错误!

标签: javascript html canvas sprite


【解决方案1】:

在 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);
};

【讨论】:

  • 感谢您的回答!下次我编写一个期望值的函数时,这将非常有帮助,感谢您的帮助!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-04-28
    • 1970-01-01
    • 2014-04-27
    • 2012-10-11
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    相关资源
    最近更新 更多