(Based on input from http://www.html5gamedevs.com/topic/20539-infinite-scroll-wrapping-with-tweened-sprites/)
A suggested workaround:
I coupled it with some event signals, and came up with the following test for performance (see below for code):
http://www.holbrook.no/tests/tweencamerasync.html
You can pass a whole number on get param c to change the count, default count is 100. On my laptop browser it starts acting up on after 2000 somewhere (Linux Mint 17,1, 770 MHz cpu, 3,5G ram, firefox 44.0.2) on a 800x600px canvas.
Basically I add a signal to the world object that adds the yank difference with addAll to all DisplayObjects' x values. Then it iterates the game tween manager to update each tweened custom sprite's camera_offset_x variable, used for those sprites to calculate the x together with the intermediary tweened tx property (IF the isTweened is true for the sprite). The camera_offset_x is reset with tween onComplete.
Funnily, the game.tweens.getAll() function is undefined when no tweens exist. Expected behaviour would be that it return 0 and not just blatantly fail, no?
var sprite = new Array();
var spawncount;
window.onload = function() {
game = new Phaser.Game(window.innerWidth, window.innerHeight, Phaser.AUTO, '', {create: create, update: update});
spawncount = parseInt(getQuery("c"));
if (!spawncount || spawncount == 0 || spawncount === undefined || spawncount === null)
spawncount = 100;
else if (spawncount > 5000)
spawncount = 5000;
};
CameraTweenGfx = function(game, x, y) {
Phaser.Graphics.call(this, game, x, y);
this.camera_offset_x = 0;
this.tx = x;
this.ty = y;
this.update = function() {
if (this.game.tweens.isTweening(this)) {
this.x = this.tx - this.camera_offset_x;
this.y = this.ty;
}
};
};
CameraTweenGfx.prototype = Object.create(Phaser.Graphics.prototype);
CameraTweenGfx.prototype.constructor = CameraTweenGfx;
function create() {
game.camera.yank = function() {
var params;
params = {
x: this.x,
y: this.y
};
this.setPosition(0, 0);
console.log("inside custom camera yank method");
this.onYank.dispatch(params);
};
game.camera.onYank = new Phaser.Signal();
game.camera.onYank.add(yankHandler, game.camera);
game.onCameraYank = new Phaser.Signal();
game.onCameraYank.add(yankHandler2, game);
game.world.setBounds(0, 0, window.innerWidth + 100, window.innerHeight);
for (var i = 0; i < spawncount; i++) {
var startx;
var starty;
var endx;
var endy;
var duration;
var color;
var size;
startx = game.rnd.integerInRange(10, game.width - 10);
starty = game.rnd.integerInRange(10, game.height - 10);
endx = game.rnd.integerInRange(10,game.width - 10);
endy = game.rnd.integerInRange(10, game.height - 10);
color = game.rnd.integerInRange(0, 16581375);
duration = game.rnd.integerInRange(100, 4000);
size = game.rnd.integerInRange(10, 20);
sprite[i] = new CameraTweenGfx(game, startx, starty);
game.add.existing(sprite[i]);
sprite[i].beginFill(color);
sprite[i].drawRect(0, 0, size, size);
sprite[i].endFill();
sprite[i].camera_offset_x = 0;
game.add.tween(sprite[i]).to({
tx: endx,
ty: endy
}, duration, null, true, 0, 0).onComplete.addOnce(function() {
this.camera_offset_x = 0;
}, sprite[i]);
}
poly = new Phaser.Polygon();
poly.setTo([
new Phaser.Point(0, game.height),
new Phaser.Point(game.width, game.height / 2),
new Phaser.Point(game.width, game.height),
]);
var graphics = game.add.graphics(0, 0);
graphics.beginFill(0x00FF00);
graphics.drawPolygon(poly.points);
graphics.endFill();
game.world.sendToBack(graphics);
}
function update() {
game.camera.x ++;
if (game.camera.x > 50)
game.camera.yank();
}
function yankHandler(params) {
console.log("inside camera onYank handler" + this.totalInView);
// doesn't do anything now, but maybe needed for other stuff maybe needed for other stuff
this.game.onCameraYank.dispatch(params);
}
function yankHandler2(params) {
console.log("inside game onCameraYank handler");
this.world.addAll("x", -50);
if (typeof this.tweens.getAll == "function") {
this.tweens.getAll().forEach(function(o) {
o.target.camera_offset_x += params.x;
});
}
}
// naughtly stolen from stackoverflow.com/questions/831030/how-to-get-get-request-parameters-in-javascript
function getQuery(name){
if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
return decodeURIComponent(name[1]);
}