para los que quieran aprender bgt

141 Nachrichten, 5 Seiten:  1 23 4 5 ↖ Zurück zur Themenliste

~msgScore~: +1

61. dhegwork-adakly,

ooooo, que bien amigo! gracias por estos nuevos capítulos que has traducido. bueno cuando puedas postea la continuación y mis felicitaciones por seguir adelante con esto.

~msgScore~: +0

62. mc-davo ,

chicos, aquí el cap de los arrais y diccionarios. saludos:
Hasta ahora, hemos visto los usos básicos de las variables. Hemos visto cómo pueden ser manipuladas, y cómo se utilizan en un contexto general de programación. Hay, sin embargo, un gran problema que indudablemente descubrirás tarde o temprano, y es la increíblemente grande cantidad de variables diferentes de las que tendrías que hacer un seguimiento incluso en un juego de tamaño medio. Imagina que tienes un tablero de juego con 50 casillas. Se supone que el usuario tira un par de dados, su posición se incrementa en la cantidad resultante, y entonces quieres comprobar lo que debería ocurrir en la casilla en la que el jugador cae. Para los propósitos de este sencillo ejemplo asumiremos que la variable que representa una casilla puede tener 3 valores; 1, 2 y 3. Estos valores pueden significar lo que quieras, por supuesto. 1 podría significar que el usuario retrocede tres casillas, 2 podría significar que se queda donde ha caído y 3 podría significar que avanza tres casillas. Ahora vamos a intentar construir parte de este tablero de juego rápidamente. Dejaremos que la primera casilla sea la número 0 en lugar de la número 1, por razones que quedarán claras en breve.

int tablero0=2;
int tablero1=2;
int tablero2=2;
int tablero3=2;
int tablero4=1;
int tablero5=2;
int tablero6=2;
int tablero7=2;
int tablero8=2;
int tablero9=3;
int tablero10=2;
int tablero11=2;
int tablero12=2;
int tablero13=2;
int tablero14=1;
...

Detengámonos aquí, ya que sin duda estarás furioso por la cantidad de papel que habrás desperdiciado si imprimes este tutorial. Estarás de acuerdo, después de ver este ejemplo, en que el código es increíblemente repetitivo y tedioso? Digamos, en cambio, que se trata de un juego de desplazamiento lateral y que los diferentes números representan el suelo, el fuego y el agua, y cosas por el estilo. Imagina la alegría de escribir 300 líneas como las que has visto arriba... Simplemente no es práctico. No sólo se tarda una eternidad en escribir el contenido real de la cuadrícula o el tablero, sino que tendrías que tener 300 sentencias if para establecer cuál de las 300 variables debe ser examinada después de que el jugador se mueva a una nueva casilla. ¿Puedes decir pesadilla? Ya me lo imaginaba. Por suerte, hay una solución bastante fácil... Los arrays.
Un array es, simplemente, una lista de variables. El array en sí tiene un nombre como cualquier otra variable, pero contiene diferentes valores a los que puedes referirte por índice. Un array puede ser tan pequeño o tan grande como lo necesites. Como siempre, vamos a ver un ejemplo para calmar nuestro apetito.
int[] board(50);
for(int x=0; x<50; x++)
{
board[x]=2;
}int[] board(50);
for(int x=0; x<50; x++)
{
board[x]=2;
}
Espera, espera... Muchas cosas nuevas aquí. Repasemos el código línea por línea como siempre. La primera línea le dice al motor que cree un nuevo array, es decir, una lista de variables, de tipo int. Los corchetes que siguen a int indican al motor que esta variable es un array. El array se asigna entonces a la variable llamada board, para que tengamos una forma de referirnos a las entradas dentro del array más adelante. El número dentro de los paréntesis le dice al motor que le dé a este array 50 entradas. En la siguiente línea usamos un bucle for para crear una nueva variable llamada x, y luego iniciamos un bucle que se ejecutará mientras x sea menor que 50. En la línea siguiente, ocurre algo muy interesante. Aquí asignamos un valor de dos a una entrada en el array del tablero. Sin embargo, esta entrada no se especifica con un valor literal en este caso. Podría haberlo hecho, pero tiene mucho más sentido utilizar un bucle, ya que así no necesitamos especificar cada entrada individualmente, ya que, por supuesto, estaríamos casi tan mal como con las variables individuales del ejemplo anterior. Observará que el índice del array, es decir, la entrada de la lista a la que hay que acceder, se especifica entre un paréntesis de izquierda y otro de derecha y no con un paréntesis de izquierda y otro de derecha, como cabría esperar. En la última línea simplemente le decimos al motor que nuestro bucle termina aquí. Lo que hemos hecho es recorrer toda la lista de 50 elementos, asignando automáticamente un valor de 2 a cada uno. Después de esto sólo tenemos que asignar valores manualmente a aquellas entradas de la lista que se supone que son algo más que 2. Bastante más sencillo que el ejemplo de pesadilla de antes, ¿verdad? Eso pensaba yo.

