CodeGym /Blog Java /Random-ES /Sección de juegos en CodeGym: Teoría útil
John Squirrels
Nivel 41
San Francisco

Sección de juegos en CodeGym: Teoría útil

Publicado en el grupo Random-ES
En la sección "Juegos" de CodeGym, encontrará proyectos emocionantes que implican escribir juegos de computadora populares. ¿Quieres crear tu propia versión de los juegos populares 2048, Buscaminas, Serpiente y otros juegos? Es sencillo. Hemos convertido la escritura de juegos en un proceso paso a paso. Sección "Juegos" en CodeGym: Teoría útil - 1Para probar sus habilidades como desarrollador de juegos, no tiene que ser un programador avanzado, pero es necesario un conjunto específico de conocimientos de Java. Aquí encontrarás información que te será útil en la escritura de juegos .

1. Herencia

Trabajar con el motor de juegos de CodeGym implica usar la herencia. Pero, ¿y si no sabes qué es eso? Por un lado, necesitas entender este tema: se estudia en el Nivel 11. Por otro lado, el motor se diseñó especialmente para que sea muy simple, de modo que pueda salirse con la suya con un conocimiento superficial de la herencia. Entonces, ¿qué es la herencia? En pocas palabras, la herencia es una relación entre dos clases. Uno de ellos se convierte en padre y el otro en hijo (descendiente). Además, es posible que la clase padre ni siquiera sepa que tiene descendientes. En otras palabras, no obtiene ninguna ventaja particular por tener descendencia. Pero la herencia da muchas ventajas a un descendiente. Y el más importante es que todas las variables y métodos de la clase principal aparecen en la descendiente como si el código de la clase principal se hubiera copiado en la clase descendiente. Esta no es una descripción del todo precisa, pero será suficiente para una comprensión simplificada de la herencia. Ejemplo 1: La herencia más simple.

public class Parent {

}
La clase Child hereda la clase Parent usando la palabra clave extends .

public class Child extends Parent {

}
Ejemplo 2: Usando las variables de la clase padre.

public class Parent {

   public int age;
   public String name;
}
La clase Child puede usar las variables de edad y nombre de la clase Parent como si estuvieran declaradas en la clase Parent .

public class Child extends Parent {

   public void printInfo() {

     System.out.println(name+" "+age);
   }
}
Ejemplo 3: Usando los métodos de la clase padre.

public class Parent {

   public int age;
   public String name;

   public getName() {
      return name;
  }
}
La clase Child puede usar las variables y métodos de la clase Parent como si estuvieran declarados en la clase Child. En este ejemplo, usamos el método getName() .

public class Child extends Parent {

   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}
Así es como se ve la clase Child para el compilador:

public class Child extends Parent{

   public int age;  // Inherited variable
   public String name;  // Inherited variable

   public getName() {  // Inherited method.
      return name;
  }
   public void printInfo() {

     System.out.println(getName()+" "+age);
   }
}

2. Métodos de anulación

A veces hay situaciones en las que hacemos que nuestra clase Child herede una clase Parent muy útil, junto con todas sus variables y métodos, pero algunos de los métodos no funcionan exactamente como queremos. O no del todo como queremos que lo sean. ¿Qué podemos hacer en esta situación? Podemos anular el método que no nos gusta. Esto es muy fácil de hacer: en nuestra clase Child, simplemente declaramos un método con la misma firma que el método en la clase Parent, y luego escribimos nuestro propio código en él. Ejemplo 1: anular un método.

public class Parent {

   public String name;

   public void setName(String nameNew) {
       name = nameNew;
  }

   public getName() {
      return name;
  }
}
El método printInfo() mostrará "Luke, No!!!"

public class Child extends Parent{

   public void setName(String nameNew) {
       name = nameNew + ", No!!!";
  }

   public void printInfo() {
      setName("Luke");
      System.out.println(getName());
   }
}
Así es como se ve la clase Child para el compilador:

public Child extends Parent {

   public String name;  // Inherited variable

   public void setName(String nameNew)  // Overridden method instead of the inherited method {

       name = nameNew + ", No!!!";
   }
   public getName() {  // Inherited method.

      return name;
   }
   public void printInfo() {

     setName("Luke");
     System.out.println( getName());
   }
}
Ejemplo 2: algo de magia de herencia (y anulación de métodos).

public class Parent {

   public getName() {
      return "Luke";
  }
   public void printInfo() {

     System.out.println(getName());
   }
}

public class Child extends Parent {

   public getName() {
      return "Luke, I am your father";
  }
}
En este ejemplo, si el printInfométodo (de la clase principal) no se anula en la clase secundaria, cuando se llama a este método en un objeto secundario, getName()se llamará a su método en lugar del getName()método de la clase principal.

Parent parent = new Parent ();
parent.printnInfo();
Este código muestra "Luke" en la pantalla.

Child child = new Child ();
child.printnInfo();
Este código muestra "Luke, soy tu padre" en la pantalla.
Así es como se ve la clase Child para el compilador:

public class Child extends Parent {

