Jump to content

melonjs zooming and panning


Anna
 Share

Recommended Posts

Hi,

Yes, zooming and panning are just transformation functions. This can be done by carefully controlling the renderer matrix at the correct points in your scene hierarchy.

For example, if you have a HUD element in your scene, you probably don't want the zoom function to affect it. If you use a Container element that is a sibling of the HUD and apply your transformations to that container, then everything inside of it will inherit those transformations. Scale/translate the renderer at the top of the Container's draw method, draw all of its children, and reset the transformation matrix on the way out of the draw method.

Something like that, anyway. It's actually incredibly simple.

Link to comment
Share on other sites

it's actually as simple as applying any transformation to a container, that would be in this case the "world" container, or a child container if you want  (as @parasyte was saying) split the level itself from the HUD.

 

me.Container, extends me.Renderable, and therefore has the following property http://melonjs.github.io/melonJS/docs/me.Renderable.html#currentTransform

Link to comment
Share on other sites

there is an example that add a zooming effect to the viewport here :

https://github.com/melonjs/melonJS/issues/399

but it then zoom literally everything.  As we were saying before the same can be done to a me.Container, as they both implement the currentTransform property : http://melonjs.github.io/melonJS/docs/me.Renderable.html#currentTransform

it's basically a matrix object, so you you can get crazy as much as you want with it : http://melonjs.github.io/melonJS/docs/me.Matrix2d.html

 

 

 

Link to comment
Share on other sites

  • 1 month later...

Hi, if I do it like described in your example:

keyPressed: function (action /*, keyCode, edge */) {
        
        if (action === "add") {
            this.scale(+0.02);
            return;
        }

        if (action === "substract") {
            this.scale(-0.02);
            return;
        }
},

scale: function(scale) {
        game.data.scale += scale;
        game.data.scale = game.data.scale.round(2);

        var viewport = me.game.viewport;
        viewport.currentTransform.translate(
            viewport.width * viewport.anchorPoint.x,
            viewport.height * viewport.anchorPoint.y
        );

        viewport.currentTransform.scale(game.data.scale);
        viewport.currentTransform.translate(
            -viewport.width * viewport.anchorPoint.x,
            -viewport.height * viewport.anchorPoint.y
        );
    },

It looks like this:

58a3191e977c2_Screenshot(1).png.9b61108cf30ecc411a342b9f273ed797.png

Link to comment
Share on other sites

  • 1 month later...

I needed the zoom as well today and came across this post. I copied in your code above and the plan didn't really work right away....simple quick fix for me was to use a constant value of 1.02 for zoom out and .98 for zoom in.

Seems like, from the partial code above, your idea is to keep a scale variable which you are incrementing and then applying. Which doesnt seem correct becuase [viewport.currentTransform.scale(game.data.scale) ] doesn't set a scale value it just multiplies the current values in the transform matrix.

Hopefully that helps....maybe not. 

 

 

Link to comment
Share on other sites

1 hour ago, chris.daniel said:

[viewport.currentTransform.scale(game.data.scale) ] doesn't set a scale value it just multiplies the current values in the transform matrix.

 

 

indeed,  our scale function (as for all matrix functions) follows the standard one :  https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale

Link to comment
Share on other sites

  • 5 months later...

@obiot @Parasyte

My viewport.move() and viewport.moveTo() functions aren't working.

 Correct me if I'm wrong, but after looking at the Melon 2.1.1 me.Viewport code (haven't upgraded yet), it seems if I follow the player: 

me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH); // set inside the player entity class

the follow function in melon sets this.target to the player, then calls this.updateTarget(), which is called on each frame, which sets this._followH(this.target), this._followV(this.target).

Therefore it's constantly overwriting any coordinates you set in viewport.moveTo(). Is the idea that I somehow set this.target = null, then move the camera, then reset viewport.follow back on the player?

Like:

me.game.viewport.follow(null, null);
viewport.moveTo(100, 100); // I'll add a timer on this to slowly pan
me.game.viewport.follow(player.pos, me.game.viewport.AXIS.BOTH);

 

Link to comment
Share on other sites

 

Correct, if the entity the camera is following is constantly moving, calling moveTo won't basically have any effect....  but calling `me.game.viewport.follow(null, null)`; won't work as the method won't assign anything if the give first argument is not an instance of a renderable or a vector object.

unfortunately we do not have a unfollow() method (i see it could be usefull though), but as a hack you can manually unassign the private target property by doing `me.game.viewport.target = undefined;`

that should do the trick, and you can then move the viewport where you want.

Link to comment
Share on other sites

@obiot lol I already tried that exact code. 

I'm trying to pan the view (camera) across to a certain location of interest, slowly, for beautiful cinematics.

To do this, I've tried using viewport.moveTo(x, y); at an interval.

The problem is on the initial call of moveTo - it sets the viewport at the location of the player, but the viewport isn't centered on the player, rather it's top left is the location of the player.

To fix this I added

            var x = playerMoveCoords.x - viewport.width/2;
            var y = playerMoveCoords.y - viewport.height/2;

It's still a bit jerky though. Any thoughts?


			var viewport = me.game.viewport;
			viewport.unfollow();
			var playerCoords = $.extend({}, game.state.getPlayer().coordinates());
			var playerMoveCoords = $.extend({}, game.state.getPlayer().coordinates());
			var newLocX = playerCoords.x += 200;
			var newLocY = playerCoords.y += 200;
			var x = playerMoveCoords.x - viewport.width/2;
			var y = playerMoveCoords.y - viewport.height/2;;

			var myInt = me.timer.setInterval(function() {

				if (x < newLocX) {
					x++;
				} else {
					x--;
				}
				if (y < newLocY) {
					y++;
				} else {
					y--;
				}

				viewport.moveTo(x, y);

				if (x === newLocX && y === newLocY) {
					me.timer.clearInterval(myInt);
					myInt = null;
				}
			}, 50);

 

Link to comment
Share on other sites

  • 2 weeks later...

I have some really old code that does non-linear interpolations (tweening) between camera positions. Some of it should still be usable. You can see it in action on the Neverwell Moor title screen, and the code is available here: https://github.com/blipjoy/nm-prototype/blob/gh-pages/js/objects/screens.js#L349-L384 Maybe it will help you out.

Link to comment
Share on other sites

@Growler I actually wrote a crazy bit of logic that can animate tile layers for that... Each frame is on its own layer, and the animation just cycles the layer visibility. The code for that is here: https://github.com/blipjoy/nm-prototype/blob/gh-pages/js/objects/screens.js#L43-L55 There are better ways to do this now that melonJS and Tiled both support tile animations. But back then, this was a really impressive feat.

BTW the original windmill assets are available here: https://opengameart.org/content/lpc-cnilsson

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...