Ahora también habrás entendido la razón por la que especificamos la primera casilla del tablero en el ejemplo original como 0 en lugar de 1. Esto es simplemente porque el primer índice de un array es siempre 0, nunca 1. Así que si tienes un array con 100 entradas y deseas hacer un bucle a través de él para realizar alguna tarea, empezarías en el 0 y llegarías hasta el 99. Si intentas acceder a una entrada de un array que está fuera del rango, obtendrás un error de ejecución. Esto significa que el intérprete no se quejará hasta que el array sea evaluado, por lo tanto es absolutamente esencial que pruebes el juego a intervalos regulares, especialmente cualquier sección relacionada con el array, de lo contrario puedes encontrarte con algunos jugadores bastante enfadados en tu espalda.

Puedes tratar una entrada de array como una variable normal, lo que significa que puedes usarla en sentencias if y bucles y cualquier otra cosa que puedas hacer con variables normales, con la única diferencia de que especificas un índice en el array en lugar de un nombre de variable único.

También puedes tener arrays con múltiples dimensiones, para hacer cosas como una cuadrícula x-y o incluso x-y-z. Por ejemplo, si quieres hacer un tablero de ajedrez puedes hacer lo siguiente:
int[][] chessboard;
Las matrices multidimensionales son, en pocas palabras, matrices de matrices. Existe una limitación actual en el uso de arrays que impide especificar el tamaño de cada dimensión en un array multidimensional. Para hacer esto con nuestro tablero de ajedrez, por ejemplo, debemos redimensionar manualmente la primera dimensión y luego usar un bucle para redimensionar también cada entrada de la segunda dimensión, como sigue:
chessboard.resize(8);
for(int i=0; i<8; i++)
{
chessboard[i].resize(8);
}
int[][][] board;
board.resize(3);
for(int i1=0; i1<3; i1++)
{
board[i1].resize(3);
for(int i2=0; i2<3; i2++)
{
board[i1][i2].resize(3);
}
}

Entonces podrías acceder a un elemento diciendo

tabla[2][0][1]=10;

Usando un array con tres dimensiones podrías, por ejemplo, representar una cuadrícula con coordenadas x, y y z. Esto sería un verdadero juego 3d con movimiento hacia la izquierda, derecha, atrás, adelante, arriba y abajo.

En este momento, el motor BGT soporta arrays de hasta 4 dimensiones.

Los arrays se utilizan para muchas cosas diferentes. De hecho, una cadena en sí misma es un array, aunque no lo parezca por fuera. Cada elemento de un array de cadenas, es un solo carácter.
Aquí hay un ejemplo:
string my_string="This is a string.";
alert("my_string","my_string entry number 2 is the letter "+my_string[2]);
Esto devolvería la letra i. Recuerde que las matrices siempre empiezan por 0, por lo que la entrada 2 contiene el carácter 3.
Al igual que las cadenas se pueden utilizar como parámetros de funciones y valores de retorno, también lo pueden hacer las matrices. Sin embargo, puede haber ocasiones en las que no conozcas la longitud de tu array, ya sea porque se trata de una cadena o un array devuelto, o porque un bucle siempre está cambiando los valores dependiendo de ciertas condiciones. No hay problema. Un array contiene dos funciones especiales que te permiten comprobar o cambiar tu array. Length se explica por sí misma. Devuelve la longitud del array. Tenga en cuenta que esto no significa el número de elemento final. Si está utilizando este método como la condición de un bucle, necesita comprobar que su contador es menor que el de la longitud, como se muestra en el siguiente ejemplo, que mostrará cada carácter de la cadena en un cuadro de mensaje:

