public Thing ColisionaConThing(Thing thingToEvaluate, Vector2 center, Vector2 size, float rotationInDegress) { Sector centerSector = GetSectorEnPosicion(center); Thing thingCollided = centerSector.CollidesWithThing(thingToEvaluate, center, size, rotationInDegress); if (thingCollided == null) { //Ningun thing deberia tener un tamaño mayor al de un sector, debido a lo cual con chequear la colisión contra los things //que esten en los sectores que rodean al sector destino alcanza para asegurarme de que no hay colision con ningun thing SectorID centerSectorID = centerSector.SectorID; for (int x = centerSectorID.X - 1; x <= centerSectorID.X + 1; x++) { for (int y = centerSectorID.Y - 1; y <= centerSectorID.Y + 1; y++) { if (x != centerSectorID.X || y != centerSectorID.Y) { Sector sec = GetSector(new SectorID(x, y)); thingCollided = sec.CollidesWithThing(thingToEvaluate, center, size, rotationInDegress); if (thingCollided != null) { return(thingCollided); } } } } } return(thingCollided); }
public void Procesar(float elapsedSeconds, Vector2 centroDesdeElCualProcesar, int sectoresAledaniosAProcesar) { //Mantengo los things activos en un vector aparte para asegurarme de procesarlos siempre en el mismo orden, ya que si se procesan en orden //cambiante, puede ocurrir que objetos que normalmente no colisionarian colisionen, por ejemplo: //- El objeto A esta a una unidad del objeto B //- Proceso el objeto B, avanza una unidad //- Proceso el objeto A, avanza una unidad //Ahora, si proceso el objeto B primero, va a colisionar con el objeto A, ya que el objeto A no se va //a haber desplazado, por lo tanto produciendo una falsa colisión. //Para asegurarme de no procesar 2 veces un mismo objeto, guardo en cada objeto un identificador de "ID de Proceso", //que no es ni mas ni menos que un long (64 bits) que incremento cada vez que se completa un ciclo de proceso, si bien //no es imposible que se produzca un wrap-around del contador de 64 bits, la probabilidad de que justo coincida con uno usado antes //en un objeto justo al momento de procesar, y que por este motivo se pierda de procesar un ciclo, se podria decir que es infima. //Igualmente, suponiendo que se produzcan 1000 procesos por segundo, eso nos deja con un total de 18446744073709551 segundos (2^64 / 1000) antes de que se empiecen //a repetir, y son 584942417 años.. asi que se podria decir que no deberia pasar. //Proceso los things activos foreach (Thing thing in thingsActivos.ToArray()) //Hago un .ToArray() para trabajar sobre una copia del vector { if (!thing.Eliminado && thing.identificadorProcesado != identificadorProcesado) { thing.identificadorProcesado = identificadorProcesado; thing.Procesar(elapsedSeconds); } } //Ahora proceso los things en los sectores cercanos SectorID sectorIDCentro = GetSectorEnPosicion(centroDesdeElCualProcesar).SectorID; int fromSectorX = sectorIDCentro.X - sectoresAledaniosAProcesar; int toSectorX = sectorIDCentro.X + sectoresAledaniosAProcesar; int fromSectorY = sectorIDCentro.Y - sectoresAledaniosAProcesar; int toSectorY = sectorIDCentro.Y + sectoresAledaniosAProcesar; for (int x = fromSectorX; x <= toSectorX; x++) { for (int y = fromSectorY; y <= toSectorY; y++) { GetSector(new SectorID(x, y)).Procesar(elapsedSeconds, identificadorProcesado); } } //Finalmente proceso los things que se encuentren en sectores con things activos foreach (Sector sec in new List <Sector>(sectoresConThingsActivos.Keys)) { if (sec.SectorID.X < fromSectorX || sec.SectorID.X > toSectorX || sec.SectorID.Y < fromSectorY || sec.SectorID.Y < toSectorX) { sec.Procesar(elapsedSeconds, identificadorProcesado); } } identificadorProcesado++; }
public Sector GetSector(SectorID sectorID) { Sector sector; if (dicSectores.TryGetValue(sectorID, out sector) == false) { sector = generador.CrearSector(sectorID); } return(sector); }
public Sector(Galaxia galaxia, SectorID sectorID, Faccion faccion) { this.galaxia = galaxia; this.sectorID = sectorID; this.faccion = faccion; tamanio = new Vector2(TamanioSector, TamanioSector); centro = new Vector2(SectorID.X * TamanioSector, SectorID.Y * TamanioSector); CrearEstrellas(); }
public Sector GetSectorEnPosicion(Vector2 position) { int sectorIDx, sectorIDy; Math.Sign( //if (position.X >= 0.0f) sectorIDx = (int)(position.X + Math.Sign(position.X) * Sector.TamanioSector / 2) / Sector.TamanioSector); //else // sectorIDx = (int)((position.X - Sector.SectorSize / 2) / Sector.SectorSize); //if (position.Y >= 0.0f) sectorIDy = (int)((position.Y + Math.Sign(position.Y) * Sector.TamanioSector / 2) / Sector.TamanioSector); //else // sectorIDy = (int)((position.Y - Sector.SectorSize / 2) / Sector.SectorSize); SectorID sectorID = new SectorID(sectorIDx, sectorIDy); return(GetSector(sectorID)); }
public bool SectorCargado(SectorID sectorID) { return(dicSectores.ContainsKey(sectorID)); }