Easiest way to make a map?

pixeltroid

Member
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?
 
A

Annoyed Grunt

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

trentallain

Guest
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?
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.
 
D

Deleted member 16767

Guest
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)
}
 

pixeltroid

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

pixeltroid

Member
How are the wall and ground objects drawn? Can you show the whole code?
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)
}
 
A

Annoyed Grunt

Guest
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

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


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

Annoyed Grunt

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

pixeltroid

Member
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
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!
 
A

Annoyed Grunt

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

pixeltroid

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

Annoyed Grunt

Guest
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;
 
A

Annoyed Grunt

Guest
Like this?

xp =view_xview/2 - 160;
yp =view_yview/2 - 40;
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.
 

pixeltroid

Member
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;
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:
A

Annoyed Grunt

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

pixeltroid

Member
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? :|
 
D

Deleted member 16767

Guest
@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.
 
A

Annoyed Grunt

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

View attachment 25731

Why is that? :|
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;
 

pixeltroid

Member
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;
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:
A

Annoyed Grunt

Guest
This is odd because it's clear the vertical alignment is working, do you happen to change the value of xp anywhere?
 

pixeltroid

Member
This is odd because it's clear the vertical alignment is working, do you happen to change the value of xp anywhere?
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)
}
 
A

Annoyed Grunt

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

pixeltroid

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


 
A

Annoyed Grunt

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

pixeltroid

Member
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.
hmmm.. I changed it to draw GUI. But now the map moves around as I move around. :/
 
A

Annoyed Grunt

Guest
The Draw GUI events works on different rules than the standard draw event so I suggest you check out the relevant documentation.
 
D

Deleted member 16767

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

pixeltroid

Member
@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.
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...
 
D

Deleted member 16767

Guest
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

Member
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.
Hey man, thanks for posting the codes. I'll test it out, and post the results!
 
D

Deleted member 16767

Guest
Hey man, thanks for posting the codes. I'll test it out, and post the results!
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.
 

pixeltroid

Member
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. :)
 
Top