ZekeTheGeek
ZekeTheGeek

Reputation: 93

Setting Schedule in Custom Layer and Callback Not Firing

I am working on a simple reusable custom Layer in Cocos2d-html5 to manage a classic continuous background scroller. I initially created this in my main game layer, where I got it working, but when I moved it to its own BackgroundScroller Layer everything works except that the Schedule, whether set from the Main Layer or in a method inside of BackgroundScroller the function "scroll" never gets called.

What can cause a schedule to be registered but not fire? Is it a scope issue? Should I schedule the event on the BackgroundScroller or from within the code that is instantiating it?

onEnter: function(){
    var self = this;
    this._super();

    winSize = cc.director.getWinSize();
    centerPos = cc.p(winSize.width/2, winSize.height/2);

    bs = new BackgroundScroller("https://fbcdn-sphotos-f-a.akamaihd.net/hphotos-ak-xap1/v/t1.0-9/1014377_10153225997278888_209146662968373758_n.jpg?oh=287c045d5b8752581f8bdce968312c5c&oe=55BBA0B3&__gda__=1437658479_65b312f58967c3e1bd0ddb07260395cb", 
winSize, centerPos, BackgroundScroller.Speeds.MEDIUM_SLOW);
        this.addChild(bs);
        bs.startScroll();
    }

Here is the BackgrounScroller custom layer's code:

var BackgroundScroller = cc.Layer.extend( /** @lends cc.Layer# */ {
  _bgSprites: [],
/* This is the interesting bit */
  startScroll: function(scrollSpeed) {
    scrollSpeed = scrollSpeed || this.scrollSpeed;
    cc.log('Start Scroll:' + scrollSpeed);
    this.schedule(this.scroll, scrollSpeed);
    this.scheduleUpdate();
  },
  scroll: function(dt) {
    debugger;
    for (var i = 0; i < this._bgSprites.length; i++) {
      var bgSprite = this._bgSprites[i];
      bgSprite.setPositionX(bgSprite.getPosition().x - 1);
      this.checkIsOffEdge(bgSprite);
    }
  },
  ctor: function(bgSpriteOrCallbackFunction, winSize, centerPos, scrollSpeed) {
    this._super();

    this.scrollSpeed = scrollSpeed;
    this.winSize = winSize || cc.director.getWinSize();
    this.centerPos = centerPos || cc.p(this.winSize.width / 2, this.winSize.height / 2);

    if (typeof bgSpriteOrCallbackFunction == "function") {
      this.setupBackgroundSprite = bgSpriteOrCallbackFunction;
    } else {
      this.bgSpriteName = bgSpriteOrCallbackFunction;
    }

    this._bgSprites = [];
  },
  onEnter: function() {
    this.setupBackgroundSprites();
  },
  stopScroll: function() {
    this.pause();
  },
  /**
   * Sets up sprites with either the Background sprite name or the callback function specified in the ctor.
   * @returns void
   */
  setupBackgroundSprites: function() {
    cc.log("Setup background sprites");
    this.totalBgWidth = 0;
    var bgSpriteWidth = 0;
    while (this.totalBgWidth < this.winSize.width * 2) {
      var bgSprite = this.setupBackgroundSprite();
      this._bgSprites.push(bgSprite);
      bgSprite.setAnchorPoint(0, 0);
      bgSpriteWidth = bgSprite.getBoundingBox().width;
      this.addChild(bgSprite);
      this.totalBgWidth += bgSpriteWidth;
      this.maximumBgExtent = this.totalBgWidth - bgSpriteWidth;
      var posN = (this._bgSprites.length - 1) * bgSprite.getBoundingBox().width; // Stack them left to right
      bgSprite.setPositionX(posN);
    }

    cc.log("BgSprites in background sprites:" + this._bgSprites);
  },
  setupBackgroundSprite: function() {
    var bgSprite = new cc.Sprite(this.bgSpriteName)
    return bgSprite;
  },
  checkIsOffEdge: function(sprite) {
    var spriteBB = sprite.getBoundingBox();
    if (spriteBB.x + spriteBB.width < 0) {
      sprite.setPositionX(this.maximumBgExtent - 1);
    }
  }
});

BackgroundScroller.Speeds = {
  "SLOW": 0.5,
  "MEDIUM_SLOW": 0.005,
  "MEDIUM": 0.001,
  "MEDIUM_FAST": 0.0005,
  "FAST": 0.0001
};

Upvotes: 0

Views: 195

Answers (1)

ZekeTheGeek
ZekeTheGeek

Reputation: 93

I figured it out. I encapsulated everything but the schedule in the BackgroundScroller layer. In MainLayer I set the schedule and it calls "scroll" on the BackgroundScroller.

I'm still not sure why it wasn't working, but this makes sense--the parent layer is where all of this logic should be managed anyway.

Upvotes: 0

Related Questions