string my_string="string";
for(uint my_counter=0; my_counter < my_string.length(); my_counter++)
{
alert("my_string","my_string["+my_counter+"]="+my_string[my_counter]);
}
Observa que para obtener la longitud decimos mi_string.length(). Esto se debe a que la función length() está almacenada dentro de la variable. Esto se conoce como un método. Hablaremos de los métodos con más detalle en el próximo capítulo. También habrás notado que he utilizado una variable de tipo uint en lugar de int. Esto se debe a que el método de la longitud devuelve un uint en lugar de un int o un double. Siempre es recomendable que los enteros con signo y sin signo coincidan, de lo contrario el compilador marcará una advertencia cuando intentes ejecutar tu script.
Hay un último método que se utiliza para controlar un array. Se llama resize, y se utiliza para, lo has adivinado, redimensionar un array, ya sea añadiendo nuevos elementos o eliminando elementos. Toma un parámetro, el número de elementos que debe contener el nuevo array. Ten en cuenta que, al igual que length, estás declarando el número real de elementos que debe haber, no el número del último elemento. Por ejemplo:

string my_string="this is a string.";
my_string.resize(4);
Esto redimensionará el array a 4 elementos, terminando en la entrada 3. Tenga en cuenta que cuando se redimensiona un array a un valor menor que el original, las entradas se eliminan de derecha a izquierda, es decir, desde el último elemento hacia atrás. Por lo tanto, la cadena resultante será "esto".

Es posible especificar exactamente qué valores irán a un array en el punto en el que se define el array. Para ello, basta con poner un signo de igualdad después del nombre del array, y seguirlo con una lista de valores entre llaves. Parece más complicado de lo que es. Por ejemplo, vamos a definir una matriz de enteros e inicializarla con algunos valores significativos, todo en la misma línea de código:
código:

uint[] primos = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

Hay una pequeña limitación con las matrices, y es que sólo pueden almacenar valores del mismo tipo de datos. No se podría, por ejemplo, tener una entrada con el valor 45, y otra con el valor "hola". Sin embargo, esto se puede resolver con otro tipo de variables, conocidas como diccionarios. Un diccionario es lo que se llama un objeto con métodos, al que me referí brevemente en nuestro último ejemplo. Más sobre esto en el próximo capítulo.
Los diccionarios son otra forma de declarar variables. Sin embargo, a diferencia de las variables estándar, usted declara el nombre de la variable usando una cadena, y puede almacenar cualquier valor. Por lo tanto, puede tener un diccionario que contenga varias variables, todas con un nombre y un valor, como las tablas que describimos en nuestros ejemplos anteriores. Usemos ahora el mismo ejemplo, esta vez usando diccionarios.

dictionary board;
for(int x=0; x<50; x++)
{
board.set(x, 2);
}
De nuevo, muchas cosas nuevas que discutir. La primera línea simplemente declara un diccionario, al que nos referimos como tabla. La siguiente línea inicia un bucle, como hicimos con el array, de 0 a 49. La línea que sigue le dice al intérprete que cree una entrada en el diccionario, llamada el valor actual de x, y asigne el número 2 a esa entrada.
Esto tiene ciertas ventajas sobre los arrays, ya que en teoría podrías almacenar valores de coordenadas x e y, así

dictionary board;
for(int x=0; x < 4; x++)
{
for(int y=0; y < 4; y++)
{
board.set(x+","+y, 2);
}
}

Esto lo logramos utilizando un bucle anidado para incrementar ambos contadores y asignar el valor inicial de 2 a cada casilla. Observe que estamos usando dos valores separados por una coma dentro de nuestra cadena de nombre. Esto sólo nos facilita la separación de los cuadrados entre sí, ya que el objeto diccionario sólo lo ve como una cadena; no tiene idea de lo que el nombre puede significar para nosotros. En la práctica, lo único que ocurre es que se arma una cadena con un nombre único, es decir, nuestros números de casilla separados por comas.

Del mismo modo, para recuperar el valor de un determinado cuadrado, se puede hacer lo siguiente:
int square_value;
board.get("2,2", square_value);
El segundo parámetro del método get se pasa por referencia, lo que significa que el valor se almacena en la variable que le pasamos. Si no te queda claro lo que quiero decir, vuelve a la sección de funciones que contiene información detallada sobre el uso de los parámetros.

Además de poder establecer y recuperar valores en los diccionarios, también puedes modificarlos, e incluso borrarlos:
if(board.exists("2,2"))
{
board.delete("2,2");
}

Esto le dice al intérprete que busque "2,2" en el diccionario llamado board. Si lo encuentra, este valor se borra. Esto no se puede hacer con variables estándar.

