Prima di tutto, sono nuovo di LINQ, quindi non conosco bene i dettagli. Sto tentando di usarlo in qualche codice al minuto, e secondo la mia diagnostica sembra essere veloce quanto usare un ciclo for allo stesso modo. Tuttavia, non sono sicuro di quanto sarebbe scalabile in quanto le liste con cui sto lavorando potrebbero aumentare in modo drammatico.Novità di LINQ: è questo il posto giusto per utilizzare LINQ?
Sto usando LINQ come parte di una funzione di rilevamento collisione (che è ancora in lavorazione) e lo sto usando per selezionare l'elenco solo per quelli rilevanti per i controlli.
Ecco la versione LINQ:
partial class Actor {
public virtual bool checkActorsForCollision(Vector2 toCheck) {
Vector2 floored=new Vector2((int)toCheck.X, (int)toCheck.Y);
if(!causingCollision) // skip if this actor doesn't collide
return false;
foreach(
Actor actor in
from a in GamePlay.actors
where a.causingCollision==true&&a.isAlive
select a
)
if(// ignore offscreen collisions, we don't care about them
(actor.location.X>GamePlay.onScreenMinimum.X)
&&
(actor.location.Y>GamePlay.onScreenMinimum.Y)
&&
(actor.location.X<GamePlay.onScreenMaximum.X)
&&
(actor.location.Y<GamePlay.onScreenMaximum.Y)
)
if(actor!=this) { // ignore collisions with self
Vector2 actorfloor=new Vector2((int)actor.location.X, (int)actor.location.Y);
if((floored.X==actorfloor.X)&&(floored.Y==actorfloor.Y))
return true;
}
return false;
}
}
Questo è il mio metodo precedente:
partial class Actor {
public virtual bool checkActorsForCollision(Vector2 toCheck) {
Vector2 floored=new Vector2((int)toCheck.X, (int)toCheck.Y);
if(!causingCollision) // skip if this actor doesn't collide
return false;
for(int i=0; i<GamePlay.actors.Count; i++)
if(// ignore offscreen collisions, we don't care about them
(GamePlay.actors[i].location.X>GamePlay.onScreenMinimum.X)
&&
(GamePlay.actors[i].location.Y>GamePlay.onScreenMinimum.Y)
&&
(GamePlay.actors[i].location.X<GamePlay.onScreenMaximum.X)
&&
(GamePlay.actors[i].location.Y<GamePlay.onScreenMaximum.Y)
)
if(// ignore collisions with self
(GamePlay.actors[i].isAlive)
&&
(GamePlay.actors[i]!=this)
&&
(GamePlay.actors[i].causingCollision)
) {
Vector2 actorfloor=
new Vector2(
(int)GamePlay.actors[i].location.X,
(int)GamePlay.actors[i].location.Y
);
if((floored.X==actorfloor.X)&&(floored.Y==actorfloor.Y))
return true;
}
return false;
}
}
Al minuto, sia eseguito in pochissimo tempo (ma eseguire numerose volte al secondo), ma man mano che il progetto si costruisce e diventa più complesso, questo si troverà ad affrontare molti più oggetti contemporaneamente e il codice per verificare le collisioni sarà più dettagliato.
Il tuo codice è completamente corretto. LINQ è abbastanza performante, estremamente performante in alcuni casi, meno in alcuni altri. La cosa migliore che puoi fare è provare e confrontare. –
"Tuttavia, non sono sicuro di quanto sarebbe scalabile in quanto le liste con cui sto lavorando potrebbero aumentare in modo drammatico". Allora dovresti misurarlo. Dovresti essere in grado di creare facilmente grandi dati di test ed eseguire il tuo codice su questo. – svick
Se sono necessarie prestazioni migliori, è necessario sostituire il rilevamento delle collisioni O (n^2) con un algoritmo che si adatta meglio. – CodesInChaos