   public getName() {
      return "Luke, I am your father";
   }
   public void printInfo() {

     System.out.println(getName());
   }
}

3. Listas

Si aún no conoces las listas (Lista), aquí tienes una breve descripción. Puedes encontrar la información completa en los Niveles 6-7 del curso de CodeGym . Las listas tienen mucho en común con las matrices:
  • puede almacenar una gran cantidad de datos de un tipo específico;
  • te permiten obtener artículos por su índice;
  • los índices de los elementos empiezan desde 0.
Beneficios de las listas: a diferencia de las matrices, las listas pueden cambiar de tamaño dinámicamente. Cuando se crea una lista, su tamaño es 0. A medida que agrega elementos a una lista, su tamaño aumenta. Este es un ejemplo de creación de una lista:

ArrayList<String> myList = new ArrayList<String>(); // Create a new ArrayList
El valor entre paréntesis angulares indica el tipo de datos que la lista puede almacenar. Estos son algunos métodos para trabajar con la lista:
Código Breve descripción de lo que hace el código.
ArrayList<String> list = new ArrayList<String>(); Crear nueva lista de cadenas
list.add("name"); Agregar un elemento al final de la lista
list.add(0, "name"); Añadir un elemento al principio de la lista
String name = list.get(5); Obtener un elemento por su índice
list.set(5, "new name"); Cambiar un elemento por su índice
int count = list.size(); Obtener el número de elementos en la lista
list.remove(4); Eliminar un elemento de la lista
Puede obtener más información sobre las listas en los siguientes artículos:
  1. clase ArrayList
  2. ArrayList en imágenes
  3. Eliminar un elemento de un ArrayList

4. Matrices

¿Qué es una matriz? Una matriz no es más que una tabla rectangular que se puede llenar con datos. En otras palabras, es una matriz bidimensional. Como probablemente sepa, las matrices en Java son objetos. Una matriz unidimensional estándar intse ve así:

int [] array = {12, 32, 43, 54, 15, 36, 67, 28};
Podemos visualizarlo así:
0 1 2 3 4 5 6 7
12 32 43 54 15 36 67 28
La fila superior indica las direcciones de las celdas. En otras palabras, para obtener el número 67, debe acceder al elemento de la matriz con el índice 6:

int number = array[6];
Es todo muy simple. Una matriz bidimensional es una matriz de matrices unidimensionales. Si escuchas esto por primera vez, detente e imagínalo en tu cabeza. Una matriz bidimensional se ve así:
0 Matriz unidimensional matriz unidimensional
1 matriz unidimensional
2 matriz unidimensional
3 matriz unidimensional
4 matriz unidimensional
5 matriz unidimensional
6 matriz unidimensional
7 matriz unidimensional
En codigo:

int [][] matrix = {
{65, 99, 87, 90, 156, 75, 98, 78}, {76, 15, 76, 91, 66, 90, 15, 77}, {65, 96, 17, 25, 36, 75, 54, 78}, {59, 45, 68, 14, 57, 1, 9, 63}, {81, 74, 47, 52, 42, 785, 56, 96}, {66, 74, 58, 16, 98, 140, 55, 77}, {120, 99, 13, 90, 78, 98, 14, 78}, {20, 18, 74, 91, 96, 104, 105, 77} }
0 0 1 2 3 4 5 6 7
sesenta y cinco 99 87 90 156 75 98 78
1 0 1 2 3 4 5 6 7
76 15 76 91 66 90 15 77
2 0 1 2 3 4 5 6 7
sesenta y cinco 96 17 25 36 75 54 78
3 0 1 2 3 4 5 6 7
59 45 68 14 57 1 9 63
4 0 1 2 3 4 5 6 7
81 74 47 52 42 785 56 96
5 0 1 2 3 4 5 6 7
66 74 58 dieciséis 98 140 55 77
6 0 1 2 3 4 5 6 7
120 99 13 90 78 98 14 78
7 0 1 2 3 4 5 6 7
20 18 74 91 96 104 105 77
Para obtener el valor 47, debe consultar el elemento de matriz en [4][2].

int number = matrix[4][2];
Es posible que haya notado que las coordenadas de la matriz son diferentes del sistema de coordenadas rectangular clásico (sistema de coordenadas cartesianas). Cuando accede a la matriz, primero especifica la coordenada y y luego la coordenada x. En matemáticas, se acostumbra especificar primero la coordenada x, es decir, (x, y). Quizás se esté preguntando: "Bueno, ¿por qué no rotar su representación de la matriz y luego acceder a los elementos de la forma habitual usando (x, y)? Hacer esto no cambiaría el contenido de la matriz". Sí, nada cambiaría. Pero en el mundo de la programación, la práctica aceptada es acceder a las matrices "primero por y, luego por x". Debes aceptar esto como la forma correcta. Ahora hablemos de proyectar la matriz a nuestro motor (Gameclase). Como sabes, el motor tiene muchos métodos que cambian las celdas del campo de juego en coordenadas específicas. Por ejemplo, el setCellValue(int x, int y, String value)método. Establece una celda específica con coordenadas (x, y) iguales al parámetro de valor. Es posible que haya notado que este método toma x primero, al igual que en el sistema de coordenadas clásico. Los otros métodos del motor funcionan de manera similar. Al desarrollar juegos, a menudo será necesario reproducir el estado de una matriz en la pantalla. ¿Como hacemos eso? Primero, debe iterar a través de todos los elementos de la matriz en un ciclo. En segundo lugar, llame al método de visualización para cada uno de ellos, utilizando coordenadas INVERSAS. Por ejemplo:

private void drawScene() {
    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
            setCellValue(j, i, String.valueOf(matrix[i][j]));
        }
    }
}
Naturalmente, la inversión funciona en ambas direcciones. Puede pasar (i, j) al setCellValuemétodo y simultáneamente tomar el elemento [j][i] de la matriz. Invertir las coordenadas puede parecer un poco difícil, pero debes recordarlo. Y siempre, si encuentra algún problema, debe tomar una hoja de papel y un bolígrafo, dibujar la matriz y reproducir los procesos relacionados con la matriz.

5. Números aleatorios

¿Cómo se trabaja con un generador de números aleatorios? La Gameclase define el getRandomNumber(int)método. Bajo el capó, usa la Randomclase del paquete java.util, pero la forma en que trabaja con el generador de números aleatorios no cambia. getRandomNumber(int)toma un número entero como argumento. Este número será el límite superior de lo que el generador puede devolver. El límite inferior es 0. ¡Importante! El generador NUNCA devolverá el número del límite superior. Por ejemplo, si llamas getRandomNumber(3), devolverá aleatoriamente 0, 1 o 2. Como puedes ver, no puede devolver 3. Usar el generador de esta manera es bastante simple, pero muy efectivo en muchos casos. Suponga que necesita obtener un número aleatorio en algún rango: imagine que necesita un número de tres dígitos en el rango [100..999]. Como ya sabe, el número mínimo devuelto es 0. Por lo tanto, deberá agregar 100. Pero en este caso, debe tener cuidado de no exceder el límite superior. Para obtener 999 como el valor aleatorio máximo, llame algetRandomNumber(int)con el argumento 1000. Pero ahora recordamos que estamos agregando 100 al resultado: esto significa que el límite superior debe reducirse en 100. En otras palabras, el código para obtener nuestro número aleatorio de tres dígitos se verá así :

int number = 100 + getRandomNumber(900);
Pero para simplificar este procedimiento, el motor proporciona el getRandomNumber(int, int)método cuyo primer parámetro es el número mínimo a devolver. Usando este método, el ejemplo anterior se puede reescribir de la siguiente manera:

int number = getRandomNumber(100, 1000);
Los números aleatorios se pueden usar para obtener un elemento de matriz aleatorio:

String [] names = {"Sarah", "Val", "Sergey"};
String randomName = names[getRandomNumber(names.length)]
Generando ciertos eventos con cierta probabilidad. Para los humanos, las mañanas comienzan con algunos escenarios posibles: quedarse dormido: 50% de probabilidad; Me desperté a tiempo: 40% de probabilidad; Me desperté una hora antes: 10% de probabilidad. Imagina que estás escribiendo un generador de resultados matutinos. Necesitas generar eventos con una cierta probabilidad. Para hacer esto, nuevamente necesita usar un generador de números aleatorios. Son posibles diferentes implementaciones, pero la más simple debe basarse en el siguiente algoritmo:
  1. establecer los límites utilizados para generar un número;
  2. generar un número aleatorio;
  3. procesar el número obtenido.
En este caso, el máximo será de 10. Llame algetRandomNumber(10)método y analizar que podemos devolver. Puede devolver 10 números (del 0 al 9), cada uno con la misma probabilidad: 10%. Ahora necesitamos combinar todos los resultados posibles y asignarlos a nuestros posibles eventos. Su imaginación puede pensar en muchas combinaciones posibles, pero esta es la más obvia: "Si el número aleatorio está en el rango [0..4], tenemos el evento "Overslept"; si el número está en el rango [5 ..8], tenemos el evento "Desperté a tiempo"; y si el número es 9, entonces tenemos el evento "Desperté una hora antes". Todo es muy simple. Hay 5 números en el rango [0 ..4], cada uno de los cuales puede devolverse con una probabilidad del 10%, para un total del 50%, hay 4 números en el rango [5..8], bueno, y 9 es solo un número que aparece con una probabilidad del 10%.

int randomNumber = getRandomNumber(10);
if (randomNumber < 5) {
    System.out.println("Overslept");
} else if (randomNumber < 9) {
    System.out.println("Woke up on time");
} else {
    System.out.println("Woke up an hour early");
}
En general, hay muchas formas de usar números aleatorios. Estás limitado solo por tu imaginación. Pero se usan con mayor eficacia si necesita obtener algún resultado repetidamente. Entonces el nuevo resultado será diferente al anterior. Con alguna probabilidad, por supuesto. ¡Eso es todo por ahora! Si desea obtener más información sobre la sección "Juegos", aquí hay una documentación útil que puede ayudar:
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION