Creating a quick minimap
Hey everyone! I've got a couple of comments about the minimap feature of our space shooter whatever game.
I apologize for the graphical errors in the gif. I just changed laptops and my software isn't playing well with the new version...
You can see it in action in the lower right of the game screen. The basic premise of the game is you are defending your ship while you get far enough away to jump to lightspeed, so it is important to have a quick and easy way to see where everything is at a glance. The minimap was a later addition but it completely changed the way the whole game is played. Early on the best strategy was just to hang out next to the ship but the minimap allows you to go deal with problems before they can even reach you. It took about 20 minutes to implement, no graphics, and no changes to my existing objects to do. I wanted to do a quick writeup explaining how it works...
Note I am using the language Haxe which has very similar syntax to a lot of languages, so it should be pretty easy to follow.
All the magic happens in a MinimapMarker object. A minimapMarker object is one of the colored dots that appears on the map. It is ~30 lines of code long and some of them are blank.
```
class MinimapMarker extends FlxSprite
{
var parent:Entity;
public function new()
{
super();
makeGraphic(3, 3, FlxColor.WHITE);
scrollFactor.set();
}
public function registerEntity(e:Entity) {
parent = e;
color = e.minimapColor;
setPosition(-100,-100);
revive();
}
override public function update(elapsed:Float):Void
{
if (parent == null || !parent.alive && parent.type != EnemyTypes.GUNSHIP) {
kill();
return;
}
var xx = parent.x / H.LEVEL_SIZE;
var yy = parent.y / H.LEVEL_SIZE;
setPosition(H.MAP_LOC_X + H.MAP_SIZE * xx - 1, H.MAP_LOC_Y + H.MAP_SIZE * yy - 1);
super.update(elapsed);
}
}
```
I'll walk through the pieces.
The constructor
var parent:Entity;
Nothing exciting here. I'm just creating a variable to hold the object that I want to display (all my objects are type Entity). The constructor just makes a white sprite that is 3 pixels by 3 pixels. The line about scrollFactor.set() is just making it stationary if the camera moves, which is what all the HUD elements have.
public function new()
{
super();
makeGraphic(3, 3, FlxColor.WHITE);
scrollFactor.set();
}
Register Entity
public function registerEntity(e:Entity) {
parent = e;
color = e.minimapColor;
setPosition(-100,-100);
revive();
}
Next I register the entity that this minimap object should represent. I set it to a color (so the player can be red, the ship green, enemies blue and bosses yellow). Then I move it off the board and make it active.
Update
``` override public function update(elapsed:Float):Void { if (parent == null || !parent.alive) { kill(); return; }
var xx = parent.x / H.LEVEL_SIZE;
var yy = parent.y / H.LEVEL_SIZE;
setPosition(MAP_LOC_X + MINIMAP_SIZE * xx,MAP_LOC_Y + MINIMAP_SIZE * yy);
super.update(elapsed);
}
``` Finally, I call the update function this every frame. It just kills the object if the parent Entity is dead (or doesn't exist because I did something stupid). If the parent object is alive, it calculates the xx and yy values. They are just a ratio of the entities position in relation to the whole level. My levels are 2000x2000 units, so a unit in the center (1000,1000) would have an xx and yy of .5 each.
Finally, I just move the dot to the correct location. The MINIMAP_SIZE is how large I want my minimap to be. So the entity with the xx and yy values of .5 would be placed in the center of the area. Then I add the coordinates where I want the minimap to appear and I'm done.
The great thing about this method is that my entities don't have to change. I can track anything with an X and Y value in world coordinates and place it on the map.
Hope this was useful! If you want to see it in action you can play the game here:
https://ldjam.com/events/ludum-dare/42/wingman