Es muy importante que compruebe la existencia de una entrada del diccionario. Si borra o comprueba una entrada que no existe, no se producirá ningún error de sintaxis o de ejecución, pero la variable que está intentando utilizar para recuperar el valor no cambiará.

También puede utilizar el método delete_all para eliminar todas las asignaciones del diccionario.

Ten en cuenta que los diccionarios son significativamente más lentos que los arrays y las variables regulares, así que úsalos con cuidado.

~msgScore~: +0

63. Ronald-Weasley,

Saludos amigos!
Paso para transmitir una felicitación al amigo por el trabajo que está haciendo, y para animarlo a seguir adelante. Gracias por tu colavoración con los futuros programadores de la plataforma xd.

~msgScore~: +0

64. nahuel-rodrigo ,

posteo para que se me quede en partisipaciones

~msgScore~: +0

65. mc-davo ,

hola chicos. les vengo a informar que pronto habrá la entrega del siguiente capítulo. ando atravesando complicaciones (no tienen que ver con el manual) y por eso me retraso tanto, pero no los olvidé, aquí estoy haciendo lo posible

~msgScore~: +0

66. kaladin-bendito-por-la-tormenta,

sooorri chiquilines por hablar de otra cosa que no sea bgt, pero. necesito hacerles una preguntita. como es un hilo de programación no quise crear otro hilo innecesario. resulta que, me he estado leyendo un manual enorme de python. quiero trabajar concretamente con la última versión. el tema es, que, digamos que no tengo problemas con usar un block de notas para escribir las líneas de códigos. pero cuando quiero trabajar con IDLE Python, es totalmente compatible el NVDA en el menú pero cuando escribo líneas en la pantalla esta no lee. y y en realidad me es un poco más complicadito usar la consola, ya que como soy un verdadero principiante y que estoy más verde que marinero nobato en su primer salida, pos les pregunto para no pecar de ignorancia. qué editor de códigos es el más apropiado? que sea compatible claro. se, que no puedo pedir milgaros, pero ustedes que lleban más tiempo quizá tengan la respuesta. gracias.

~msgScore~: +0

67. Rayo.bgtr ,

podrías probar con notepad++

~msgScore~: +0

68. Fluttershy,

y ya que los últimos 2 mensages an sido de este tema. alguien me podría explicar como ver los fallos en un scrip? como lo que ase el IDLE por fabor. gracias

~msgScore~: +0

69. Ronald-Weasley,

Saludos amigos!
Arriba este hilo, esperando el siguiente capítulo. Mucho ánimo para el amigo que lleva el foro, y gracias por tu contribución.

~msgScore~: +0

70. dhegwork-adakly,

sii, ánimo y que pueda seguir con este proyecto. traducir no es que sea muy fácil por lo que se le agradece el esfuerzo.

~msgScore~: +0

71. phoenix_rising,

revivo hilo, a petición de su autor! ea zi más traduccioneees! xdd

~msgScore~: +0

72. el-killer-lhp,

hola chicos. soy yo, el mismo autor del hilo. camvié de cuenta, pero pues aquí estoy. en unos me pondré con el manual. no dejaré esto inconcluso como hicieron otros, por que de verdad quiero que el bgt quede como un código que pese a su antiguedad y agujeros almenos esté documentado en español y los que quieran aprender pero no sepan inglés se puedan hacerlo.

~msgScore~: +0

73. dhegwork-adakly,

bieeen, espero con ancias el próximo capítulo! bueno cuando puedas postéalo

~msgScore~: +0

74. el-killer-lhp,

chicos. la traducción del manual está demorando, pues un amigo y yo estamos traduciendo más caps para traerles los 4 caps finales de una. pero, para que esta demora no sea en vano y se pueda hacer algo, les propongo algo.
quien quiera y de verdad tenga la gana de aprender este lenguaje, yo le daré clases. solo pónganse en contacto con migo al pv, y explíquenme de que parte necesitan clases (básico o avanzado) así mismo, si requieren en una parte en espefícico o en general. por ejemplo, pueden pedirme que les enseñe todo sobre la parte servidor, como los send_reliables y unreliables (lo veremos mas adelante) y cosas así.
si alguno quiere una clase desde 0, pueden escribirme y con mucho gusto yo se las daré. solo hay que ver cuando cuadrán nuestros tiempos libres y en una reunión de google meet o por wpp de ser necesario estas clases se prestarán. también, claramente no solo serán una persona por clase, si no todas las que quieran.
de mas está aclarar que las clases son totalmente gratuitas.
saludos

