Ir al contenido principal

Juego de la Serpiente con Java Swing

En esta entrada les voy a mostrar como hice el juego de la serpiente. Cuando tenía 15 años lo intente hacer y en ese momento lo ví como algo extremadamente complejo.  En su momento no vi mucha información de como hacer el juego ( o no supe encontrar ) , y por si alguien está en esta situación , aquí va mi aportación para intentar aclarar sus dudas.
   He visto muchos códigos que lo han hecho mucho mejor, dibujando en el Frame y mucho más trabajado, pero yo personalmente soy partidiario de que siempre es mejor ver las cosas desde su nivel más simple, y una vez entendida la idea, ya luego pasarla a otra cosa, darle mejor aspecto y adornos son valores añadidos.
Para el que no sepa como funciona el juego de la serpiente ( cosa que dudo , todos tuvimos un Nokia ) , es una serpientita a la que le van apareciendo frutas , ella va comiendo y se va haciendo grande, hasta que llega un momento que se hace muy difícil controlarla porque es demasiado grande y chocamos con nosotros mismos.

¿Qué he usado ?

He usado un JFrame con un JPanel en su interior , lleno de JButton . Importante, quitar el foco a los JButtons mientras se crean , si no , estos tendrán el foco y no podremos mover la serpiente.

¿En qué se basa ?

El juego de la serpiente basicamente es una cuadricula ( un array bidimensional ) de unas dimensiones. Es decir , por ejemplo , 22 x 22 .
Situamos un punto en la cuadricula que será la fruta y otro punto que será la serpiente. Y empezamos a mover la serpiente.

¿ Cómo la hacemos caminar ?

Para que la serpiente se mueva , yo lo que hice fue un bucle principal, que comprueba siempre en que dirección va la serpiente, hacia arriba, abajo , derecha , izquierda , que son unas variables booleanas que se ponen a true cuando pulso el cursor del teclado.
En este bucle, si la cabeza de la serpiente va hacia arriba, decrementa Y ( y--) , si va hacia abajo incrementa Y ( y++ ) , para izquierda y derecha igual pero con la coordenada X , izquierda decrementa X ( x-- ) y para la derecha incrementa X ( x++ ) . Luego otro factor importante es que si la serpiente esta caminando hacia la izquierda al pulsar derecha no me tiene que dejar , porque si no la serpiente se atravesaría a si misma y eso no está permitido en el juego, lo mismo para arriba y abajo. Por lo tanto hay otras variables que controlan esto.

Vale ... bien , ¿ Pero como hace el efecto de movimiento?

Pues muy fácil, antes de mover la serpiente , tienes que intercambiar sus valores desde el final ( la cola de la serpiente ) hasta la cabeza - 1 ( llamemosla cuello ... ) desde cola al cuello de la serpiente , y en la cabeza , poner la nueva posición. Ponemos todo el tablero en gris de nuevo y repinto la serpiente.
Lo que hago es que voy recorriendo las coordenadas de la serpiente ( cada cuerpo ) obtengo sus coordenadas y en esas mismas pinto en el tablero de botones. Les doy un color de fondo rojo y así sucesivamente, porque si recuerdas ... el bucle estará comprobando la dirección hacia la que va la serpiente e irá sumando o restando valores de Y o X. Y al estar repintando el tablero , da la sensación de que "está viva".

Y ¿Como la hago crecer ?

Pues bien, en todo momento voy mirando donde está la cabeza de la serpiente ( snakeBody.get(0).getPositionY() , snakeBody.get(0).getPositionX() y compruebo si el tablero ( los JButtons ) tiene el background Amarillo en las mismas coordenadas de la cabeza, si lo tiene, es que ha llegado a una fruta y ahí creo un cuerpo nuevo con las posiciones "Y" "X" de la fruta ( JButton con fondo amarillo ), y cuando el cuerpo de la serpiente haya pasado por encima de donde está la fruta  , justo después , añado el cuerpo con los valores Y X de donde estaba la fruta , por lo tanto , justo donde estaba la fruta ahora será una nueva cola para la serpiente. 

Notas.

He intentado explicarlo de una manera más o menos clara , se que habrá alguien que lo haría mejor , diferente , con más efectos , utilizando otro algoritmo , y que el código se podría mejorar , todo es posible, pero mi intención es explicar como funciona desde una manera simple, sobre todo porque cuando se está empezando a programar , añadir muchas cosas es poner más carga de aprendizaje al problema. Yo lo he hecho de esta manera , el código creo que se entiende bien , y puedes descargarlo arriba  debajo de la imagen e importarlo a Eclipse.
Muchas gracias y espero que te sirva de ayuda.

Entradas populares de este blog

LPIC-1 101 y 102

Certificación LPIC-1 101-102. Linux Certification Institute. Esta entrada es especial para mi porque he aprobado el certificado LPIC-1 de Linux. Al buscar información sobre las certificaciones , pues encontré información confusa y sé de algunas personas que quieren prepararse el exámen para un futuro , y si las bases de los exámenes no cambian quería aclararle las dudas. Quien no sepa lo que es LPIC-1 , es una certificación del Linux Professional Institute  la cual avala que tienes los conocimientos mínimos para gestionar un sistema operativo Linux independientemente de su distribución, como siempre te pongo la información más extendida   aquí .  El LPIC-1 es el primer exámen de todos y te digo desde ya que tiene su dificultad. Esto lo digo porque yo mismo al llevar un par de años con Linux , creía que mis conocimientos en Linux eran suficientes y solo había visto la punta del iceberg. Y en el primer nivel tocas muchas cosas. Lo que te quiero decir con esto es que e

Añadiendo autocompletado a un JTextField de Java Swing

Esta vez para un trabajo de clase en  Java Swing  me vi con la necesidad de tener un JTextField con autocompletado ( como la caja de texto de Google cuando buscas algo ) y como no viene por defecto el JTextField con esta característica , pues tuve que hacerme uno. Pero en este caso no me hacía falta consultar una base de datos para rellenarlo según vas escribiendo en él, sino que a este ya le doy los datos a filtrar de antemano. Tú dirás ... pero si hay miles en internet ya hechos , por qué reinventar la rueda ...,  Ya , ya lo sé , pero en algunos de los que ví , no me gustaba la manera de como se implementaban en el código para poder usarlo , otros no me gustaban como se veían visualmente , y lo más importante ... yo no me podía quedar con la duda de como se hacía uno ( esta última era la que más me podía jeje , yo y mi curiosidad ). ¿Cómo lo uso ? Te explico como funciona el componente GTextField , tan simple como instanciarlo y en su constructor pasarle t