Kiekos
Member
|
Monsters on the MiniMap
Hey there!
I've been struggling with the minimap for quite a while now and can't figure out one thing. Drawing dots on the minimap which would show position of characters (monsters, players, etc). For example I've prepared this for monsters:
Code:
REPA(Monsters)
{
//getting monster's position
Vec2 mob_pos(Monsters[i].pos().x, Monsters[i].pos().z);
//calculation world to image position
Vec2 dot_draw = Game::World.mini_map.worldToImage(mob_pos);
}
And then I should draw a dot in dot_draw position on the minimap but include the rectangle, frame, mask and so on... and so on.
Any ideas?
Cheers,
Kiekos
|
|
11-13-2013 10:26 PM |
|
TBJokers
Member
|
RE: Monsters on the MiniMap
Don't want to sound like a downer here, but you should research more before posting your questions. Yvan has previously shared a solution for adding points (Other players or simply Monsters) in a post.
http://www.esenthel.com/community/showth...ht=minimap
It should get you somewhere! I wish you goodluck!
|
|
11-14-2013 03:53 AM |
|
Fex
Gold Supporter
|
RE: Monsters on the MiniMap
This is how I do it:
Code:
/******************************************************************************/
Vec2 MapPosition=0;
Game::MiniMap MiniMap;
Flt MapRadius=32;
/******************************************************************************/
Bool InitMiniMap()
{
MiniMap.load("world/t4.world"); // load world mini map
return true;
}
/******************************************************************************/
void DrawMiniMap(C Rect &rect, C Vec2 &world_center_position, Flt radius)
{
Vec2 world_min=world_center_position-radius, // minimum coordinates of world position drawn on the mini map
world_max=world_center_position+radius; // maximum coordinates of world position drawn on the mini map
Vec2 image_min =MiniMap.worldToImage(world_min),
image_max =MiniMap.worldToImage(world_max),
image_center=MiniMap.worldToImage(world_center_position);
VecI2 image_mini=Floor(image_min), // minimum indexes of used image maps
image_maxi=Floor(image_max); // maximum indexes of used image maps
Vec2 image_size=rect.size()/(image_max-image_min); // size of a single map image on the screen
// iterate through all image maps to be displayed
for(Int y=image_mini.y; y<=image_maxi.y; y++)
for(Int x=image_mini.x; x<=image_maxi.x; x++)
{
// calculate screen position of the (x,y) image map
Vec2 image_pos=rect.center() - image_center*image_size;
image_pos.x+=x*image_size.x;
image_pos.y+=y*image_size.y;
// prepare the screen rectangle of the (x,y) image map
Rect_LD map_image_rect(image_pos, image_size.x, image_size.y);
// draw the image
Image &image=MiniMap(VecI2(x,y)); // access the image map from the world manager
if( image.is())image.drawMask(WHITE, Color(0,0,0,0), map_image_rect, *Images("gfx/mini map alpha.gfx"), rect); // if the image map is valid then draw it on the screen using masked drawing
}
WorldMap.arrow.drawRotate(rect.center(), Vec2(0.05, 0.05), Plr.angle.x/*+ 4.71*/);
REPA(NeighborClients)
{
Neighbor &neighbor=NeighborClients.lockedData(i);
if(neighbor.alive())
{
Vec2 diff = Plr.pos().xz() - neighbor.pos().xz();
if(neighbor.guildname != Plr.ginfo.guildName)
{
(rect.center() - diff/(MapRadius*MiniMap.areaSize()*0.1)).draw(BLUE, 0.003f);
}
else
{
(rect.center() - diff/(MapRadius*MiniMap.areaSize()*0.1)).draw(GREEN, 0.003f);
}
}
}
}
class MiniMapWindow : DragWindow
{
SizeRegion region;
GuiStyle originalstyle;
GuiStyle regionstyle;
void create()
{
super::create(Rect_RU(D.w(), D.h(), 0.9f, 0.9f).extend(-0.05f));
T.barVisible(false); FlagEnable(T.flag, WIN_RESIZABLE); FlagEnable(T.flag, WIN_IMMEDIATE);
T+=region.create(Rect_LU(0, 0 , 0.18f, 0.18f));
regionstyle.back_color=TRANSPARENT; regionstyle.border_color=TRANSPARENT; regionstyle.shadow=0; // style when we are not moused over
T.originalstyle = *T.style;
T.originalstyle.back_color = TRANSPARENT;
Gui+=T;
T.hide();
}
virtual void update(C GuiPC &gpc)
{
super::update(gpc);
if(Gui.ms() == &T || Gui.ms() == &T.region || Kb.alt())
{
T.style = &originalstyle;
if(Ms.wheel())
{
MapRadius*=ScaleFactor(Ms.wheel()*-0.2f);
Clamp(MapRadius, 16, 256);
}
}
else
{
T.style = ®ionstyle; //this will make completely transparent
}
}
}
MiniMapWindow minimapwindow;
This seems to work for me with 512x512 minimap images of 4 areas each. The Minimap window rect must be square not rectangular otherwise the dots won't show up in the right place. I just fiddles with the 0.1 in MapRadius*MiniMap.areaSize()*0.1 until the dots lined up with where other players were. I don't have AI shown on the map but to do so would be the same code.
|
|
11-14-2013 05:13 AM |
|
Kiekos
Member
|
RE: Monsters on the MiniMap
It's ok TBJokers, I have researched for a bit but must have missed this thread for some reason... My fault. Thanks for the replies anyway, I'll finish what has to be done.
EDIT: I did it the Fex's way as it seemed easier and shorter. It works but not as quite as it should. Take a look at this:
Green dot is an NPC (teleporter) which does not move and stands still on the map. However, even though the minimap is square, the green dot slightly moves away from the teleport (as I move away from it) while its distance should be constant...
I know it's a problem with scaling... of some sort... but I'm out of ideas which number causes the problem ;--;
Code:
REPA(NPCs)
{
Vec2 npc_pos = NPCs [i].pos().xz();
Vec2 chr_pos = Players [0].pos().xz();
Vec2 diff = chr_pos - npc_pos;
if(Dist(chr_pos, npc_pos) < radius * 1.4)
(rect.center() - diff/(radius*Game::World.mini_map.areaSize()*0.1)).draw(GREEN, 0.005f);
}
Oh and btw - I didn't know why I had to do 'radius * 1.4' for dots to be drawn all the way to the minimap's frame. If I leave 'radius' without it, dots are drawn on not even half of the minimap...
EDIT 2: Both problems - with moving dots and multiplying radius solved by using a bit different method which doesn't envolve scaling. Sorry for the problems guys
For those who are interested in 100% working code, here you go:
Code:
REPA(NPCs)
{
Vec2 npc_pos = NPCs [i].pos().xz();
Vec2 chr_pos = Players [0].pos().xz();
Vec2 diff = chr_pos - npc_pos;
Vec2 dot_draw = Game::World.mini_map.worldToImage(diff);
if(Dist(chr_pos, npc_pos) < radius)
(rect.center() - dot_draw).draw(GREEN, 0.005f);
}
(This post was last modified: 11-14-2013 01:42 PM by Kiekos.)
|
|
11-14-2013 10:59 AM |
|
Fex
Gold Supporter
|
RE: Monsters on the MiniMap
Using Game::World.mini_map.worldToImage(diff) looks like the more correct solution, I will have to try it...
|
|
11-14-2013 04:52 PM |
|
Kiekos
Member
|
RE: Monsters on the MiniMap
Well, go for it
It works fine for me and doesn't require any scaling 'from your side' as it scales vectors automatically to fit the minimap.
EDIT: I've figured out one thing... This method works fine only if map radius = 15... Once I change it in any way (+10/-10 or whatever), the scaling works still as if map radius was 15, so it has to be multiplied by something...
EDIT2: Yep, just checked it! It's quite simple:
- if you increase the radius from 15 to 30, you have to divide the scaled diff by 2
- if you change it from 15 to 10, you have to multiply scaled diff by 1.5 and so on...
So you only have to add this:
Code:
Vec2 dot_draw = Game::World.mini_map.worldToImage(diff) * 15/radius;
But the question is... Why does scaling always work as if radius equaled 15?
(This post was last modified: 11-14-2013 06:30 PM by Kiekos.)
|
|
11-14-2013 05:58 PM |
|
Rofar
Member
|
RE: Monsters on the MiniMap
Seeing this thread reminded me I have not done this yet so I figured this would be a good time to implement it. Especially since you kindly provided your code. I worked with this for a bit and although the implementation kind of works, the dots still offset as the camera/player moves.
I haven't come up with a solution yet and decided to put it on hold for now. But thanks for posting your code.
|
|
11-15-2013 01:44 AM |
|
Kiekos
Member
|
RE: Monsters on the MiniMap
Quote:the dots still offset as the camera/player moves
They don't do that in my game anymore, " * 15/radius " bit did the trick for me, but I still haven't figured out why...
There's something in the .worldToImage function that scales the position of the dots in the same way even though the radius changes - that's what I've found out.
|
|
11-15-2013 12:41 PM |
|
Rofar
Member
|
RE: Monsters on the MiniMap
I got it worked out now. I had to make the center of the image correspond to player position rather than camera position. Then where you are using 15/radius, I am using image_size (.x or .y doesn't matter since the image is square).
|
|
11-16-2013 02:29 PM |
|
Kiekos
Member
|
RE: Monsters on the MiniMap
Glad you got it working
|
|
11-16-2013 03:16 PM |
|
docrst
Member
|
RE: Monsters on the MiniMap
1> Game.cpp
1>e:\projects\_build_\client\source\game.cpp(161): error C2059: syntax error : 'for'
1>e:\projects\_build_\client\source\game.cpp(161): error C2143: syntax error : missing ')' before ';'
1>e:\projects\_build_\client\source\game.cpp(161): error C2059: syntax error : '--'
1>e:\projects\_build_\client\source\game.cpp(161): error C2059: syntax error : ')'
1>e:\projects\_build_\client\source\game.cpp(162): error C2447: '{' : missing function header (old-style formal list?)
|
|
11-16-2013 06:11 PM |
|