~msgScore~: +0

75. TemasVarios,

Avisen, yo me apunto.

~msgScore~: +0

76. Fluttershy,

igual, me apunto. rofl

~msgScore~: +0

77. el-killer-lhp,

claro, todos los que quieran escríbanme por privado. dorami ya entró, si alguien mas quiere solo escriban y están.

~msgScore~: +0

78. dhegwork-adakly,

me apunto igual

~msgScore~: +0

79. gabino_06,

me apunto, yo quiero aprender

~msgScore~: +0

80. el-killer-lhp,

¡hola chicos!
aquí les traigo el capítulo 10 de este manual. pero, no está traducido por mi esta vez. mi amigo @croalclau, me a ayudado para poder traerles este magnífico manual mas rápido, y este capítulo lo a traducido el.. sin mas que decir, allá vamos:
10. Objetos y clases
Los objetos son una característica muy poderosa y absolutamente esencial a la hora de crear juegos con el motor bgt, así que asegúrate de leer este capítulo cuidadosamente. Un objeto es una variable regular, pero con una funcionalidad especial. Puedes pensar en un objeto como una variable que contiene otras variables dentro de sí misma, así como funciones que hacen algo con ese objeto en particular. Otra denominación para un objeto es una clase. Para ir aclarando un poco las cosas, comenzaremos con un ejemplo.

sound ambience;
ambience.load("curry.ogg");

Este ejemplo realiza varias cosas. Le dice al motor que queremos un nuevo objeto de tipo sound, que queremos que dicho objeto sea asignado a una variable que denominamos ambience, y finalmente llama a una función dentro de la variable ambience, especificando el nombre del archivo de sonido a abrir.

Cuando se crea un objeto, puede tomar una lista de parámetros que determinan en gran medida cómo este se comportará. También es posible que los objetos no tomen ningún parámetro, de lo cual el sonido y el temporizador son buenos ejemplos. El objeto de temporizador se crearía de la siguiente manera:

timer jumptime;

Una vez que un objeto ha sido creado, puedes comenzar a usarlo. Un objeto tiene lo que se llama propiedades, que son básicamente variables que se almacenan dentro del objeto y que se utilizan tanto para obtener como para establecer diversas piezas de información durante la vida útil del objeto. El objeto de sonidos, por ejemplo, tiene una propiedad denominada volumen. Esto determina qué tan alto se reproducirá el sonido y puede ser modificado en tiempo real. Aquí hay un ejemplo de cómo crear un objeto de sonido con un sonido que se abre como un flujo, y luego cómo establecer su volumen en -6 decibelios, lo que equivale aproximadamente a la mitad de la amplitud original.

sound ambience;
ambience.stream("curry.wav");
ambience.volume=-6;

Bastante simple, ¿Derdad? Claro que también es posible verificar el valor de una propiedad en nuestro objeto, de esta forma:

if(ambience.volume>-10)
{
// Do something
}

En este caso, hacemos algo si el volumen es mayor que -10 decibelios. Algunas propiedades no pueden modificarse, únicamente se pueden verificar, mientras que otras pueden modificarse solo en ciertos momentos, pero no en otros. Puedes encontrar toda la información sobre esto en la lista de propiedades de cada objeto en la referencia del mismo.

Los objetos también tienen algo llamado métodos. Un método es simplemente una función como cualquier otra que puedas encontrar en el motor bgt, con la única diferencia de que trabaja exclusivamente con un objeto en particular. Para volver al objeto de sonido, hay un método llamado play_wait que inicia la reproducción del sonido y luego espera a que termine antes de regresar. De hecho, las funciones de carga y transmisión con las que trabajamos anteriormente también son buenos ejemplos de métodos.
Extendamos el ejemplo anterior para incluir la reproducción del sonido y el ajuste de su volumen.

sound ambience;
ambience.stream("curry.wav");
ambience.volume=-6;
ambience.play_wait();

¿Familiar? bien, ya que básicamente solo estamos llamando a una función, pero una que opera en nuestra copia específica del objeto de sonido, en este caso denominada ambience. play_wait no toma parámetros, pero muchos otros métodos de objeto lo hacen, en cuyo caso se especifican entre un abrir y cerrar paréntesis como en una llamada de función normal.

