Lo difícil de responder a su pregunta es que usted está preguntando a ambos: "¿qué debo hacer ahora, para Pong" y "qué debo hacer más adelante, en un juego genérico"?
Para hacer Pong ni siquiera necesitas las clases de Bola y Paleta, porque básicamente son solo posiciones. Sólo se adhieren algo como esto en su clase de juego:
Vector2 ballPosition, ballVelocity;
float leftPaddlePosition, rightPaddlePosition;
A continuación, sólo actualizar y dibuja en el orden que más le convenga en Update
y Draw
funciones de su juego. ¡Fácil!
Pero, supongamos que desea crear varias bolas, y las bolas tienen muchas propiedades (posición, velocidad, rotación, color, etc.): Es posible que desee hacer una clase Ball
o estructura que pueda instancia (misma va por las paletas).Incluso podría mover algunas funciones a esa clase donde son independientes (una función Draw
es un buen ejemplo).
Pero mantenga el concepto de diseño igual: todo el manejo de la interacción objeto a objeto (es decir, la jugabilidad) ocurre en su clase Game
.
Todo está bien si tienes dos o tres elementos de juego (o clases) diferentes.
Sin embargo, vamos a postular un juego más complicado. Tomemos el juego básico de pong, agreguemos algunos elementos de pinball como mutli-ball y aletas controladas por jugadores. Agreguemos algunos elementos de Snake, digamos que tenemos una "serpiente" controlada por AI, así como algunos objetos de recolección que pueden golpear las bolas o la serpiente. Y por si fuera poco, digamos que las paletas también pueden disparar láser como en Space Invaders y los rayos láser hacen cosas diferentes dependiendo de lo que golpeen.
Golly que es un gran lío de interacción! ¿Cómo vamos a lidiar con eso? ¡No podemos ponerlo todo en el juego!
¡Simple! Hacemos una interfaz (o una clase abstracta o una clase virtual) de la que se derivará cada "cosa" (o "actor") en nuestro mundo del juego. He aquí un ejemplo:..
interface IActor
{
void LoadContent(ContentManager content);
void UnloadContent();
void Think(float seconds);
void UpdatePhysics(float seconds);
void Draw(SpriteBatch spriteBatch);
void Touched(IActor by);
Vector2 Position { get; }
Rectangle BoundingBox { get; }
}
(Esto es sólo un ejemplo no hay "una verdadera interfaz de agente" que funcione para todos los juegos, tendrá que diseñar su propio Esto es por lo que Don 'me gusta DrawableGameComponent
.)
Tener una interfaz común permite que Game solo hable de actores, en lugar de tener que conocer todos los tipos de tu juego. Simplemente se deja de hacer las cosas comunes a todos los tipos - detección de colisiones, dibujo, actualización, carga, descarga, etc.
Una vez que estés en el actor, puede empezar a preocuparse por tipos específicos de actor. Por ejemplo, esto podría ser un método en el Paddle
:
void Touched(IActor by)
{
if(by is Ball)
((Ball)by).BounceOff(this.BoundingBox);
if(by is Snake)
((Snake)by).Kill();
}
Ahora, me gusta hacer que la pelota rebotó por el Paddle, pero en realidad es una cuestión de gusto. Podrías hacerlo al revés.
Al final deberías ser capaz de incluir a todos tus actores en una gran lista que simplemente puedes repetir en Game.
En la práctica, puede terminar teniendo múltiples listas de actores de diferentes tipos por motivos de rendimiento o simplicidad de código. Esto está bien, pero en general, intenta mantenerte en el principio de Juego solo sabiendo acerca de los actores genéricos.
Los actores también pueden querer consultar qué otros actores existen por varias razones. Así que dale a cada actor una referencia al juego y haz que la lista de actores sea pública en el juego (no es necesario ser súper estricto sobre público/privado cuando estás escribiendo código de juego y es tu propio código interno)
Ahora, incluso podría ir un paso más allá y tener múltiples interfaces. Por ejemplo: uno para renderizado, uno para scripting y AI, uno para física, etc. Luego, tiene múltiples implementaciones que se pueden componer en objetos.
Esto se describe en detalle en this article. Y tengo un ejemplo simple en this answer. Este es un próximo paso apropiado si comienzas a encontrar que tu interfaz de actor único está empezando a convertirse en más un "árbol" de clases abstractas.
Creo que cuando dices "lógica" en realidad quieres decir "arquitectura". –
(Sigo haciendo referencia a esta pregunta, así que voy a arreglar el título yo mismo ...) –
Esto es más adecuado para http://gamedev.stackexchange.com/ – AlexFoxGill