3
\$\begingroup\$

Currently, I am making a top down game using Unity. Here is the problem that I’m trying to solve: The player in my game is always centered on the screen, and the since the map is rounded, the agents controlled by AI must acts and be shown base on the distance of the round map. Here is the sketch for the better explanation. enter image description here

I want to ask for a good way to design and implementing the above task.

And here is my approach for this task:

  • I split the map into 4 areas (could be smaller and more in number).
  • Each of the 4 areas will have its corresponding area outside of the map area (The outside map areas are trigger boxes).
  • When the area that is covered by the main camera has its parts out of the map area, these outside parts will active the trigger boxes that are overlapped by them.
  • When a trigger box is activated, all the agents in its corresponding area inside the map will be moved temporally to the trigger box area. This can be done just by adding the difference between the trigger area position and the inside map area that the agent is staying to the agent’s position.
  • When the area that is covered by the main camera no longer overlap the trigger box, all the agent will move back to its corresponding position inside the map. This process is done by reversing the moving out process.

Here is the sketch for this. enter image description here

And the flawless come when there are agents with the flocking or forming formation behavior that requires the agents to have connections with others. When an agent is moved out of it actual position, the other agents in the formation will lose their connection with the moved agent (Like the distance between them suddenly becomes large). I think that this could be somehow solved by storing the actual position of the agent and marking it as moved, but it may be too computational cost, or having too many cases.

I tried to think of a different approach, that the map border is a circle, and to show the round view is just needed to take the symmetric through the center of the map. However, the circular border shows a bad animation when the agents try to move through the border. (I don't have enough reputation attach image about the flocking behavior problem and the circular approach, so you have to imagine it)

If you can solve the problems that I mentioned above or have a different approach, please show me. Thank you.

\$\endgroup\$
  • \$\begingroup\$ Why not treat the map as an 'endless map'? Thus the coordinates of the entities can have coords bigger than the actual map size. It means that you only need to adjust your render and collision logic to coord%mapsize. \$\endgroup\$ – Felsir Sep 25 '16 at 7:50
  • \$\begingroup\$ Thank you for your suggestion, Felsir. That way will solve my problem about flocking behavior. But there is a case when the player is considered to be near the border (its position % mapsize is almost about to turn around), half of the screen would have to show the other side. for example (top half of the screen must show the bottom view of the fixed area, and bottom half of the screen must show the top view of the fixed area. Is there a way to solve that? \$\endgroup\$ – valadilene2 Sep 25 '16 at 11:26
  • \$\begingroup\$ See Jon's answer: depending on how your world is constructed you can render it. Worst case your camera needs to render the game in four segments, but there are many ways of achieving this- it starts with how your world is constructed. \$\endgroup\$ – Felsir Sep 25 '16 at 15:43
1
\$\begingroup\$

I am not really understanding how you are implementing your wrapping world rendering. Here is a way to render wrapping worlds.

First, you would get a Start and End X and Y positions of your camera view. The idea is to grab all tiles that are currently in your view, and process/render them.

Going through these values, you run a modulos operation on them in order to wrap the values inside of the game world:

for (int x = startx; x <= endx; x += 1)
{
    for (int y = starty; y >= endy; y -= 1)
    {
        int nx = Helper.Mod (x, World.Width);
        int ny = Helper.Mod (y, World.Height);

        TileData tile = World.GetTile (nx, ny);
        tile.Refresh();
    }
}

The Mod is a slight modification, to account for proper wrapping in both directions:

public static int Mod(int x, int m)
{
    int r = x % m;
    return r < 0 ? r + m : r;
}    

Reposition the tiles using this Mod technique, and they will render at the right position. It doesn't matter if you go in the negative X,Y coordinate area, as this modulos operation will always normalize to your map size.

This method of course, requires you to have a dynamic way to position your Tile objects. I would highly suggest the use of a Tile Pool here.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks, although I don't use the tilemap (only image objects), but just rendering objects is even simpler with this way. Implementing the behavior is still a problem but it is not as hard as before. \$\endgroup\$ – valadilene2 Sep 26 '16 at 7:57
  • \$\begingroup\$ Even if you do not have a tilemap, you are going to have some sort of representation of your level in data. You need to have a way to query those game objects. You may also want to look into possibly implementing a QuadTree to store those object positions in 2d space. That way you would have a mechanism to query your world space, and then process/render those objects using a similar technique as described above. \$\endgroup\$ – jgallant Sep 26 '16 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.