无限滚动与Phaser中的补间

假设你有一堆补间这样运行:

http://holbrook.no/tests/featherfall.html

现在,你想在他们掉下来的时候水平地滚动它们。 通过更新相机x,他们开始移动,但最终,相机的x值将溢出。 此外,在此之前,可能要包装一些背景graphics。

因此,我们需要定期将摄像机拍回原来的位置。 但是,那么补间也会反弹。

因此,单个精灵需要在当前补间位置之上的变换值来校正摄像机重新定位。

我还没有在Phaser中find任何设置。 有任何想法吗?


编辑:

可以通过保留一个全局variables来跟踪相机的延伸,并将其手动添加到补间的onUpdateCallback,并将差异与下一个补间更改合并。 但是有时候这个破解似乎有点小问题,我怀疑它比使用内部变换variables要慢。 无论如何,结果如下:

http://holbrook.no/tests/featherfallscrolled.html

(基于来自http://www.html5gamedevs.com/topic/20539-infinite-scroll-wrapping-with-tweened-sprites/的input)

建议的解决方法:

我把它与一些事件信号结合起来,并提出了以下性能testing(请参阅下面的代码):

http://www.holbrook.no/tests/tweencamerasync.html

你可以通过一个整数得到参数c来改变计数,默认的计数是100.在我的笔记本电脑浏览器,它开始在2000年后的某个地方(Linux Mint 17,1,770 MHz CPU,3,5G RAM,火狐44.0 .2)在800x600px的canvas上。

基本上我向世界对象添加一个信号,将addAll与所有DisplayObject的x值相加。 然后它迭代游戏补间管理器来更新每个补间的自定义精灵的camera_offset_xvariables,用于这些精灵来计算x和中间补间tx属性(如果isTweened对于精灵是真的)。 camera_offset_x通过补间onComplete进行重置。

有趣的是,当没有补间时,game.tweens.getAll()函数是未定义的。 预期的行为将是返回0,不只是公然失败,不是?

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