No tengo experiencia en preguntas de desarrollo de juegos, pero como programador. En el lenguaje Scala, puedes tener multitareas escalables con actores, muy estables, según tengo entendido. Incluso puede tener cientos de miles de ellos ejecutándose a la vez sin ningún problema.
Así que pensé, tal vez puedas usarlos como una clase base para 2D-Sprites, para salir del juego que requiere pasar por todos los sprites y moverlos. Básicamente se moverían ellos mismos, impulsados por eventos.
¿Tendría sentido para un juego? ¿Tenerlo multitarea así? Después de todo, se ejecutará en la JVM, aunque eso no debería ser un gran problema hoy en día.
EDITAR:
Después de incursionar por un tiempo, noté que solo hay una ventaja real para esta idea: soporte multinúcleo. Un bucle de juego simple solo se ejecutará en un núcleo y funcionará todo secuencialmente.
Dado que las computadoras modernas, incluso en casa, hoy en día tienen dos o más núcleos incorporados, creo que es una buena idea permitir que los programadores de juegos usen eficientemente los otros núcleos. Después de todo, creo que generalmente el jugador solo tendrá el juego ejecutándose en su máquina de ocho núcleos, entonces, ¿por qué no?
La otra ventaja que veo es que en Scala, puede tener RemoteActors
, que puede tratarse de la misma manera pero ejecutarse en otra computadora. Entonces, quizás esto también pueda simplificar los juegos en red.
Tengo la intención de construir eso en mi motor Scala 2D tan pronto como pueda.
fuente
Respuestas:
No lo intenté, pero soy un programador de Scala, y diría que este no es el mejor enfoque. Los sprites necesitan ser animados sincrónicamente. Los actores no tienen garantías de que se ejecutarán de manera justa: algunos sprites pueden ser más rápidos que otros, lo cual no es lo que quieres. Es posible que desee utilizar una barrera para sincronizarlos, pero entonces, ¿por qué usar actores? Si solo confía en la transmisión de mensajes, implementar este tipo de sincronización (implementar una barrera para más de 1000 actores) es una exageración.
Otro problema es: ¿para qué usarías el paso de mensajes? ¿Necesitas tus sprites para comunicarte? Podría enviar un mensaje del actor principal, diciéndole a cada sprite que se mueva al siguiente cuadro, pero en términos de rendimiento, eso es magnitudes y magnitudes más que invocar métodos directamente e iterar a través de un conjunto de sprites.
Me parece que lo que necesita aquí es una especie de multitarea muy liviana, y ningún mensaje pasa en absoluto. Implementar su propia implementación similar a la de un actor que garantiza la equidad es probablemente la mejor manera de hacerlo si desea garantizar esto, pero eso es demasiado trabajo para muy poca ganancia. Otra cosa a tener en cuenta es la programación reactiva funcional y
scala.react
, creo que es una mejor combinación para este caso de uso.He implementado un motor de juego isométrico 2D en Scala. Solo he usado 1 actor global para actualizar sprites visibles que fueron animados.
Es posible que desee implementar su lógica de juego utilizando actores, por ejemplo, para distribuir cálculos en diferentes partes de su mapa de juego a diferentes actores, de modo que actualicen el estado del juego en paralelo, y ganen una ganancia de rendimiento. No usaría un solo actor por objeto de juego, sino un actor por región. Si va demasiado fino, el rendimiento se ve afectado.
Aún así, si fuera tú, lo intentaría, solo para ver qué pasa.
fuente
¿Cuál sería el evento que los conmueva?
¿Sería un evento que emites una vez por cuadro?
Y si es así, ¿cómo ha cambiado esto el sistema de manera práctica?
Cuando estudié originalmente la orientación a objetos en el contexto de C ++, aprendí que a algunas personas les gustaba pensar en una declaración
xyz.doThis(x)
como `` enviar el mensaje doThis a xyz (con una carga útil de x) y esperar una respuesta inmediata ''. Cuando se ve en este nivel, no hay diferencia intrínseca entre un sistema basado en eventos o mensajes y uno normal de procedimiento.fuente
xyz.doThis(x)
se hace. Creo que esto incluso podría ayudar a acelerar la lógica del juego, especialmente en sistemas de múltiples núcleos.Ese es un enfoque genial para pensar en actualizar los objetos de tu juego. No conozco a Scala, pero le digo que intente y vea cómo resulta, ¡y aún mejor publique sus resultados!
Las principales preguntas que me vienen a la mente son: ¿Cómo manejas con qué frecuencia se actualizan algunos objetos del juego en comparación con otros? ¿Tendrás que preocuparte de que los actores de sprites tomen demasiados ciclos de modo que el sistema de renderizado no tenga tiempo para dibujar un cuadro cada 1/60 | 30 | | 24 de segundo?
Otra cosa a considerar es cómo esto afectará la resolución de las interacciones jugador contra IA que dependen del orden de una secuencia de eventos muy rápidos. Dependiendo del tipo de juego, esto
puede noprobablemente no va a importar mucho.fuente
Bueno, tampoco soy un gran programador, pero no veo ningún problema en tu propuesta. Ni siquiera pensé en tal forma de desarrollar actores.
Puede ser todo un desafío, ya que la IA tiene que ser muy precisa para evitar comportamientos inesperados, pero además de eso, veo que es una muy buena propuesta
fuente
Si por sprite te refieres a la entidad del juego, entonces seguro.
Las entidades del juego nunca deberían dibujarse a sí mismas. Deben actualizar un controlador gráfico que describa dónde y cómo deben dibujarse. El sistema de renderizado o el gráfico de escena o lo que sea que haga el dibujo real. Hay una tarjeta gráfica, además, la tarjeta gráfica debe sincronizarse cada 16 ms. Una configuración como esa simplemente no funciona bien para el procesamiento asincrónico distribuido.
El sistema de renderizado debe ser un actor (o posiblemente un par si eres complicado). Cuando las entidades del juego actualizan el controlador de gráficos, envía mensajes al sistema de representación. El sistema de renderizado puede tomar todo tipo de decisiones y / u optimizaciones, por ejemplo, renderizado por lotes, oclusión, suavizado de jitter de física, etc.
No soy un desarrollador de Scala, pero he hecho bastante con Erlang. Entonces, si parte de mi terminología Scala es incorrecta, por favor perdóname.
fuente