cocos2d-xcollision-detectiongame-physicscocos2d-js

Cocos2d-js: effect on cocos2d-js application running on browser while a move from one application to another application


i was running parkour game given on cocos2d website on my browser. everything was working fine, but when i move from my browser to sublime text and returned to my browser, the running player start to show some unexpected behaviour, the player disappeared from its position and and after few second it fall on the ground and then start running again .whenever i move from one application to another it happens.

i don't why its happening. could some one tell me how to prevent this from happen?

here is the code for animation layer:-

       var AnimationLayer = cc.Layer.extend({
spriteSheet: null,
runningAction: null,
sprite: null,
space:null,
body:null,
shape:null,

ctor:function (space) {
    this._super();
    this.space = space;
    this.init();

    this._debugNode = cc.PhysicsDebugNode.create(this.space);
    this._debugNode.setVisible(false);
    // Parallax ratio and offset
    this.addChild(this._debugNode, 10);
},
init:function () {
    this._super();

    // create sprite sheet
    cc.spriteFrameCache.addSpriteFrames(res.runner_plist);
    this.spriteSheet = cc.SpriteBatchNode.create(res.runner_png);
    this.addChild(this.spriteSheet);


    // init runningAction
    var animFrames = [];
    for (var i = 0; i < 8; i++) {
        var str = "runner" + i + ".png";
        var frame = cc.spriteFrameCache.getSpriteFrame(str);
        animFrames.push(frame);
    }

    var animation = cc.Animation.create(animFrames, 0.1);
    this.runningAction = cc.RepeatForever.create(cc.Animate.create(animation));


    //create runner through physic engine
    this.sprite = cc.PhysicsSprite.create("#runner0.png");
    var contentSize = this.sprite.getContentSize();
    // init body
    this.body = new cp.Body(1, cp.momentForBox(1, contentSize.width, contentSize.height));
    this.body.p = cc.p(g_runnerStartX, g_groundHight + contentSize.height / 2);
    this.body.applyImpulse(cp.v(150, 0), cp.v(0, 0));//run speed
    this.space.addBody(this.body);
    //init shape
    this.shape = new cp.BoxShape(this.body, contentSize.width - 14, contentSize.height);
    this.space.addShape(this.shape);

    this.sprite.setBody(this.body);
    this.sprite.runAction(this.runningAction);

    this.spriteSheet.addChild(this.sprite);

    this.scheduleUpdate();
},

getEyeX:function () {
    return this.sprite.getPositionX() - g_runnerStartX;
}});

and this is the code for playScene.js:-

    var PlayScene = cc.Scene.extend({
space:null,
gameLayer:null,
// init space of chipmunk
initPhysics:function() {
    this.space = new cp.Space();
    // Gravity
    this.space.gravity = cp.v(0, -350);
    // set up Walls
    var wallBottom = new cp.SegmentShape(this.space.staticBody,
        cp.v(0, g_groundHight),// start point
        cp.v(4294967295, g_groundHight),// MAX INT:4294967295
        0);// thickness of wall
    this.space.addStaticShape(wallBottom);
},
onEnter:function () {
    this._super();
    this.initPhysics();



    this.gameLayer = cc.Layer.create();

    //add three layer in the right order
    this.gameLayer.addChild(new BackgroundLayer(), 0, TagOfLayer.background);
    this.gameLayer.addChild(new AnimationLayer(this.space), 0, TagOfLayer.Animation);
    this.addChild(this.gameLayer);
    this.addChild(new StatusLayer(), 0, TagOfLayer.Status);

    this.scheduleUpdate();

},
update:function (dt) {
    // chipmunk step
    this.space.step(dt);
    var animationLayer = this.gameLayer.getChildByTag(TagOfLayer.Animation);
    var eyeX = animationLayer.getEyeX();

    this.gameLayer.setPosition(cc.p(-eyeX,0));
}

});


Solution

  • Ok, this may or may not solve the issue some scenarios, but after looking at it profoundly, the biggest suspect seems to be a lack of steps in the calculations of Chipmunk when the framerate drops (which appears to happen when you resize or minimize/maximize the screen).

    The closest thing to a fix that I've found comes from a lead in this post in the forums, and which I've adapted it like this: where you have this.space.step(dt); in your update function, change it for the following:

    var timeWindow = 1/60; //replace by your configured FPS rate if it's not 60
    var steps = Math.ceil(dt / timeWindow);
    var i = 0;
    for (; i < steps; i++) {
      this.space.step(timeWindow);
    }
    

    This should ensure that even if your application drops below 60fps the physics simulation will be updated properly, and this problem should not happen anymore.