He estado estudiando y haciendo pequeños juegos por un tiempo, y he decidido últimamente que trataría de desarrollar juegos para Android.¿La mejor manera de separar la lógica del juego de la representación para un juego rápido para Android con OpenGL?
Para mí, saltar de código C++ nativo a Android Java no fue tan difícil, pero me da dolores de cabeza pensar cómo podría mantener la lógica separada de la representación.
He estado leyendo por aquí y en otros sitios que:
Es mejor no crear otro hilo para ello, sólo porque voluntad Android con seguridad no tendrá problemas para su procesamiento.
Significado del código sería algo como esto:
public void onDrawFrame(GL10 gl) {
doLogicCalculations();
clearScreen();
drawSprites();
}
Pero no estoy seguro de si eso sería el mejor enfoque. Dado que no creo que me guste cómo se verá si pongo mi lógica dentro del método GLRenderer::onDrawFrame
. Hasta donde yo sé, este método está destinado a dibujar, y puedo ralentizar los cuadros si pongo lógica allí. Sin mencionar que daña los conceptos de POO en mi comprensión.
creo que el uso de hilos podría ser cierto, esta es la forma en que estaba planeando:
Actividad principal:
public void onCreate(Bundle savedInstanceState) {
//set fullscreen, etc
GLSurfaceView view = new GLSurfaceView(this);
//Configure view
GameManager game = new GameManager();
game.start(context, view);
setContentView(view);
}
GameManager:
OpenGLRenderer renderer;
Boolean running;
public void start(Context context, GLSurfaceView view) {
this.renderer = new OpenGLRenderer(context);
view.setRenderer(this.renderer);
//create Texturelib, create sound system...
running = true;
//create a thread to run GameManager::update()
}
public void update(){
while(running){
//update game logic here
//put, edit and remove sprites from renderer list
//set running to false to quit game
}
}
y, finalmente, OpenGLRenderer:
ListOrMap toDraw;
public void onDrawFrame(GL10 gl) {
for(sprite i : toDraw)
{
i.draw();
}
}
Esta es una idea aproximada, no completamente completa. Este patrón lo mantendría todo separado y se vería un poco mejor, pero ¿es el mejor para el rendimiento?
Mientras investigué, la mayoría de los ejemplos de juegos con subprocesos utilizan canvas o surfaceview, esos no se adaptarán a mi caso, porque estoy usando OpenGLES.
Así que aquí están mis preguntas:
Cuál es la mejor manera de separar mi lógica juego de la prestación cuando se utiliza OpenGLES? Enhebrando mi aplicación ? Ponga la lógica en un método separado y simplemente llámelo desde el método de sorteo?
¡Gran respuesta Steve, gracias!Creo que incluso si no me gusta estropear el diseño, seguiré el # 1. Mi juego está activo, pero no hay cálculos pesados sobre él, como la física o una gran cantidad de comprobación de colisión. Solo para estar seguro de mis pensamientos, mi enfoque de enhebrar la pregunta sería correcto si lo elijo (escritura de hilo lógico en un mapa sincronizado y el hilo de renderizado leyéndolo). –
Oh, una cosa más. La gente me dijo que limite mis actualizaciones lógicas a 30 fps, ¿este es el caso también para renderizar? ¿Debería limitar la función completa a esperar 33 ms por cada actualización, o simplemente actualizar la lógica si se ha pasado 33 ms desde la última actualización? –
No creo que tengas que limitarlo, pero quizás no esperes algo mejor que eso en algunos teléfonos. Esto se debe a que la velocidad de fotogramas de algunos de los primeros teléfonos HDPI (creo que en el momento del Droid 1) era limitada, lo que significa que no podían dibujar una pantalla llena de píxeles más de 30 veces por segundo. Tal vez la GPU pueda generar cuadros más rápido que eso, pero la CPU no puede moverlos a la pantalla lo suficientemente rápido. Este no es el caso en los teléfonos más nuevos, creo. –