Ok, entonces tengo una gran lista de todas mis entidades que reviso y actualizo. En AS3 puedo almacenar esto como una matriz (longitud dinámica, sin tipo), un vector (con tipo) o una lista vinculada (no nativa). En este momento estoy usando Array pero planeo cambiar a Vector o lista vinculada si es más rápido.
De todos modos, mi pregunta, cuando se destruye una Entidad, ¿cómo debo eliminarla de la lista? Podría anular su posición, empalmarlo o simplemente ponerle una bandera para decir "salta sobre mí, estoy muerto". Estoy agrupando mis entidades, por lo que es muy probable que una entidad que está muerta vuelva a estar viva en algún momento. Para cada tipo de colección, ¿cuál es mi mejor estrategia y qué combinación de tipo de colección y método de eliminación funcionará mejor?
Respuestas:
Almacenaría todas las adiciones / eliminaciones en listas separadas y realizaría esas operaciones después de iterar a través del ciclo de actualización.
fuente
El marco Flixel usa el indicador muerto (en realidad, varios indicadores que determinan si se debe dibujar, actualizar, etc.). Diría que si va a revivir entidades, y si el rendimiento es un problema, use la bandera muerta. En mi experiencia, crear instancias de entidades nuevas es la operación más costosa en el caso de uso que usted describe, y el empalme o la anulación de elementos pueden llevar a la acumulación de memoria dada la recolección de basura a veces arduamente de Flash.
fuente
dead
realmente ayuda con el rendimiento.Si bien algunas técnicas son inherentemente más eficientes que otras, solo importará si se está quedando sin ciclos en su plataforma de destino. Usa cualquier técnica que te permita terminar tu juego más rápido. Mientras tanto, trate de no confiar en la implementación específica de sus estructuras de datos de contenedor y le ayudará a optimizar después si lo necesita.
Solo para abordar algunas de las técnicas ya discutidas por otros aquí. Si el orden de las entidades es importante, entonces una bandera muerta puede permitirle empalmar durante su ciclo de actualización en el siguiente cuadro. p.ej. pseudocódigo muy simple:
Estas son las características de este esquema:
fuente
Hablando en términos de mi experiencia de programación general, el empalme suele ser una operación lenta, que implica cambiar todos los elementos existentes hacia arriba. Creo que establecerlo en nulo sería la mejor solución aquí ; una bandera muerta funcionaría, pero debe tener cuidado de no dejar que su código se vea desordenado.
Sin embargo, en realidad solo estábamos hablando de la agrupación de recursos en la sala de chat. Es una muy buena práctica, y es bueno saber que lo estás haciendo. :)
fuente
Personalmente, usaría una lista vinculada. Iterar sobre una lista de Me gusta es rápido, así como agregar y eliminar elementos. Usar una matriz o un vector sería una buena opción si necesita acceso directo a elementos en la estructura (por ejemplo, acceso a un índice), pero no parece que lo necesite.
Siempre que elimine un elemento de la lista vinculada, puede agregarlo a un grupo de objetos que luego se pueden reciclar para guardar en la asignación de memoria.
He utilizado las estructuras de datos poligonales en varios proyectos y he estado muy contento con ellas.
Editar: Lo siento, creo que la respuesta no fue muy clara en términos de estrategia de eliminación: sugeriría eliminar el elemento de la lista, tan pronto como esté muerto y agregarlo directamente a la estructura de agrupación (reciclaje). Dado que eliminar un elemento de una lista vinculada es muy eficaz, no veo ningún problema al hacerlo.
fuente
next
puntero al nodo después de uno eliminado. Si no quiere la molestia de hacer esto usted mismo, una lista de doble enlace sería la estructura de datos de elección."solo ponle una bandera que diga" salta sobre mí, estoy muerto ". Estoy agrupando mis entidades, por lo que es muy probable que una entidad que está muerta vuelva a estar viva en algún momento"
Creo que respondió su propia pregunta con respecto a esta aplicación específica. Me alejaría de las matrices si alguna vez planea trabajar en ellas además de push y pop. Las listas vinculadas serían una forma más inteligente de hacerlo si planea realizar operaciones pesadas. Dicho todo esto, si planeas volver a integrar la misma entidad en el juego, entonces tiene sentido establecer solo una variable booleana y verificarla durante los bucles de operación del juego.
fuente
Una solución limpia y general que encontré en una biblioteca que usé fue usar un mapa bloqueable.
tienes 2 operaciones
lock()
yunlock()
, mientras iteras sobre el mapalock()
, ahora, a partir de este punto, cada operación que cambie el mapa no tiene efecto, solo se inserta en unaCommandQueue
que se ejecutará una vez que llamesunlock()
.Entonces, eliminar una entidad tendría el siguiente pseudocódigo:
y cuando tu
unlock()
Lo único que debe tener en cuenta es que solo eliminará la entidad después del ciclo.
EDITAR: esta es la solución propuesta por Simon.
fuente
Aquí hay una respuesta que recibí de Liosan :
/gamedev//a/46765/24633
fuente
Tengo dos métodos
Cuando llama a un objeto para que se elimine, realmente establece dos banderas:
1. Uno para decirle al contenedor que un objeto ha sido eliminado
2. Uno para decirle al contenedor qué objetos se han solicitado que se eliminen
Uno usando un vector de objetos
Luego, en la función de actualización, verifique si se ha eliminado un objeto y, en caso afirmativo, repita todos los objetos y elimine los que tienen un indicador de eliminación.
Dos Usando un (puntero a) un vector de objetos.
En la función de actualización, si se va a eliminar un objeto, repita los objetos y agregue los que no se van a eliminar a un nuevo vector. eliminar el vector de objetos y establecer el puntero en el nuevo vector
fuente