public void init(int divisionsOverWidth) { for (int i = 0; i < managedDivisions.Length; i++) { managedDivisions[i] = new CollisionDivision(); } width = chart.getAIMesh().getWidth(); height = chart.getAIMesh().getHeight(); // Get the square root of the division count. This is why it requires to be squared. (It's a map of 3x3 by default) //CORE_INFO("CollisionHandler has %d divisions.", divisionsOverWidth*divisionsOverWidth); divisionCount = divisionsOverWidth; // Setup the division dimensions for (int y = 0; y < divisionsOverWidth; y++) { for (int x = 0; x < divisionsOverWidth; x++) { managedDivisions[y * divisionsOverWidth + x].min.X = x * (width / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].min.Y = y * (height / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].max.X = (x + 1) * (width / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].max.Y = (y + 1) * (height / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].objectCount = 0; } } }
public void init(int divisionsOverWidth) { for (int i = 0; i < managedDivisions.Length; i++) managedDivisions[i] = new CollisionDivision(); width = chart.getAIMesh().getWidth(); height = chart.getAIMesh().getHeight(); // Get the square root of the division count. This is why it requires to be squared. (It's a map of 3x3 by default) //CORE_INFO("CollisionHandler has %d divisions.", divisionsOverWidth*divisionsOverWidth); divisionCount = divisionsOverWidth; // Setup the division dimensions for (int y = 0; y < divisionsOverWidth; y++) { for (int x = 0; x < divisionsOverWidth; x++) { managedDivisions[y * divisionsOverWidth + x].min.X = x * (width / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].min.Y = y * (height / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].max.X = (x + 1) * (width / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].max.Y = (y + 1) * (height / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].objectCount = 0; } } }
public void addObject(GameObject obj) { if (divisionCount == -1) // If we have not initialised.. { Logger.LogCoreError("Tried to add an object before we initialised the CollisionHandler!"); return; } if (obj.getMap() != chart) { Logger.LogCoreInfo("Map is adding an object that is not healthy. His map pointer is " + obj.getMap() + " (not " + chart + "). Not adding it."); return; } float divX = obj.getPosition().X / (float)(width / divisionCount); // Get the division position. float divY = obj.getPosition().Y / (float)(height / divisionCount); int divi = (int)divY * divisionCount + (int)divX; if (divX < 0 || divX > divisionCount || divY < 0 || divY > divisionCount) // We're not inside the map! Add to the unmanaged objects. { Logger.LogCoreError("Object spawned outside of map. (" + obj.getPosition().X + ", " + obj.getPosition().Y + ")"); //addUnmanagedObject(object); } else { addToDivision(obj, (int)divX, (int)divY); CollisionDivision curDiv = managedDivisions[divi]; bool a = false, b = false; if (Math.Abs(obj.getPosition().X - curDiv.max.X) < obj.getCollisionRadius()) // Are we in the one to the right? { addToDivision(obj, (int)divX + 1, (int)divY); // Add it there too. } if (Math.Abs(obj.getPosition().X - curDiv.min.X) < obj.getCollisionRadius()) // Maybe on the left? { a = true; addToDivision(obj, (int)divX - 1, (int)divY); } if (Math.Abs(obj.getPosition().Y - curDiv.max.Y) < obj.getCollisionRadius()) // Are we touching below us? { addToDivision(obj, (int)divX, (int)divY + 1); } if (Math.Abs(obj.getPosition().Y - curDiv.min.Y) < obj.getCollisionRadius()) // Or above? { b = true; addToDivision(obj, (int)divX, (int)divY - 1); } if (a && b) // If we are touching all four, add the left-upper one. { b = true; addToDivision(obj, (int)divX - 1, (int)divY - 1); } } }
private void correctDivisions(int pos) { CollisionDivision curDiv = managedDivisions[pos]; for (int j = 0; j < curDiv.objects.Count; j++) // For all objects inside this division { var o = curDiv.objects[j]; if (o != null) //if (o->isMovementUpdated()) // Only check if they moved around. { while (o.getMap().getId() != chart.getId()) { Logger.LogCoreWarning("I have found an object that is not healthy. His map pointer is " + o.getMap().getId() + " (not " + chart.getId() + "). Removing it from the database (" + j + "/" + curDiv.objects.Count + " in div " + pos + ")."); removeObject(o); if (j < curDiv.objects.Count) { o = curDiv.objects[j]; } else { break; } } // If they are no longer in this division.. if ((o.getPosition().X - o.getCollisionRadius() > curDiv.max.X || o.getPosition().Y - o.getCollisionRadius() > curDiv.max.Y || o.getPosition().X + o.getCollisionRadius() < curDiv.min.X || o.getPosition().Y + o.getCollisionRadius() < curDiv.min.Y)) { removeFromDivision(o, pos); // Remove them from it. addObject(o); // Reset in what divisions this object is. } // If they've entered another division, but not left this one yet.. else if ((o.getPosition().X + o.getCollisionRadius() > curDiv.max.X || o.getPosition().Y + o.getCollisionRadius() > curDiv.max.Y || o.getPosition().X - o.getCollisionRadius() < curDiv.min.X || o.getPosition().Y - o.getCollisionRadius() < curDiv.min.Y)) { addObject(o); // Reset in what divisions this object is. } } } }
public void getDivisions(GameObject obj, CollisionDivision[] divs, out int divCount) { for (int i = 0; i < 4; i++) // Prepare the divisions { divs[i] = null; } divCount = 0; // How many divisions the object is in. float divX = obj.getPosition().X / (float)(width / divisionCount); float divY = obj.getPosition().Y / (float)(height / divisionCount); int divi = (int)divY * divisionCount + (int)divX; // Current division index if (divY >= 0 && divY < divisionCount) // If we're inside the map { divs[divCount] = managedDivisions[divi]; divCount++; } // Below is same principle from addObject. bool a = false, b = false; var curDiv = managedDivisions[divi]; if (Math.Abs(obj.getPosition().X - curDiv.max.X) < obj.getCollisionRadius() && divX + 1 >= 0 && divX + 1 < divisionCount) { divs[divCount] = managedDivisions[(int)divY * divisionCount + (int)divX + 1]; divCount++; } else if (Math.Abs(obj.getPosition().X - curDiv.min.X) < obj.getCollisionRadius() && divX - 1 >= 0 && divX - 1 < divisionCount) { divs[divCount] = managedDivisions[(int)divY * divisionCount + (int)divX - 1]; divCount++; a = true; } if (Math.Abs(obj.getPosition().Y - curDiv.max.Y) < obj.getCollisionRadius() && divY + 1 >= 0 && divY + 1 < divisionCount) { divs[divCount] = managedDivisions[(int)divY * divisionCount + (int)divX + 1]; divCount++; } else if (Math.Abs(obj.getPosition().Y - curDiv.min.Y) < obj.getCollisionRadius() && divY - 1 >= 0 && divY - 1 < divisionCount) { divs[divCount] = managedDivisions[(int)divY * divisionCount + (int)divX + 1]; divCount++; b = true; } if (a && b && divX + 1 >= 0 && divX + 1 < divisionCount) { divs[divCount] = managedDivisions[(int)divY * divisionCount + (int)divX + 1]; divCount++; } }