lash Posted February 15, 2016 Share Posted February 15, 2016 I have a bunch of sprites that are continuously tweening in a feather fall like movement: http://holbrook.no/tests/featherfall.html To this I need to add infinite side scroll. To avoid that potentially the camera value (theoretically) overflows, I need to yank the camera back periodically. To avoid that the sprites aren't yanked with it, I need to update their x-transformation, too,. I can't find any settings (like camera offset) that can adjust the transformation on the sprites individually, that can be applied on top of the tweening position. Any ideas how to do this? Link to comment Share on other sites More sharing options...
fillmoreb Posted February 16, 2016 Share Posted February 16, 2016 Are you trying to keep your feather-falling sprite fixed to the camera even when it's yanking back to the beginning of the world? If so, I would throw all those sprites into a group, and make that group fixed to camera. myFeatherFallGroup.fixedToCamera = true; Link to comment Share on other sites More sharing options...
lash Posted February 16, 2016 Author Share Posted February 16, 2016 No, I want the hearts to follow the scrolling, like this: http://www.holbrook.no/tests/featherfallscrolled.html In the above link, it's done by manually adding the camera offset x to every update callback of the tweens, which I suspect is more expensive than any already existing transform routine. Also, it's not perfect, as it glitches occasionally, as if sometimes the calculation isn't being made. Link to comment Share on other sites More sharing options...
fillmoreb Posted February 16, 2016 Share Posted February 16, 2016 Okay, I think I follow you. My approach would be: At the instant of the yank, find out exactly how many pixels back I'm going to yank. Let's say it's 500px just for fun. Then I would do this: var yankAmount = 500; for(var i = featherGroup.children.length - 1; i >= 0; i--){ featherGroup.children.x -= yankAmount; } This will instantly reposition the feathers back to the left side of their group. As long as you move them the same number of pixels as your yank, you shouldn't notice any problem. The advantage here is that rather than doing extra calculations on every update frame, you do it only every yank. Link to comment Share on other sites More sharing options...
lash Posted February 16, 2016 Author Share Posted February 16, 2016 But if one does that, the tween overwrites the yank afterwards, because it's still operating on the same coords as initially given. Therefore it's instantly yanked back. This is the issue at hand Link to comment Share on other sites More sharing options...
fillmoreb Posted February 16, 2016 Share Posted February 16, 2016 You beat me to it. I was just editing my last post to retract my shortsightedness. Here's my instinct. When a feather is launched, I would set a targetX on the sprite. I would then tween a property I invented like xOffset rather than x itself. Then, in the sprite's update loop, I would set x to targetX + offsetX. Then, in the loop I gave above, I would do featherGroup.children.targetX -= yankAmount; This should decouple the tween from the x position enough for things to work. Link to comment Share on other sites More sharing options...
lash Posted February 17, 2016 Author Share Posted February 17, 2016 Ah,I didn't think of the possibility of using arbitrary properties for tween. That's very useful. Based on your input I've made a 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). 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 = new CameraTweenGfx(game, startx, starty); game.add.existing(sprite); sprite.beginFill(color); sprite.drawRect(0, 0, size, size); sprite.endFill(); sprite.camera_offset_x = 0; game.add.tween(sprite).to({ tx: endx, ty: endy }, duration, null, true, 0, 0).onComplete.addOnce(function() { this.camera_offset_x = 0; }, sprite); } 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]); } Link to comment Share on other sites More sharing options...
Recommended Posts