Hemos discutido la programación orientada a objetos para los desarrolladores de juegos en general y los principios OOP específicos de cohesión y acoplamiento. Ahora echemos un vistazo a encapsulamiento y cómo ayuda a mantener el código acoplado de forma flexible y más fácil de mantener.
Nota: Aunque este Consejo rápido se explica utilizando Java, debería poder usar las mismas técnicas y conceptos en casi cualquier entorno de desarrollo de juegos.
La encapsulación es el principio de la ocultación de la información. Eso es el implementación (el funcionamiento interno) de un objeto está oculto del resto del programa.
Un ejemplo popular que escuchará para la encapsulación es conducir un automóvil. ¿Necesita saber exactamente cómo funcionan todos los aspectos de un automóvil (motor, carburador, alternador, etc.)? No, debe saber cómo usar el volante, los frenos, el acelerador, etc..
Otro ejemplo es buscar un valor en una matriz. En Java, puedes hacer lo siguiente:
int myArray [] = 1, 2, 3, 5, 7, 9, 11, 13; Arrays.asList (myArray) .contains (11);
El código anterior volverá cierto
si el valor 11
es en myArray
, de lo contrario volverá falso
. Cómo hace el contiene ()
método de trabajo? ¿Qué técnica de búsqueda utiliza? ¿Preordena la matriz antes de buscar? La respuesta es No importa Porque la implementación exacta del método está oculta..
La encapsulación ayuda a crear código que está acoplado libremente. Debido a que los detalles están ocultos, reduce la capacidad de otros objetos para modificar directamente el estado y el comportamiento de un objeto..
También es de gran ayuda cuando debe cambiar el tipo de datos de una variable. Digamos que usted decidió usar un Cuerda
para realizar un seguimiento del tiempo en formato "hh: mm: ss". Después de un rato, te das cuenta de que un En t
representar segundos podría ser un mejor tipo de datos para el tiempo. No solo debe cambiar el tipo de datos en el objeto, sino también cada vez que hace referencia al tiempo del objeto en todo el programa.!
En su lugar, puede usar lo que se conoce como funciones getter y setter. Getters y setters son generalmente funciones pequeñas que devuelven y establecen una variable respectivamente. Una función getter para obtener el tiempo se vería como sigue:
public String getTime () return time;
El captador devolverá un Cuerda
valor: la variable hora
. Ahora cuando queremos cambiar hora
a un int, en lugar de cambiar todas las llamadas al captador, podemos cambiar la función del captador para cambiar el En t
tipo de datos en una Cuerda
tipo de datos.
public String getTime () // divide el tiempo en horas, minutos y segundos int horas = tiempo / 3600; int resto = tiempo% 3600; int minutos = resto / 60; int segundos = resto% 60; // // combina el resultado en una cadena de caracteres separados por dos puntos + ":" + minutes + ":" + seconds;los
%
operador se conoce como el operador de módulo y devuelve el resto de una división. Asi que 10% 3
volvería 1
ya que 10/3 = 3
con un resto de 1
. La función getter ahora devuelve un Cuerda
y ninguna de las llamadas a la función tiene que cambiar. El código es por lo tanto más mantenible..
Volvamos al ejemplo de un barco disparando una bala introducida en el artículo de acoplamiento. Recordemos que definimos una nave de la siguiente manera:
/ ** * La clase de envío * / clase de envío público / ** * Función: realiza el comportamiento (tarea) de girar el envío * / void público rotate () // Código que hace girar el envío / ** * Función - realiza el comportamiento (tarea) de mover el Barco * / public void move () // Código que mueve el barco / ** * Función - realiza el comportamiento (tarea) de disparar la pistola del Barco * / fuego de vacío público ( ) // Código que hace que el barco dispare una bala
Para que el barco dispare una bala, todo lo que tendrías que hacer es llamar ship.fire ()
. La forma en que el código implementa el disparo de una bala no es importante, porque lo único que nos importa es disparar una bala. De esta manera, si desea cambiar el código para disparar una explosión láser, solo tiene que cambiar el método fuego()
y no todas las llamadas a ship.fire ()
.
Esto le permite tener la capacidad de cambiar cualquier aspecto de cómo funciona la nave sin tener que cambiar la forma en que se usa el objeto de la nave en cualquier otro lugar..
Tetris tiene diferentes maneras de lidiar con las líneas de compensación. El encapsular el comportamiento de borrar una línea le permitirá cambiar rápidamente el método que usa sin tener que volver a escribir cada uso de la misma. Esto incluso te permitirá cambiar el método de línea clara para crear diferentes modos de juego en el juego..
Hay una característica más de la encapsulación que trata de ocultar el acceso a un objeto. En muchas ocasiones, no desea el acceso externo al estado o comportamiento de un objeto, por lo que desea ocultarlo de cualquier otro objeto. Para hacer esto, puede usar modificadores de nivel de acceso que dan u ocultan el acceso a los estados y comportamientos de los objetos..
Los modificadores de nivel de acceso definen dos niveles de acceso:
público
- Cualquier objeto puede acceder en cualquier momento a la variable o función..privado
- Solo el objeto que contiene la variable o función puede acceder a ella..(Hay un tercer nivel - protegido
- pero lo cubriremos en un futuro post.)
Recordemos que un fantasma tenía estados de:
color
nombre
estado
dirección
velocidad
... y se definió de la siguiente manera:
/ ** * La clase fantasma * / clase pública fantasma / ** * Función - mueve el fantasma * / movimiento público () // Código que mueve el fantasma en la dirección actual / ** * Función - cambiar fantasma direction * / public void changeDirection () // Código que cambia la dirección del Ghost / ** * Function - change Ghost speed * / public void changeSpeed () // Code que cambia la velocidad del Ghost / ** * Function - cambiar el color del fantasma * / public void changeColor () // Código que cambia el color del fantasma / ** * Función - cambiar el estado del fantasma * / public void changeState () // Código que cambia el estado del fantasma // Esta función también llamará a las tres funciones de changeDirection (), changeSpeed (), y changeColor ()
Ya que cambiar color ()
, changeSpeed ()
, y cambia la direccion()
son funciones de ayuda y se supone que no se puede acceder a ellas desde ningún otro lugar, pero dentro de la clase, podemos definirlas como privado
funciones Todos los estados del fantasma también pueden ser declarados. privado
ya que tampoco deberían ser modificados desde fuera de la clase, y solo se puede acceder a ellos a través de las funciones getter y setter. Esto cambiaría la clase para ser definida como sigue:
/ ** * The Ghost Class * / public class Ghost // Ghost states privado Color de cadena; nombre de la cadena privada; privado booleano es disputable; direccion Vector privada; velocidad int privada; / ** * Función: mueve el Fantasma * / public void move () // Código que mueve al fantasma en la dirección actual / ** * Función - cambia la Dirección del Fantasma * / private void changeDirection () // Codifique que cambia la dirección del Fantasma / ** * Función: cambia la velocidad del Fantasma * / private void changeSpeed () // Código que cambia la velocidad del Ghost / ** * Función - cambia el color del Ghost * / private void changeColor () // Código que cambia el color del Fantasma / ** * Función: cambiar el estado del Fantasma * / public void changeState () // Código que cambia el estado del Fantasma // Esta función también llamará a las tres funciones de changeDirection, changeSpeed, y changeColor / ** * Getters y setters * /…
La encapsulación puede ayudar a crear un código más mantenible al ayudar a prevenir el efecto dominó de los cambios de código. También ayuda a crear código acoplado libremente al reducir el acceso directo al estado y comportamiento de un objeto.
En el siguiente Consejo rápido, discutiremos el principio de abstracción y cómo puede ayudar a reducir la redundancia de código. Síganos en Twitter, Facebook o Google+ para mantenerse al día con las últimas publicaciones..