In a game where the camera centers on the player and the scene/level is bigger than the screen I want to create a radar or map view in the screen corner. It does not have to be a complete screenshot but at least show the level with the position of a few sprites (Player, Treasure but e.g. no enemies).
How to best accomplish that? Maybe there is also some fog of war that can be added?
If I understand right, Rapa has the map drawn out fuly, has a bunch of black boxes that hide the map, and then destroys each box the “Minimap player” comes in contact with to reveal part of the map.
Feel free to look through my example, but you’ll need to dig into a lot of dealing with positioning, layers, secondary cameras, etc.
Thank you for that response. It is excellent news that a level map can be accomplished.
I had a quick look at your demo, and it looks interesting so I downloaded the code. Will have to through details later. What I had in mind somehow was to have some canvas that I can draw on just the important parts of the level and keep it in memory. Then have it rendered through a sprite, and only the dot representing the player’s position would have to be custom painted.
Fog of war could be done by a second image acting as a fog mask that will be drawn on top of the first image. In that fog mask the pixels would loose transparency over time and thus show their real (black) color. Wherever the player runs the overlay could be painted with 100% transparent black ink.
This would just require editing images in memory. Is there such support in GDevelop, or maybe at least in JavaScript?
couldn’t you add another layer, create objects that represent game objects, and simply assign them the coordinates of the game objects but divided by maybe 10 or more, that way it will show the position of the objects but on a smaller scale?
This could well work although I believe it is a lot of overhead on the developer (me).
GDevelop has to render the scene anyway. Usually only the portion visible by the camera is rendered.
Now imagine you could zoom away until the whole scene fits the screen and take a screenshot to be kept in memory. If this screenshot allows some more operations as I mentioned above the topic could be closed in a generic way.
The performance penalty would be based on the speed of the machine and the idea of the developer. For my purpose it would be sufficient to create that screenshot at the beginning of the scene. When rendering that out I’d just add one point as player position, and optionally the mask resembling the fog of war.
That means in the game loop/render part there would be
one image blit operation (show the map)
one image blit operation (overlay the fog of war)
one filled circle drawing (indicate the player position)
During the game loop/update part there would be
one image blit operation (intensify the fog globally)
one filled circle drawing (unfog player’s vicinity)
I’m not sure whether the camera can be zoomed out, but if that assumption holds true I believe this concept could be implemented as a generic extension.
Next would be to find out how to further process it in the game (there is JavaScript support for images, but in the end something would have to be rendered on the screen again)
I tried taking screenshots of my game, and after experimenting a while I found the file in the expected location. (Side note: If some action fails at runtime, how does GDevelop behave?)
Then I tried to zoom out the camera before taking the screenshot and yes, that also works. So this could be a cheap method to create a level map.
However when I completed the sequence to also zoom in again afterwards the screenshot would always contain the unzoomed screenshot. Not what I expected.
Not even adding the sound play did help.
Is it possible that the screenshot, much like the sound work asynchronously?
How could I synchronize actions?
Is there a way to react on ‘Sound finished playing’ or ‘Screenshot finished saving’ events?
When we talk about examples we usually talk about the examples projects proposed to you when you create a new project
Here I indeed got mistaken. What I meant is a modified version of the load image from url example that uses the code snippet you quoted.
I am anything but a JavaScript expert, and looking at all these examples that I find everybody wants to save to local file. This is the case here, here and in various other places. However what I want to achieve is to have the image ready for display through a sprite. The most helpful resource is the Mozilla Canvas tutorial, which made me write this:
//-- this stuff will run as one-off
const radius = 20; // radius to unfog for the player
var mapCanvas = document.createElement('canvas');
var fogCanvas = document.createElement('canvas');
const renderer = runtimeScene.getRenderer();
const levelCanvas = renderer._pixiRenderer.view; // we have the rendered level now
//-- this stuff will run during update
// fog of war gets intense every step
var ctx = fogCanvas.getContext('2d');
ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'; // almost transparent black ink
ctx.fill();
// player can see vicinity, so punch a hole into fog
ctx.fillStyle = 'rgba(0, 0, 0, 0)'; // fully transparent black ink
ctx.arc(Player.X(), Player.Y(), radius, 0, 2*Math.PI)
ctx.fill()
// assemble the map for rendering
var ctx = mapCanvas.getContext('2d');
ctx.drawImage(levelCanvas, 0, 0);
ctx.drawImage(fogCanvas, 0, 0);
// mapCanvas contains our fogged level map. How to push this into the level sprite?
I’d expect to have the map ready to draw in mapCanvas. But how would I inject that into a Sprite? Or how else could this be rendered in GDevelop?
Now for the modification:
I understand the example loads something from a URL using the PIXI image manager - which I do not need. so I guess the important parts are from the callback method:
var object_texture_image = runtimeScene.getObjects("Map"); // Get all the objects called "Map"
var object_texture_image_renderer = object_texture_image[0].getRendererObject(); // get the map's renderer (PIXI sprite)
object_texture_image_renderer.texture = mapCanvas.texture; // change the texture in renderer (PIXI sprite) to the map
Somehow I am not yet convinced about type safety - especially when using a canvas like an image…