2D rpg, active or not active, AI-unit handling

Started by
6 comments, last by ToniKorpela 11 years, 9 months ago
Hello,
I am currently working on a 2d RPG, with an "open world" concept, therefore I have no loading screens and load/unload maps without the user knowing. As seen in the picture below I have 9 maps loaded at one time, and if the user enters a new map (as in the pic, I unload the bottom and right hand maps and load the respective maps in the top and left side). The green rectangle is the view point of the user (the tiles drawn to the screen) and the blue is representing witch AI-units that are considered active (where I run path finding etc).

[attachment=10051:game_tile_engine.png]

The problem that I am having is in regards to the AI-units, I cant figure out how to handle which are active and which are not, how to load and unload them. For the tiles this problem was easily handled, as the tiles are static and do not move around. So I could just store them in a two 2d-arry. But the AI-units are dynamic and move around, how should I store them?

Having a list of all loaded units (for all 9 maps) is to slow, because that is a rather big list to go through every update to see if the unit should be active or not.

I am developing this game in C#(XNA), how would I approach this in regards to a fast way of finding out witch units should be active? speed is of a higher concern then memory. I have tried to explained all parts as simple as I could, but as I have been working on this for a while I have probably forgot something, if so, just ask!
Advertisement
Two options spring to my mind:

1. In each cell, where you store tile info, you could also store a reference (or handle/key) to agent(s) that are at that location. Of course, you would have to update this information in the cells as each agent moves.

2. A smarter collection for storing agents. For example, instead of a list, you could group agents by region, or use a sparse 2d array, or similarly use a dictionary and key (hash) them by coordinate value*. It may take some experimentation to see which data structure provides the needed efficiency.

EDIT: *note that this may require frequent insertions/removals, so depending on how often agents are moved this may or may not be viable.

From the infomation you provided, I would think #1 would be the simplist to implement.
Yay! I like this question, because in multiplayer game the AI units woulds be active all the time. Now in single player game you want to have only those units active that are on the maps currently loaded.

I have small idea for this and it basically goes like this. You have list of AI units for every map. Once the AI unit moves to another map also move it into the maps list of AI units. Now you can easily inactivate those AI units that are on the maps list which you are unloading, basically you do not need to check every AI units position to see if they should be inactivated.
I would do an array with all AI units inside. Every update do an if:
if(AIUnit.onScreen() == true){
AIUnit.setActive(true);
}else{
AIUnit.setActive(false);
}
to know which ones are onscreen is really easy. Just make an rectangle of the screen: Entity ent = new Entity(cameraX,cameraY,screenWidth,screenHeight);
if(ent.collide(AIUnit) == true){
return true;
}else{
return false;
}
this would be slow depending on how many entities you have but if you don't have much then it's fine. If you have a lot then segregate them depending on the area they are based.
Thanks for the response!

I try to implement something similar to what laztrezort suggested. I add variable to my tile code, this will contain a reference to the AI-unit. Every update I will go through the tiles that are within the active AI area and if it contains a unit I will add that AI reference to a list of active AI units (this list will be cleared at the beginning of every update cycle). I will then go trough the list of active units and if they should be moved I move its reference to the appropriate tile.
I disagree about their being active all the time. A function call to get distance from player would work out easily enough.
if(me.distance_from_player(x,y,PlayerID,playerx,playerY < me.range+1)//if my TOTAL distance x-Px, y-Py is less than or equal to my range for instance(i'd use sight distance)
{
//set my AI to active, thus I actively idle, ready to rumble, without wasting processor on my AI.
}

I disagree about their being active all the time. A function call to get distance from player would work out easily enough.
if(me.distance_from_player(x,y,PlayerID,playerx,playerY < me.range+1)//if my TOTAL distance x-Px, y-Py is less than or equal to my range for instance(i'd use sight distance)
{
//set my AI to active, thus I actively idle, ready to rumble, without wasting processor on my AI.
}


That is essentially what I am doing, but not worded in the same way. I have a grid around the player which contain the active AI units (the blue in the picture). It is depending on the position of the player, just described in another way. :)

I disagree about their being active all the time. A function call to get distance from player would work out easily enough.
if(me.distance_from_player(x,y,PlayerID,playerx,playerY < me.range+1)//if my TOTAL distance x-Px, y-Py is less than or equal to my range for instance(i'd use sight distance)
{
//set my AI to active, thus I actively idle, ready to rumble, without wasting processor on my AI.
}


I said that in multiplayer game they should be active all the time, because there are so many players that you would be checking all the time which units should be active or inactive. In a single player game this is different as you might stay on the same map for hours.

This topic is closed to new replies.

Advertisement