locked
Pregunta sobre eliminar objetos de la memoria. RRS feed

  • Pregunta

  • Hola a todos,

    les planteo un poco el problema. Estoy haciendo un juego cualquiera, en el que quiero que, desde un punto, se lance un objeto en línea recta cada vez que se pulse una tecla, pero claro, no quiero que cuando salga de la pantalla el objeto siga aumentando la posicion y cargado en memoria, pues con 1 objeto lanzado vale, pero si se lanzan diez mil objetos, la cosa cambia.

    La pregunta es cómo puedo hacer eso, que el objeto deje de dibujarse y se elimine de la memoria. Realmente no se si la pregunta tiene sentido, o si el objeto cuando sale de la pantalla deja de consumir memoria. En cualquier caso, espero que me puedan ayudar, muchas gracias.

    sábado, 10 de noviembre de 2012 11:53

Respuestas

  • El mayor problema de los juegos en XNA para Xbox y para WP es el Garbage Collector, que si no tienes cuidado puede causar que tu juego vaya a saltos. Para esto, tienes dos alternativas, pero en este caso para ti la mejor es utilizar pools de objetos. Lo que haces es reservar un array o una lista de por ejemplo, balas, y cuando se sale una bala de pantalla le pones un flag que indique que está muerta. Cuando el jugador quiere crear una bala nueva, buscas en el array una bala que esté marcada como muerta, y la reutilizas (obviamente esto significa que no puedes tener más de X balas activas a la vez).

    Este enlace de la Wikipedia explica muy bien el patrón pool de objectos:

    http://en.wikipedia.org/wiki/Object_pool_pattern

    Y este artículo de Shawn Hargreaves explica como diseñar tu juego para que el GC no te de problemas.

    http://blogs.msdn.com/b/shawnhar/archive/2007/07/02/twin-paths-to-garbage-collector-nirvana.aspx

    Un saludo!


    Vicente Cartas Espinel - MVP XNA/DirectX

    Blog about C# and XNA Development

    Blog about Role Playing Games

    • Marcado como respuesta AleDonzok lunes, 12 de noviembre de 2012 18:51
    domingo, 11 de noviembre de 2012 2:29
    Moderador

Todas las respuestas

  • El mayor problema de los juegos en XNA para Xbox y para WP es el Garbage Collector, que si no tienes cuidado puede causar que tu juego vaya a saltos. Para esto, tienes dos alternativas, pero en este caso para ti la mejor es utilizar pools de objetos. Lo que haces es reservar un array o una lista de por ejemplo, balas, y cuando se sale una bala de pantalla le pones un flag que indique que está muerta. Cuando el jugador quiere crear una bala nueva, buscas en el array una bala que esté marcada como muerta, y la reutilizas (obviamente esto significa que no puedes tener más de X balas activas a la vez).

    Este enlace de la Wikipedia explica muy bien el patrón pool de objectos:

    http://en.wikipedia.org/wiki/Object_pool_pattern

    Y este artículo de Shawn Hargreaves explica como diseñar tu juego para que el GC no te de problemas.

    http://blogs.msdn.com/b/shawnhar/archive/2007/07/02/twin-paths-to-garbage-collector-nirvana.aspx

    Un saludo!


    Vicente Cartas Espinel - MVP XNA/DirectX

    Blog about C# and XNA Development

    Blog about Role Playing Games

    • Marcado como respuesta AleDonzok lunes, 12 de noviembre de 2012 18:51
    domingo, 11 de noviembre de 2012 2:29
    Moderador
  • Mi respuesta es prácticamente igual a la de Vicente, pero te diré como lo haría yo:

    Como dices, al pulsar una tecla se genera un proyectil en línea recta, yo para los proyectiles crearía una clase para crear los proyectiles y un List para almacenarlos en lugar de un array, para hacer el código un poco menos restringido, este segundo es muy importante, por que es la forma que usarás para identificar el proyectil que se a añadido en tiempo de ejecución. Bien.

    - La clase:  Cuando pulsas la tecla creas el proyectil, que ya tendrá su posición y todos su parámetros, pero tal cual no aparecerá en pantalla, para que aparezca, tendrás que añadir el proyectil que añades dinámicamente al pulsar una tecla a la lista de items del game principal con < Game1.Items.Add(Proyectil); > Bien, con esto generamos las balas dinámicamente, supongo que hasta hay ya lo tienes. Ahora es cuando entra en juego la lista de balas.

    - El List: La lista de balas te va a ayudar a identificar cada bala que añades dinámicamente, ya que al añadirlas al List se le añade un identificador a cada objeto de la lista en función del orden en el que se añaden empezando desde el <0>. Con esto en lugar de añadir la bala directamente a los items del Game principal, añades el objeto de la lista de balas, ¿Como? < Game.Items.Add( ListaBalas[ListaBalas.Count - 1] ); >

    Ahora depende de ti el algoritmo que uses para identificar cada bala, yo suelo utilizar ciclos for, dentro colocas una condición en la que diga que si la bala X está fuera de la pantalla la elimine de la lista de objetos del Game principal.

    Espero haber te sido de ayuda. Un saludo.

    • Propuesto como respuesta JoseSoftware sábado, 24 de noviembre de 2012 17:59
    sábado, 24 de noviembre de 2012 17:57
  • Un apunte sobre los List es que genera basura. Internamente List utiliza arrays, y cada ciertos elementos cuando el List cambia de tamaño ese array se tira y se utiliza otro nuevo. Por eso los pools normalmente se hacen con arrays (o te creas el List de un tamaño inicial y te ocupas que no cambie de ese tamaño nunca).

    Vicente Cartas Espinel - MVP XNA/DirectX

    Blog about C# and XNA Development

    Blog about Role Playing Games

    sábado, 24 de noviembre de 2012 18:32
    Moderador