ChubbRck Posted June 13, 2014 Share Posted June 13, 2014 Hi there, I'm trying to zoom out the entire game world from the center.. unfortunately I see no method for the camera for zooming out so I'm scaling the game.world directly withthis.game.world.scale.setTo(0.5, 0.5);Unfortunately, this scales around the top left of the screen. I've tried setting the anchor on the game.world as well as the pivot to the center of the world or the center of the stage to no avail. Is it possible to achieve what I'm trying to do? Thanks for any thoughts - Nick Link to comment Share on other sites More sharing options...
lewster32 Posted June 14, 2014 Share Posted June 14, 2014 The camera doesn't support zooming natively right now - I'm afraid if you want this functionality you're going to have to code it yourself. It is of course possible but not without some understanding of the maths and techniques involved. You may want to Google for other frameworks that support this and have a go at replicating the way their cameras work, or wait for it to be supported in Phaser (which I'm sure it will eventually!). Phaser is influenced by Flixel, a Flash AS3 library which has advanced cameras, so maybe it could be interesting to work out how that works? Link to comment Share on other sites More sharing options...
ChubbRck Posted June 14, 2014 Author Share Posted June 14, 2014 Thanks for the thoughts, lewster - Do you know if it is possible to scale the world around the center point? I know cameras in Phaser don't support zooming yet, but as a workaround I was hoping to scale the entire game.world. I just can't figure out how to set its anchor, origin, pivot, or whichever is needed. Nick Link to comment Share on other sites More sharing options...
lewster32 Posted June 14, 2014 Share Posted June 14, 2014 I think you may be able to do something if, rather than using the camera, you used the world.pivot to move around your scene. Then technically scaling should also be centered on the pivot point. It's untested but it may work... Link to comment Share on other sites More sharing options...
lewster32 Posted June 14, 2014 Share Posted June 14, 2014 Eureka! This does actually work - example here: http://jsfiddle.net/lewster32/NMNJ7/ - added some rudimentary clipping too. CAVEAT: Until body alignment with pivot is fixed in Phaser, this method will not work with collision. The issue is that Phaser's body positioning does not take into account pivot correctly. yahiko 1 Link to comment Share on other sites More sharing options...
valueerror Posted September 6, 2014 Share Posted September 6, 2014 i can not manage to get the zoom out around the exact center point of the camera it has at the moment i invoke the zoom.. do you have an idea? i have a world with different objects.. most of the time the camera follows the object... when i zoom out i want the camera to zoom out from the objects coordinates.. it always zooms out from the upper left corner and that looks very bad.. thank you ! Link to comment Share on other sites More sharing options...
wayfinder Posted September 6, 2014 Share Posted September 6, 2014 What I do in update() is apply the zoom to world.scale and calculate the new position based on the object's world position. The non-offset part of the value is scaled with world.scale, but not the point of focus (camCenter = offset within the camera view of the object you want to follow). I tween this.worldScale and this takes care of everything else: var new = new Phaser.Point(this.math.interpolateFloat(this.lastCamPos.x, this.followedObject.x, this.camfollowfactor), this.math.interpolateFloat(this.lastCamPos.y, this.followedObject.y, this.camFollowFactor)); new.copy(this.lastCamPos); this.world.scale.setTo(this.worldScale); new.x = new.x * this.worldScale - this.camCenter.x; new.y = new.y * this.worldScale - this.camCenter.y; this.camera.setPosition(new.x, new.y); Link to comment Share on other sites More sharing options...
valueerror Posted September 6, 2014 Share Posted September 6, 2014 puhh.. thank you for your input.. unfortunately i can not make sense out of your code or apply it to mine... my camera jumps around and centers on whatever points it likes - just not the one point that was in the middle of the screen the moment i started the zoom... just out of interest.. what is the camfollowfactor and where to you define lastcampos ? Link to comment Share on other sites More sharing options...
wayfinder Posted September 6, 2014 Share Posted September 6, 2014 You should set camCenter to half your game width and height (or wherever in your view the object you are following is); lastCamPos is set right there in the code - you could probably do it with sprite.body.data.previousPosition as well. Cam follow factor is how much the camera lags behind, i currently have it set to 0.1 Link to comment Share on other sites More sharing options...
valueerror Posted September 7, 2014 Share Posted September 7, 2014 i just don't get it... i can't think straight anymore.. i deleted everything in the game to make a clean showcase http://test.xapient.net/phaser/springtest/indexzoom.html you can zoom in/out with the letters A and O and then grab the map with the mouse and move it around .. you will see that the camera zooms out from somewhere in the upper left corner and that this point constantly changes with the zoom level.. so the camera is moving around like crazy.. if you find some time to read the code (only one function is important where all the magic (not) happens) : i would very much appreciate it .. thank you! i just want the camera to constantly focus on the exact middle of the view.. i don't care if it goes out of bounds to do this... function updateLevelstatus(){ //desktop zoom if (game.input.keyboard.isDown(Phaser.Keyboard.A) && (mapSizeMaxCurrent < mapSizeMax)) {mapSizeMaxCurrent += 16;} else if (game.input.keyboard.isDown(Phaser.Keyboard.O) && (mapSizeMaxCurrent > worldwidth )) { mapSizeMaxCurrent -= 16; } mapSizeMaxCurrent = Phaser.Math.clamp(mapSizeMaxCurrent, worldwidth , mapSizeMax); //prevent odd scalefactors - set a minimum and maximum scale value worldScale = mapSizeMaxCurrent/mapSizeMax; if (mapSizeMaxCurrent < mapSizeMax ){ zoomed=true; stageGroup.scale.set(worldScale); currentBounds = new Phaser.Rectangle(0, 0, mapSizeX*worldScale, mapSizeY*worldScale); game.camera.bounds=currentBounds; // update bounds to the actual size for the camera so it cannot move outside }else{ currentBounds = new Phaser.Rectangle(0, 0, mapSizeX, mapSizeY); game.camera.bounds=currentBounds; // keep camera in bounds if (stageGroup.scale.x != 1) { zoomed=false; stageGroup.scale.set(1); } } if(zoomed === false){ } else { if(game.input.activePointer.isDown && !game.input.pointer2.isDown){ //move around the world if (oldcamera) { game.camera.x += oldcamera.x - game.input.activePointer.position.x; game.camera.y += oldcamera.y - game.input.activePointer.position.y; } oldcamera = game.input.activePointer.position.clone(); } else { oldcamera = null; } }} Link to comment Share on other sites More sharing options...
MorpheusZ Posted September 7, 2014 Share Posted September 7, 2014 Here's my function that zooms in/out on the mouse pointer's current location. Perhaps passing in the center of the world in your application could work?I'm adding all my sprites to a "scaler" group to help simulate zooming and I have an initial size of my world stored in this.mapWidth, this.mapHeight. Light.Game.prototype.zoom = function(delta) { var oldScale = this.scaler.scale.x; // We always scale both co-ordinates equally. var scale = oldScale + delta; // Don't zoom out if the whole world is visible (clip it right on the edge). scale = Math.max(scale, game.camera.view.width / this.mapWidth); scale = Math.max(scale, game.camera.view.height / this.mapHeight); var scaleCoef = scale / oldScale; var scaledMouseX = game.input.mousePointer.worldX * scaleCoef; var scaledMouseY = game.input.mousePointer.worldY * scaleCoef; var deltaMouseX = scaledMouseX - game.input.mousePointer.worldX; var deltaMouseY = scaledMouseY - game.input.mousePointer.worldY; this.scaler.scale.set(scale); game.world.width = scale * this.mapWidth; game.world.height = scale * this.mapHeight; game.camera.setBoundsToWorld(); game.camera.focusOnXY( game.camera.view.centerX + deltaMouseX, game.camera.view.centerY + deltaMouseY);}; Link to comment Share on other sites More sharing options...
wayfinder Posted September 7, 2014 Share Posted September 7, 2014 valueerror, your example doesn't work here! Link to comment Share on other sites More sharing options...
valueerror Posted September 7, 2014 Share Posted September 7, 2014 @wayfinder : what do you mean with "here" ? the link seems to work for me and zooming in and out too ? btw. thx for your contributions .. you helped me to figure out what i need to do.. i needed to store the actual camera center in a variable. the trick was to store its value relative to the current world scale size here is the code to zoom I/O and pan: variables explanation: worldwidth (canvas size x) mapSizeMaxCurrent (current size of the zoomed map in pixels - its always the smaller side of the map to avoid black bars later)mapSizeMax (initial size of the smaller side of the map)mapSizeX (map width)mapSizeY (map height)worldScale (current scale factor)function updateLevelstatus(){ // zoom in/out with a/o if (game.input.keyboard.isDown(Phaser.Keyboard.A) && (mapSizeMaxCurrent < mapSizeMax)) { mapSizeMaxCurrent += 32; } else if (game.input.keyboard.isDown(Phaser.Keyboard.O) && (mapSizeMaxCurrent > worldwidth )) { mapSizeMaxCurrent -= 32; } mapSizeMaxCurrent = Phaser.Math.clamp(mapSizeMaxCurrent, worldwidth , mapSizeMax); worldScale = mapSizeMaxCurrent/mapSizeMax; stageGroup.scale.set(worldScale); // scales my stageGroup (contains all objects that shouldbe scaled) if(game.input.activePointer.isDown && !game.input.pointer2.isDown){ //move around the world if (oldcamera) { game.camera.x += oldcamera.x - game.input.activePointer.position.x; game.camera.y += oldcamera.y - game.input.activePointer.position.y; } oldcamera = game.input.activePointer.position.clone(); // store current camera position (relative to the actual scale size of the world) rescalefactorx = mapSizeX / (mapSizeX * worldScale); // multiply by rescalefactor to get original world value rescalefactory = mapSizeY / (mapSizeY * worldScale); currentcamerapositionX = game.camera.view.centerX*rescalefactorx; currentcamerapositionY = game.camera.view.centerY*rescalefactory; } else { //center camera on the point that was in the center of the view atm the zooming started oldcamera = null; if (!currentcamerapositionX){ // if not set yet (never zoomed) currentcamerapositionX = game.camera.view.centerX; currentcamerapositionY = game.camera.view.centerY; } followx = currentcamerapositionX*worldScale; followy = currentcamerapositionY*worldScale; game.camera.focusOnXY(followx, followy); }}and here is the example demo: http://test.xapient.net/phaser/springtest/indexzoom.html Link to comment Share on other sites More sharing options...
0912403 Posted September 11, 2014 Share Posted September 11, 2014 Hi valueerror, the link doesn't work, i got this error: GET http://test.xapient.net/phaser/springtest/phaser.map 404 (Not Found) Could you please update it?I really need to see your demo. Thanks! Link to comment Share on other sites More sharing options...
valueerror Posted September 11, 2014 Share Posted September 11, 2014 this is browser related.. if you open the debug tools it will seach for a .map file to map everything in the minimized version..this is no showstopper at all.. just ignore it .. it has no influence on the demo.. zoom in or out with the letters A and O and then use the mouse to move the world around.. i just tried the link and it works as intended Link to comment Share on other sites More sharing options...
Oxide246 Posted July 19, 2015 Share Posted July 19, 2015 Edit: Worked it out. If I multiply my world x and y positions by (1 / myZoom) it works! e.g. for a zoom of .5 (zoomed out)Edit 2: This was not a good idea in the end, please read the posts below.newX = game.input.mousePointer.worldX * (1 / 0.5);newY = game.input.mousePointer.worldY * (1 / 0.5);Eureka! This does actually work - example here: http://jsfiddle.net/lewster32/NMNJ7/ - added some rudimentary clipping too. CAVEAT: Until body alignment with pivot is fixed in Phaser, this method will not work with collision. The issue is that Phaser's body positioning does not take into account pivot correctly. Hi lewster32, I've been attempting to write a kind of SimCity game. I'm successfully drawing roads and panning around the game area. Unlike your example here, I'm just panning with the camera, and not touching pivot. However, when I start trying to zoom, the gameworld position doesn't update, and the road draws in the wrong place. Is this to do with your "CAVEAT" above? Or are you aware of a fancy way to translate word position with the zoom factor? I've forked your fiddle here: http://jsfiddle.net/cvcqutgf/ and added mouse cursor debug; If you hover your mouse over the stage, and pan/zoom around, you'll see that the world co-ordinates don't update (If you were just to move the camera without pivot they would). However, like I said my issue is the co-ordinates when zooming. Are you able to shed any light on this for me? Cheers, Link to comment Share on other sites More sharing options...
Oxide246 Posted July 21, 2015 Share Posted July 21, 2015 Thanks NETANEL, I found the way I did it above was not great, and after some more research found this example on Stack Overflow: https://dl.dropboxusercontent.com/u/23574503/pixitests/index.html, Stack linkhttp://stackoverflow.com/questions/29035084/zoom-to-cursor-position-pixi-js I liked this for its simplicity and ended up implementing this way, using a group and not altering the world like you've suggested. But I did not touch the pivot. The only issue now is that I can drag the main group off the boundary of the world. But it's not that big a deal at this stage in my development. I'm really only at prototyping phase. If I like your suggested method (to be seen) I will implement it though. Link to comment Share on other sites More sharing options...
liakos1992 Posted September 30, 2016 Share Posted September 30, 2016 This code allows you to zoom out, then center the camera to a desired point. var zoomFactor = 0.5; var cameraFocusX = 100; var cameraFocusY = 200; game.world.scale.setTo(zoomFactor); game.camera.focusOnXY(cameraFocusX * game.world.scale.x, cameraFocuzY * game.world.scale.y); If you want to zoom out from the center, set var cameraFocusX = game.world.width / 2; var cameraFocusY = game.world.height / 2; EDIT: Have in mind that after you zoom in/out (scale up/down the world), sprite.collideWorldBounds = true; will not work correctly. Also, if you want to get mouse X, Y coordinates based on world, instead of var mouseWorldX = game.input.worldX; var mouseWorldY = game.input.worldY; you should use var mouseWorldX = game.input.worldX / game.world.scale.x; var mouseWorldY = game.input.worldY / game.world.scale.y; However, sprite.events.onInputOver.add(callback) will work correctly whatever the world scale samme 1 Link to comment Share on other sites More sharing options...
TheCodeCrafter Posted January 25, 2017 Share Posted January 25, 2017 Hey guys! Just digging around in the source code and I think I found this in Camera.js: scale: { enumerable: true, get: function () { return this.transform._scaleX; }, set: function (value) { this.transform._scaleX = value; this.transform._scaleY = value; this.transform.dirty = true; this.transform.updateCache(); } }, scaleX: { enumerable: true, get: function () { return this.transform._scaleX; }, set: function (value) { this.transform._scaleX = value; this.transform.dirty = true; this.transform.updateCache(); } }, But even though this doesn't range from a point. The camera itself is what is scaling, so whatever location it is at should be the place scaled. So how does that work, is this the solution to all of our problems? Let me know what you think, I can be an idiot sometimes and not notice crap. Link to comment Share on other sites More sharing options...
Bal Posted May 8, 2017 Share Posted May 8, 2017 On 6/14/2014 at 5:40 PM, lewster32 said: Eureka! This does actually work - example here: http://jsfiddle.net/lewster32/NMNJ7/ - added some rudimentary clipping too. CAVEAT: Until body alignment with pivot is fixed in Phaser, this method will not work with collision. The issue is that Phaser's body positioning does not take into account pivot correctly. Thanks @lewster32, i tried your idea and have some zooming working in the beginnings of a game. When might body alignment with pivot be fixed in Phaser, as i'll need collision detection. Or even better, when might native camera zooming appear in Phaser? Link to comment Share on other sites More sharing options...
Recommended Posts