Jump to content

Minimap for melon v5.1.0


Growler
 Share

Recommended Posts

I created a minimap for my game a while back (2014, melon 1.1) by redrawing a copy of the tilemap at smaller scale into a new canvas element.

The suggestion back then from @Parasyte was to loop through map layers and draw them at scale:

var scale = 0.25;
var map = me.game.currentLevel;
var canvas = me.video.createCanvas(map.width * scale, map.height * scale);
var ctx = me.CanvasRenderer.getContext2d();

var renderer = {
    globalAlpha ; function () {
        return ctx.globalAlpha;
    }.
    setGlobalAlpha : function (a) {
        ctx.globalAlpha = a;
    }.
    drawImage : function () {
        ctx.drawImage.apply(ctx, arguments);
    }
};

ctx.scale(scale, scale);

map.getLayers().forEach(function (layer) {
    layer.draw(renderer, map);
});

In Melon 5.1.0, I've changed map = me.game.currentLevel to map = me.levelDirector.getCurrentLevel(); 

I'm getting error Cannot read property 'x' of undefined at Math.max(rect.pos.x - (layer.maxTileSize.width - layer.tilewidth), 0),:

        /**
         * draw the tile map
         * @ignore
         */
        drawTileLayer : function (renderer, layer, rect) {
            // get top-left and bottom-right tile position
            var start = this.pixelToTileCoords(
                ---> Here: Math.max(rect.pos.x - (layer.maxTileSize.width - layer.tilewidth), 0),
                Math.max(rect.pos.y - (layer.maxTileSize.height - layer.tileheight), 0),
                me.pool.pull("me.Vector2d")
            ).floorSelf();

Has the way we render a smaller replica of the full tmx map changed since then?

Looking at the source, it looks like me.TMXLayer's draw() function takes a renderer and rect. But I'm passing in a renderer and map, where map is a Class instance of the TMX map, not a rect. Has this changed, and should I be passing in a rect, if so, which rect?

        /**
         * draw a tileset layer
         * @ignore
         */
        draw : function (renderer, rect) {

Screen Shot 2018-06-23 at 1.29.08 PM.png

Link to comment
Share on other sites

The rectangle defines the draw destination. Usually it's the viewport: https://github.com/melonjs/melonJS/blob/5.1.0/src/game.js#L345 If you already have a GUI object or something else that represents the minimap size and position, you might just be able to use its rect. Otherwise you can create a me.Rect with the parameters you need, and use that.

Link to comment
Share on other sites

@Parasyte cool, I did that:

		let gameW = $('.game-wrapper').width();
		let gameH = $('.game-wrapper').height();
		let rect = new me.Rect(0, 0, gameW, gameH);
		// Get all layers of my TMX map and draw them like a boss
		map.getLayers().forEach(function(layer) {
			layer.draw(renderer, rect);
		});

If I print out layer, I see it's drawing each of my layers in Tiled correctly. I set the rectangle width/height to full screen size.

See below, however, to show comparison between full map in Tiled vs what's being printed in game. It's only part (top left) of the map:

Screen Shot 2018-06-23 at 6.14.05 PM.png

Screen Shot 2018-06-23 at 6.14.37 PM.png

Link to comment
Share on other sites

@Parasyte Secondly, the other question I have is:

I put a console.log in the melon source at drawTileLayer : function (renderer, layer, rect) { and noticed it's always redrawing the tile layers. This makes sense for a TMX tile which has an animation (I have a tileset with an animated water tile). But why redraw all the other static tiles?

Link to comment
Share on other sites

On 6/24/2018 at 6:39 AM, Growler said:

@Parasyte Secondly, the other question I have is:

I put a console.log in the melon source at drawTileLayer : function (renderer, layer, rect) { and noticed it's always redrawing the tile layers. This makes sense for a TMX tile which has an animation (I have a tileset with an animated water tile). But why redraw all the other static tiles?

well you have to think about this in the context of drawing Layer(s) for every single frame and with other potential objects, effect, UI, etc... being drawn both within or above those layers.....

now two things (tell me if you had something else in mind) :

1) to build your mini map it does not really matter, right ? as you just call it one time to draw it on your canvas

2) there is a "preRender" property (that can be defined in Tiled) that will pre-render all layers on an offset canvas. Advantage is definitely on performances, but then you just significanty increase the memory usage, as a new canvas of the map size is created PER layer. 

 

Link to comment
Share on other sites

On 6/24/2018 at 6:15 AM, Growler said:

@Parasyte cool, I did that:


		let gameW = $('.game-wrapper').width();
		let gameH = $('.game-wrapper').height();
		let rect = new me.Rect(0, 0, gameW, gameH);
		// Get all layers of my TMX map and draw them like a boss
		map.getLayers().forEach(function(layer) {
			layer.draw(renderer, rect);
		});

If I print out layer, I see it's drawing each of my layers in Tiled correctly. I set the rectangle width/height to full screen size.

See below, however, to show comparison between full map in Tiled vs what's being printed in game. It's only part (top left) of the map:

Screen Shot 2018-06-23 at 6.14.05 PM.png

Screen Shot 2018-06-23 at 6.14.37 PM.png

the second parameter is a rect that define the area of the map to draw (and we therefore pass the viewport to it), so the issue here above is that you specificy the rect size accordingly to your canvas/viewport size, where it should the size of the minimap canvas.

 

 

Link to comment
Share on other sites

On 6/25/2018 at 1:13 AM, obiot said:

well you have to think about this in the context of drawing Layer(s) for every single frame and with other potential objects, effect, UI, etc... being drawn both within or above those layers.....

now two things (tell me if you had something else in mind) :

1) to build your mini map it does not really matter, right ? as you just call it one time to draw it on your canvas

2) there is a "preRender" property (that can be defined in Tiled) that will pre-render all layers on an offset canvas. Advantage is definitely on performances, but then you just significanty increase the memory usage, as a new canvas of the map size is created PER layer. 

@Parasyte @obiot

1) Yes. The goal is to call it a single time. I simply need to create a replica of the full Tiled map at smaller scale.

2) Not sure what you mean here. Should I go with Pre-render? If so, how can I do this?

RE: "the second parameter is a rect that define the area of the map to draw (and we therefore pass the viewport to it), so the issue here above is that you specificy the rect size accordingly to your canvas/viewport size, where it should the size of the minimap canvas."

The minimap canvas should take up the full width of the screen when they click it, so that's why I pass the size of the viewport.

See below: the canvas within <div id="screen"> is the game canvas, while the canvas within <div class="full-map"> is the minimap.

Screen Shot 2018-06-28 at 7.45.44 PM.png

Link to comment
Share on other sites

I wonder if a trick where you draw the map scaled down on a much smaller canvas, and then zoom out the canvas when drawing it on screen would do ?

Normally you should be able to apply a transform (scale) on the whole map using currentTransform http://melonjs.github.io/melonJS/docs/me.Renderable.html#currentTransform

don’t forget to translate to the map center, before scaling, and also “de-scale” and translate back to the origin point once done :)

Link to comment
Share on other sites

  • 4 weeks later...

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...