Es perfectamente posible hacer dos versiones del mismo objeto, en cuyo caso funcionarán de forma completamente independiente entre sí. Si creas dos objetos de sonido, por ejemplo, y luego llamas a una reproducción en ambos, obtendrás ambos sonidos a la vez.

Es posible que desees pasar objetos por varias funciones propias. Para hacer esto, es esencial que pases identificadores y no el objeto en sí. Un identificador es esencialmente una referencia al objeto original. Para realizar esto, harías algo como lo siguiente:

sound@ play_sound(string filename)
{
sound the_sound;
the_sound.load(filename);
the_sound.play();
return the_sound;
}
void main()
{
show_game_window("My Game");
sound@ ambience=play_sound("curry.wav");
ambience.volume=-6;
@ambience=null;
}

Resumiendo, cuando declaras un identificador de objeto, se coloca un símbolo arroba (@) después del tipo de variable. Luego puedes usar esta variable como si fuera un objeto estándar, la única diferencia es que se hace referencia a la variable original. Cuando desees cambiar el nombre del identificador, por ejemplo, para que apunte a otro objeto del mismo tipo, simplemente coloca el signo arroba (@) antes del nombre de la variable.
Puedes destruir un identificador estableciendo su valor en nulo. Este es un objeto equivalente a 0. Teniendo esto en cuenta, aunque manualmente no se puede destruir el contenido de un objeto, una forma de evitarlo es estableciendo todos sus objetos glovales como identificadores y usar solo los objetos en si mismos en funciones. De esta manera, aunque los objetos en si mismo son variables locales, tienen variables glovales que aún hacen referencia a ellos. Por ende, el objeto siempre se podrá utilizar hasta que se destruya su último identificador.

También es posible crear tus propios objetos, también conocidos como clases, con tus propios métodos y propiedades. Por ejemplo, podrías crear una clase para un enemigo, de la siguiente manera:

class enemy
{
int health;
int speed;
int position;
void fire_weapon()
{
//el código del arma va aquí
}
void move(int direction)
{
//el código del movimiento va aquí
}
}

La única línea nueva aquí es la primera, pero es lo mismo que declarar una variable, con la pequeña diferencia de que tienes que decirle al motor cómo hacer esa clase. En este caso, nuestra clase para enemigo tiene tres propiedades, salud, velocidad y posición, y dos movimientos, disparar un arma y moverse. No obstante, no es necesario cambiar la propiedad de posición directamente, ya que la función de movimiento lo hará por ti, junto con cualquier otro código que ingreses allí. Por esta razón, es importante que documentes qué métodos y propiedades deben o no deben tocarse.
Para usar nuestra clase, escribiríamos:

enemy robot;

Entonces nuestra clase estaría lista para usarse, al igual que los objetos proporcionados en bgt.

robot.move(right); //asumiento que la derecha es una constante
robot.fire_weapon(); //hace que el robot dispare su arma

Sin embargo, hay un pequeño problema. No se le ha asignado un valor a la salud del enemigo. Esto significa que cada vez que declaremos una variable enemiga, tendríamos que establecer cada salud en 100. Esto puede ser fácilmente solucionado usando las funciones de constructor y destructor.
La función de constructor simplemente le indica al motor cómo deben configurarse nuestras propiedades i/o realiza cualquier otra tarea que podríamos querer hacer cada vez que se crea una nueva instancia de nuestra clase. la función destructor es opcional y se declara con el mismo nombre que la clase. Se llama a la función destructor cuando se destruye nuestra instancia de clase. Se puede utilizar para realizar cualquier trabajo de limpieza necesario. El destructor también es opcional y se declara de una manera similar al constructor, pero con un signo ~ (tilde) antes del nombre de la clase. Finalmente, tanto las funciones constructor como las destructor son las únicas funciones que no declaran un tipo de retorno, ni siquiera vacío.
Extendamos nuestra clase de enemigo para incluir un constructor.

class enemy
{
int health;
int speed;
int position;
enemy()
{
health=100;
position=0;
speed=300;
}
void fire_weapon()
{
//el código del arma va aquí
}
void move(int direction)
{
//el código de movimiento va aquí
}
}

Ahora, cada vez que declaremos una variable de tipo enemigo, sus propiedades siempre estarán correctamente configuradas.

Ten en cuenta que también se puede escribir lo siguiente:

class enemy
{
int health=100;
int speed=300;
int position=0;
void fire_weapon()
{
//el código del arma va aquí
}
void move(int direction)
{
//el código de movimiento va aquí
}
}

En este caso, en realidad no implementamos un constructor porque las propiedades reciben valores predeterminados directamente en su declaración. No obstante es posible que el constructor deba hacer otro trabajo, por lo que en el futuro también lo utilizaremos.

Para hacer que tu clase sea más portátil, puedes usar parámetros para su constructor, en lugar de esperar que el usuario de la clase modifique directamente las propiedades. Mostramos esto con nuestra clase de enemigos en rápido crecimiento.

class enemy
{
int health;
int speed;
int position;
enemy(int init_health, int init_speed, int init_pos)
{
health=init_health;
position=init_pos;
speed=init_speed;
}
void fire_weapon()
{
//el código del arma va aquí
}
void move(int direction)
{
//el código de movimiento va aquí
}
}

Ahora para declarar a nuestro enemigo, escribiríamos lo siguiente:

enemy robot(100, 300, 0);

Esto establecería las propiedades de nuestra instancia de objeto enemigo en los valores que hemos especificado. de esta forma, puedes crear enemigos de diferentes fuerzas, velocidades y dispersos aleatoriamente en el campo de juego. Ten en cuenta que, dado que se definió únicamente un constructor que toma parámetros, ya no es posible declarar a nuestro enemigo sin especificar estos parámetros, consulta a continuación para obtener más información sobre los constructores predeterminados automáticos.

Como mencionamos en la sección de funciones, las funciones pueden tener el mismo nombre, siempre que los parámetros sean diferentes. Esto igualmente es válido para los métodos de clase, incluido el constructor, pero no el destructor. Esto significa que si quisieras permitir que tu enemigo se estableciera con valores diferentes, podrías tener un constructor donde el usuario deba especificar los parámetros, pero también podrías tener un constructor donde no se deban dar parámetros. de esta forma, puedes decidir si declarar, o no, a tus enemigos con parámetros. El motor encontrará el constructor que coincida con sus parámetros, si los hay, y lo llamará por ti. Ahora demostraremos esto con nuestro código de enemigo. No incluiré las propiedades o métodos de la clase, simplemente utilizaré nuestros constructores.

class enemy
{
//las propiedades van aquí
//constructor sin parámetros
enemy()
{
health=100;
position=0;
speed=300;
}
//constructor con parámetros
enemy(int init_health, int init_speed, int init_pos)
{
health=init_health;
position=init_pos;
speed=init_speed;
}
//los métodos de clase van aquí
}

Por supuesto que puedes poner los métodos de clase donde desees, pero tiene sentido lógico poner nuestro constructor en la parte superior de nuestra clase, ya que esta es la primera función que llama.
Ahora para declarar a nuestro enemigo, ya que tenemos dos constructores, podemos hacer:

enemy robot;

o

enemy robot(200, 150, 0);

La primera declaración simplemente nos daría un enemigo con sus valores predeterminados. Sin embargo, nuestra segunda declaración le da a nuestro enemigo el doble de fuerza y velocidad que la primera. Aunque 150 es la mitad del valor de 300, lo que le estamos diciendo al programa es el tiempo que le toma moverse, no qué tan rápido se mueve en un tiempo dado.

Si no defines un constructor en el script, el compilador creará automáticamente uno vacío que no toma parámetros. Esto significa que, de forma predeterminada, podríamos declarar cualquiera de nuestras clases como hemos visto anteriormente sin una lista de argumentos. Sin embargo, si defines un constructor que toma parámetros, el predeterminado ya no se implementa de manera automática. Únicamente se implementa automáticamente por el compilador de script si no hay ningún constructor especificado por ti. Por lo tanto, si deseas un constructor predeterminado, es decir, un constructor que no toma argumentos, así como un constructor que sí los toma, debes implementar ambos explícitamente como en el ejemplo anterior.

Ten en cuenta que, como se mencionó anteriormente en este tutorial, las variables primitivas, es decir, las variables que no son objetos, contendrán valores indefinidos si no se les da valores iniciales de manera explícita. Esto no se aplica únicamente a variables glovales y variables dentro de funciones y métodos, sino también a propiedades en clases. Si declaras un objeto como:

enemy robot;

Luego, el constructor predeterminado, de estar presente, se invocará inplícitamente, por lo que, a diferencia de variables primitivas como int y float, el contenido de la variable del robot no está indefinido en absoluto. Sin embargo, se supone que los constructores inicializan las propiedades utilizadas internamente por la clase. Eso no sucede automáticamente. En resumen, debes asegurarte de que todas las propiedades que usas en una clase se inicialicen a valores significativos antes de ser usadas, al igual que lo haces con las variables primitivas fuera de las clases. Los constructores son un buen lugar para hacer esto. De forma alternativa, puedes dar a las propiedades valores iniciales cuando se declaran, tal como lo harías con variables glovales o variables de función local.

Los constructores funcionan mas o menos de la misma manera que los constructores, excepto que son llamados cuando se destruye tu clase. Esto suele suceder cuando se destruye su última referencia o cuando se cierra el programa. Aquí está nuestro enemigo básico una vez más, con un solo constructor sin argumentos y un destructor:

class enemy
{
//las propiedades van aquí
enemy()
{
health=100;
position=0;
speed=300;
}
~enemy()
{
alert("Gloria!","tu enemigo ha muerto!");
}
//los métodos van aquí
}

No tendría sentido ejecutar este ejemplo. De hecho, si implementaste este ejemplo en un juego, una vez que salieras del mismo, aparecerían cuadros de mensaje a la izquierda, al centro y a la derecha que te indicarían que tu enemigo estaría muerto, porque el intérprete está destruyendo todos los objetos activos, y por lo tanto, llamando a sus funciones de destructor, si las hay. Están presentes. Al igual que con el constructor, el compilador creará un destructor vacío por defecto si eliges no crear uno tú mismo. Esto significa que solo tienes que definir uno de manera explícita si quieres realizar alguna acción específica cuando se destruyó la clase.

~msgScore~: +0

81. phoenix_rising,

Disculpen la demora chicos, los asuntos de la universidad demandaron mi tiempo esta vez, aunque fue un placer ayudar a mi amigo @el-can-servero a traducir esta vez. Tengo un estilo un poquito menos formal de expresarme, así que espero no sea esto un problema para ustedes. Espero les guste y si todo va bien puedo pedirle al bro que me deje traducir algo más. :v jajajaja ya veremos, pero eso, fue un placer traducir este capítulo.

~msgScore~: +0

82. el-killer-lhp,

claro, puedes traducir siempre que quieras @ croalclau xd

~msgScore~: +0

83. isacelite10 ,

nadie de este hilo a creado juegos o programas. verdad
si lo hacen. yo me ofresco como beta thester. pero pasenlo sin compilar. para que solo el bgt pueda abrirlo

~msgScore~: +0

84. el-killer-lhp,

y como para que querría usted un juego/programa descompilado? digo, si usted se ofrece como vetatester, vien lo puede hacer con la versión compilada.
haver, puede que su intención mala no sea. pero de que la propuesta a lmenos a mi me hizo sospechar...

~msgScore~: +0

85. TheDreamer,

apunten xd

~msgScore~: +0

86. phoenix_rising,

mmmh... el nick era el tiflovicho. amí me huele a una de las siguientes palabras: clonación, robo de código, ganancias sin programar... xd

~msgScore~: +0

87. C-Kan ,

opino lo mismo que el dragón, y anoten. a: bastaba decir que como el nick es el tiflo bicho, fijo va hacer clonación , o porqué no quiere guiarse pa aprender como hacerlo, pero eso quiere decir que veo las cosas vonitas siempre, así que fijo es un clonador.

~msgScore~: +0

88. isacelite10 ,

creo que exprese mal las palabras de mi mensaje. si lo pido así, es para revisar. puede que le encuentre algún problema. y puedo, o arreglarlo por mi cuenta o solisitarle al creador, porque vamos
no todas las pcs son iguales. y en alguna puede que anda bien, y en otra no. y creo que en mi opiñón, es mejor que pueda correr bien en la malloría de pcs

~msgScore~: +0

89. C-Kan ,

opinión: y no, pués el error puede ser es en el juego no en el lenguaje, y no que no sabías bgt? no sé es sospechoso.

~msgScore~: +0

90. keith-moon,

bueno muchachos creo que es hora de que hagamos nuestro propio manamon, esperar a vgestorm es demasiado xd, vamos hagamos hasta el manamon 14 si es posible xd, con todo y movimientos mana o las manaevoluciones, y porque no las gigamans o las dinamans

~msgScore~: +0

141 Nachrichten, 5 Seiten:  1 23 4 5 ↖ Zurück zur Themenliste

Auf das Thema antworten

Sie müssen angemeldet sein, um posten zu können

Passwort vergessen? Benutzerkonto erstellen