Easiest way to make a map?

Discussion in 'Programming' started by pixeltroid, Jul 13, 2019.

  1. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    I followed a tutorial for a map that creates a minimap based on actual positions of in-game objects. It works great to an extent because:
    a) It automatically renders itself when I go to a new room.
    and
    b) It shows the real time positions of doors, and when I unlock a door, the door stops showing up on the minimap.

    The only problem is that it very poorly renders the wall and ground objects. It looks really shabby and is not something I would want to show.

    Here's the code of the minimap object:
    Create
    Code:
    xp = 120
    yp = 68
    height = 120
    width = 68
    xscale = width/room_width
    yscale = height/room_height
    
    Draw
    Code:
    xp = view_xview[0] +350
    yp = view_yview[0] + 10
    
    //half faded black bg
    draw_set_alpha(0.3)
    draw_rectangle(xp, yp, xp+width, yp+height, false)
    
    //count doors
    draw_set_color(c_yellow)
    draw_set_alpha(.80)
    var doorcount;
    doorcount; = instance_number(obj_door)
    for (k=0; k<doorcount; k=k+1) {
    doorid = instance_find(obj_door,k)
    var wherex = xp+doorid.x*(xscale)
    var wherey = yp+doorid.x*(yscale)
    draw_circle(wherex,wherey,2,false)
    
    I was wondering if theres a way to add a screenshot of the actual room to the code for the minimap object?

    Maybe by taking screenshots of the walls of the entire room from the room editor, shrinking it down to a small sprite and having it appear on the map? But I'm worried because each room is a different size and I may end up wasting time trying to align and scale things for every rooms map.

    I also thought of just using clean screenshots of the entire room and having them pop up as a map. But then, it wont show things in real-time, so doors will still show up even when I've opened them, and might confuse things for a player. This kind of bothers me.

    Is there an easier way to render all walls and floors neatly without manually taking screenshots, indexing them and coding them in???

    Do you have any advice for me?
     
  2. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,144
    How are the wall and ground objects drawn? Can you show the whole code?
     
  3. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    Can you please post a picture of your minimap? Your issue is aesthetical and it's kind of hard to judge on an aesthetic problem when you can't see the thing itself. It would be useful to see how "shabby" it is.
     
  4. trentallain

    trentallain Member

    Joined:
    Aug 6, 2016
    Posts:
    521
    You could have 2 views maybe? One for your normal camera and then one for the map, which is really zoomed out but then resized.
     
  5. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    314
    I think he wants a mini map out of a map for his game.
     
  6. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    314
    I'm having a problem with this too actually. I'm always enlengthening the solid wall to fit the tiles, because it saves a lot of time.

    The code:

    Code:
    var _x, _y, _s;
    _x = argument0
    _y = argument1
    _s = argument2
    
    
    
    draw_rectangle_color(_x,_y,_x+room_width/_s,_y+room_height/_s,c_white,c_white,c_white,c_white,1)
    
    
    
    with (obj_something)
    {
    draw_set_color(c_orange)
    draw_rectangle(_x+x/_s-sprite_width/(2*_s),_y+y/_s-sprite_width/(2*_s),_x+x/_s+sprite_width/(2*_s),_y+y/_s+sprite_width/(2*_s),0)
    }
     
  7. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    This is what it looks like.

    MMMAP.jpg

    Note the gaps between the solid obects. Also the map is looking squished sideways.

    The code includes specifications to show the solid object. Its the same as the ones Ive shown in the OP, but it ts for obj_solid
     
    Last edited: Jul 13, 2019
  8. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    The wall and ground objects are just 1 32x32 solid block that has been laid out to form the ground and walls.

    The draw code right now is as follows:


    Code:
    xp = view_xview[0] + 350
    yp = view_yview[0] + 10
    
    //half faded black bg
    //draw_set_alpha(0.3)
    //draw_rectangle(xp, yp, xp+width, yp+height, false)
    
    
    //couunt obj_solid
    draw_set_color(c_white)
    //draw_set_alpha(.80)
    var solidCount;
    solidCount = instance_number(obj_solid)
    for (k=0; k<solidCount; k=k+1) {
    solidId = instance_find(obj_solid,k)
    var wherex = xp+solidId.x*(xscale)
    var wherey = yp+solidId.y*(yscale)
    draw_rectangle(wherex, wherey, wherex + 2, wherey + 2.7, false)
    }
    
    //couunt doors
    draw_set_color(c_blue)
    draw_set_alpha(.80)
    var doorCount;
    doorCount = instance_number(obj_door)
    for (k=0; k<doorCount; k=k+1) {
    doorId = instance_find(obj_door,k)
    var wherex = xp+doorId.x*(xscale)
    var wherey = yp+doorId.y*(yscale)
    //draw_circle(wherex,wherey,2,false)
    draw_rectangle(wherex, wherey, wherex + 1, wherey - 6, false)
    }
    
    
    
    //couunt obj_player
    draw_set_color(c_yellow)
    draw_set_alpha(.80)
    var playerCount;
    playerCount = instance_number(obj_player)
    for (k=0; k<playerCount; k=k+1) {
    playerId = instance_find(obj_player,k)
    var wherex = xp+playerId.x*(xscale)
    var wherey = yp+playerId.y*(yscale)
    draw_rectangle(wherex, wherey, wherex + 1, wherey + 3, false)
    }
    
     
  9. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    314
    @pixeltroid Maybe you can use the code I showed here and just draw the objects with alt + click.
     
  10. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    I copy pasted your code into the draw event and changed obj_something into obj_solid but I still got an error.
     
  11. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    Map Squishes Sideways
    Currently, your map is a 120x68 rectangle (which is a ~1.765 ratio). Unless your room has the same proportions, it needs to be squished to fit inside that space. Just to drive this point home, let's say you're making an escape sequence like in the original Metroid, which is a very tall but also very thin room. It still needs to be squished into a map that is wider than it is tall, so you end up with deformation.
    The most obvious solution is to use the xscale and yscale to calculate the map's width and height rather than viceversa. For example, setting both xscale and yscale to 0.1 (both scales need to be the same for no deformation to occur) and then your minimap will be one tenth of your room. A trickier solution would be to fix either the width or height of the map and calculate the other dimension using the aspect ratio of the room. If you REALLY need the minimap to be a specific size then you would have to "fit" the room inside of the map without deforming it.
    Gaps Between Solid Instances
    Right now you convert the instances' coordinates by scaling them down, but you do not bother to do the same with the instances' width and height. Rather, you fix the dimension of your map-blocks to 2x2.7. First of all, this introduces extra deformation, because your blocks are perfect 32x32 squares, and since this size is fixed it bears no resemblance to the actual scale of your map-blocks which leads to gaps. You should also convert the size of your blocks while drawing them.​
     
    pixeltroid likes this.
  12. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Thanks for explaining things!

    My rooms are of different proportions, some are extremely wide horizontal rooms, others are vertical and narrow. So I guess that means it I should not confine the map within a rigid 120 x 68 rectangle.
    So I'll get rid of the map from the top right hand corner of the screen, and make it so that when I press a button, lets say "Space, the game is paused and the map shows up in the center of the screen.


    I didnt understand. How do I go about implementing this? I had to make it and 2 x 2.7 to fix the problem of the gaps between the blocks.
     
  13. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    I would personally use the bounding box of the instances. I've plopped the map into my own project and tinkered with it a bit:

    Code:
    //Render solids
    draw_set_color(c_white)
    //draw_set_alpha(.80)
    var solidCount = instance_number(obj_solid)
    for (k = 0; k < solidCount; k++) {
        block = instance_find(obj_solid, k)
        var x1 = ceil(block.bbox_left * xscale),
            y1 = ceil(block.bbox_top * yscale),
            x2 = floor(block.bbox_right * xscale),
            y2 = floor(block.bbox_bottom * yscale);
        draw_rectangle(xp + x1, yp + y1, xp + x2, yp + y2, false)
    }
    
    The ceil/floor affair is to avoid overlapping between blocks in case you decide to make them seethrough again.

    EDIT:
    Adding a picture for good measure
    [​IMG]
     
    pixeltroid likes this.
  14. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Hey thanks. I added your code. And I can see there is a huge improvement!

    mapnew.jpg

    But the map still appears slightly deformed.

    And there are still some gaps between some blocks -- even though they have been laid out perfectly in the room editor.

    Also how do I make the map align to the exact center of the view? regardless of how big or wide or narrow the room is, I want the map to be in the center of the view.
    Here are my view settings....


    room settins.jpg

    I tried:

    xp = view_xview[0] /2
    yp = view_yview[0] /2

    But its not showing up!
     
  15. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    Can you show me the create event?
    As for placing it in the middle of the screen, you would see the coordinates to the center of the view minus half of the size of the map, both horizontally and vertically.
     
  16. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    The create event is as follow :

    Code:
    width = 320
    height =  80
    xscale = width/room_width
    yscale = height/room_height
    
    I've changed the original code to make it larger because I now plan on having a larger map showing up only when a certain button is pressed -- as opposed to a small map constantly being on the top right hand of the screen.

    Edit: Ive changed the width and height. Posted the wrong numbers by mistake.
     
  17. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    Alright, that's the issue. Since you have not modified the way you calculate the size of the minimap, the deformation introduced by stretching the whole map to fit into a different aspect ratio is still present. As I said before, the simplest way would to just set a relative size for the map ("the minimap map is a 1/10th reproduction of the map") and move from there.

    Code:
    xscale = 0.1;
    yscale = 0.1;
    width = room_width * xscale;
    height = room_height * yscale;
    
     
  18. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Like this?

    xp =view_xview/2 - 160;
    yp =view_yview/2 - 40;
     
  19. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    view_xview/view_yview represent the top left coordinate of the view, you can use view_wview and view_hview to get its size and you should really use width/2 and height/2 instead of magic numbers, as you want your code to be easy to edit.
     
  20. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    This worked! THANKS!

    Regarding aligning it to the center, I made it like this:

    xp = (view_wview - width/2)
    yp = (view_hview - height/2)


    But now it scrolls along as I move....which is a problem! How do I fix this?
     
    Last edited: Jul 13, 2019
  21. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    Alright let's break it down step by step, only handling the horizontal axis because it's the same for the vertical one.

    Code:
    xp = view_xview
    The map will be drawn at the coordinates of the view, which in turns means top left corner of the screen (in most instances).

    Code:
    xp = view_xview + view_hview/2
    The map will be drawn with its top left corner at the center of the screen.

    Code:
    xp = view_xview + view_hview/2 - width/2
    We offset the map by half its height, thus placing its center at the center of the screen.
     
  22. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    hey thanks for all your help. I added your code and also added a line for the y axis.

    xp = view_xview + view_hview/2 - width/2
    yp = view_yview + view_wview/2 - height/2

    But its still not getting aligned to the center.

    agmap1.jpg

    Why is that? :|
     
  23. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    314
    @pixeltroid

    Try this:

    Code:
    //Create event
    wview = view_wport[0]
    hview = view_hport[0]
    
    
    //Draw event
    //Add this somewhere in your code. You might want to change the numbers.
    wview/1.4,hview/1.5
    I haven't followed you and the other helpers code thoroughly, as I was working on that other code I have.
     
  24. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    Sorry, just a typo: i used hview in the calculation of xp, while I should have used wview. So you should just switch those around.

    Code:
    xp = view_xview + view_wview/2 - width/2;
    yp = view_yview + view_hview/2 - height/2;
    
     
  25. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Hey, I changed the code to what you posted above. But its still not getting aligned to the center of the room! The last 20 percent of the map seems to be out of view!
    This room is 3700pixels wide x 550 pixels high

    agmap_a.jpg


    BUT it seems to be working fine for certain smaller rooms, like this one which is 2000 x 815 pixels:

    agmap_b.jpg

    Edit: The smaller the room, the more center aligned the map is. Like this one (1008 x 664 pixels)

    agmap_c.jpg

    Why? ://
     
    Last edited: Jul 13, 2019
  26. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    This is odd because it's clear the vertical alignment is working, do you happen to change the value of xp anywhere?
     
  27. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Nope. Not at all.

    Here are the codes the way they are right now:

    Create:
    Code:
    xscale = 0.1;
    yscale = 0.1;
    width = room_width * xscale;
    height = room_height * yscale;
    
    Draw:

    Code:
    xp = view_xview[0] + view_wview/2 - width/2;
    yp = view_yview[0] + view_hview/2 - height/2;
    
    //Render solids //FROM AGRUNT
    draw_set_color(c_white)
    //draw_set_alpha(.80)
    draw_set_halign(fa_center)
    draw_set_valign(fa_center)
    var solidCount = instance_number(obj_solid)
    for (k = 0; k < solidCount; k++) {
        block = instance_find(obj_solid, k)
        var x1 = ceil(block.bbox_left * xscale),
            y1 = ceil(block.bbox_top * yscale),
            x2 = floor(block.bbox_right * xscale),
            y2 = floor(block.bbox_bottom * yscale);
        draw_rectangle(xp + x1, yp + y1, xp + x2, yp + y2, false)
    }
    
    //Render player
    draw_set_color(c_yellow)
    //draw_set_alpha(.80)
    draw_set_halign(fa_center)
    draw_set_valign(fa_center)
    var solidCount = instance_number(obj_player)
    for (k = 0; k < solidCount; k++) {
        block = instance_find(obj_player, k)
        var x1 = ceil(block.bbox_left * xscale),
            y1 = ceil(block.bbox_top * yscale),
            x2 = floor(block.bbox_right * xscale),
            y2 = floor(block.bbox_bottom * yscale);
        draw_rectangle(xp + x1, yp + y1, xp + x2, yp + y2, false)
    }
    
    
     
  28. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    I'm at a loss, could it be you're supposed to use view_wview and view_hview as arrays? I haven't used GM1 in years.
     
  29. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Hmmmm. I dont know . :/

    I tweaked your code to

    xp = view_xview[0] + view_wview/5 - width/5;
    yp = view_yview[0] + view_hview/2 - height/2;

    The alignment problem is somewhat fixed in the first room:

    agmap_d.jpg

    but fails to align in the other smaller room

    agmap_e.jpg

    I think I'll just align it to the bottom left corner for now.

    But anyway, I want to thank you very much for all your help over the last few hours!!

    Do let me know if you figure out a way to resolve this issue!

    Thanks to @mikix as well!



    EDIT: Maybe I'll just manually set the alignment for each room. At least I have a working map thanks to you!
    @Annoyed Grunt


     
  30. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    I suggest you make them view_wview[0] and view_hview[0], as the logic behind the positioning is sound the error must be somewhere else, and I'm thinking engine quirk. You could also let go of the draw event and move to the draw gui event which should make things a bit simpler.
     
  31. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    hmmm.. I changed it to draw GUI. But now the map moves around as I move around. :/
     
  32. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    136
    The Draw GUI events works on different rules than the standard draw event so I suggest you check out the relevant documentation.
     
  33. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    ah ok. I will. Thanks!
     
  34. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    314
    @pixeltroid You don't have to manually place them. You can still code it to be used for different rooms. Like this:

    Code:
    if room1 or room4
    {
          your mini map code
    }
    
    if room2 or room3
    {
          your mini map code but with different math
    }
    
    
    I'm assuming you have the same size for some rooms? It's a habit for some to have it sometimes.
     
  35. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    my room sizes vary quite a bit. I have been manually measuring the rooms and adding the codes for the map alignment in the same object.

    if room = room_T1
    {
    xp = view_xview[0] +50
    yp = view_yview[0] + 100
    }

    if room = room_T2
    {
    xp = view_xview[0] +40
    yp = view_yview[0] + 100
    }

    if room = room_T3
    {
    xp = view_xview[0] +200
    yp = view_yview[0] + 100
    }


    and so on...
     
  36. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    314
    Create a script, call it scr_minimap.

    Add this

    Code:
    var _x, _y, _s;
    _x = argument0
    _y = argument1
    _s = argument2
    
    
    
    draw_rectangle_color(_x,_y,_x+room_width/_s,_y+room_height/_s,c_white,c_white,c_white,c_white,1)
    
    
    
    with (solid_wall)
    {
    draw_set_color(c_white)
    draw_rectangle(_x+x/_s-sprite_width/(2*_s),_y+y/_s-sprite_width/(2*_s),_x+x/_s+sprite_width/(2*_s),_y+y/_s+sprite_width/(2*_s),1)
    }
    with (obj_player)
    {
    draw_set_color(c_white)
    draw_rectangle(_x+x/_s-sprite_width/(2*_s),_y+y/_s-sprite_width/(2*_s),_x+x/_s+sprite_width/(2*_s),_y+y/_s+sprite_width/(2*_s),1)
    }
    
    and so on...
    Create an object, call it mini_map.

    In create event:

    Code:
    wview = view_wport[0]
    hview = view_hport[0]
    In draw GUI

    Code:
    if !keyboard_check(vk_tab)
    {scr_minimap(wview/1.4,hview/1.5,50)}
    
    if keyboard_check(vk_tab)
    {
    scr_minimap(wview/6,hview/6,25) 
    }
    I'm using GMS2 but I hope you can make it work for your version.
     
    pixeltroid likes this.
  37. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Hey man, thanks for posting the codes. I'll test it out, and post the results!
     
  38. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    314
    Nice. It will not work with objects that you have changed in the room editor manually, though. The best way to utilize this, is to make appropriate sizes for each platform. I'm using a 64x64 wall object, and I just alt + click it on the walls. But I like the effect it gives on my mini map, so I didn't bother making other sizes for the wall objects sprite. I'm making a top down game, btw. So I don't have platforms.
     
  39. pixeltroid

    pixeltroid Member

    Joined:
    Jul 23, 2016
    Posts:
    593
    Okay, I did what you said and here's how it looks...


    mikixmap.jpg

    I guess it can be enlarged but its clear to me your map obviously works well! I fear I may need to re-measure every room again and spend another few hours trying to align it for each room.

    I GREATLY appreciate your help but my gut is telling me to just stick to the code that has already been mostly implemented.

    Its 5 AM here and I am about to go to bed. I'll try to see tomorrow if I can mix some of your code with what I @Annoyed Grunt gave me. If it works, great. Otherwise, I'll stick to what I've already implemented. :)
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice