Growler Posted June 23, 2018 Share Posted June 23, 2018 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) { Quote Link to comment Share on other sites More sharing options...
Parasyte Posted June 23, 2018 Share Posted June 23, 2018 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. Quote Link to comment Share on other sites More sharing options...
Growler Posted June 23, 2018 Author Share Posted June 23, 2018 @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: Quote Link to comment Share on other sites More sharing options...
Growler Posted June 23, 2018 Author Share Posted June 23, 2018 @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? Quote Link to comment Share on other sites More sharing options...
obiot Posted June 25, 2018 Share Posted June 25, 2018 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. Quote Link to comment Share on other sites More sharing options...
obiot Posted June 25, 2018 Share Posted June 25, 2018 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: 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. Quote Link to comment Share on other sites More sharing options...
Growler Posted June 28, 2018 Author Share Posted June 28, 2018 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. Quote Link to comment Share on other sites More sharing options...
Growler Posted June 29, 2018 Author Share Posted June 29, 2018 @Parasyte @obiot Ah got it. Is there a way to pixelate / lower the integrity of the minimap render to basic 8 bit colors? I just want to show basic shapes. Quote Link to comment Share on other sites More sharing options...
Growler Posted June 30, 2018 Author Share Posted June 30, 2018 @Parasyte @obiot any thoughts here? Quote Link to comment Share on other sites More sharing options...
obiot Posted July 1, 2018 Share Posted July 1, 2018 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 Quote Link to comment Share on other sites More sharing options...
01271 Posted July 27, 2018 Share Posted July 27, 2018 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. obiot 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.