Sign in to follow this  
Growler

Minimap for melon v5.1.0

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

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
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?

Share this post


Link to post
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. 

 

Share this post


Link to post
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.

 

 

Share this post


Link to post
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

Share this post


Link to post
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 :)

Share this post


Link to post
Share on other sites

If you want to show just basic shapes you could draw the collision layer as rectangles on a background.

That or make a different tileset but use it only in the minimap where your ground is white and your other tiles are black.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.