Heyyyyyyyyyyyyyyy

Aprende a programar microcontroladores en C... http://tecdigitaldelbajio.com/software-tarjeta.html

sábado, 25 de septiembre de 2010

Métodos creados por el usuario -- Parte II



En la entrada anterior del blog quedaron pendientes este par de temas relacionados con métodos creados por el usuario:

• Los métodos que regresan valores
• Los métodos con parámetros

Métodos que regresan valores

Voy a repetir la sintaxis para crear un método definido por el usuario:

Identificador_de_acceso valor_de_regreso Nombre_del_metodo( parametros ) {

     //Código del método

}

Un método que regresa un valor también requiere un identificador de acceso que ya se vio en el post pasado, para nuestro ejemplo se usará private, por otro lado el valor de regreso, es el tipo de datos (puede ser int, float double etc.) que va a regresar el método, por ejemplo, el método que voy a diseñar regresa el ancho de una imagen, el ancho es un número enero que se da en pixeles, el método entonces va a regresar un número entero, aparte se va a llamar obtAncho y no tiene parámetros, entonces el método va quedando así:

private int obtAncho( ) {

   //Código del método

}

El ejemplo simplemente regresa el ancho, en los códigos vistos en los últimos post, se observa como obtener el ancho de una imagen, de la pelotita específicamente y era así:

pelota.getWidth();

Pues ese código es el que se va a gregar al método. Los métodos que regresan valores deben llevar a fuerzas la palabra
return

Esa instrucción termina el método y regresa el valor que este después del return, el método completo que regresa el ancho de la imagen queda finalmente así:

private int obtAncho( ) {
   return pelota.getWidth();
}

Eso es todo, el método se puede invocar o mandar llamar así:

imgAncho = obtAncho( );

Contrario a lo que se vio en el post pasado, los métodos que no regresan valores simplemente se invocan con el nombre del método, los que si regresan deben ser invocados por medio de una variable, como se ve en la instrucción anterior, hasta aquí vamos a dejar eso de los métodos que regresan valores, pero más adelante vamos a realizar algún ejemplo para reforzar este tema que fue un poco superficial.

Métodos con parámetros

Vea el siguiente método:

Public void estVelocidad( int x) {
    VelX = x;
}

El método es publico, y no regresa ningún valor, se llama estVelocidad y lleva un parámetro, contrario a todos los métodos vistos anteriormente, entre paréntesis, lleva la declaración de una variable, en este ejemplo la variable se llama x y es de tipo entero, esta variable es el parámetro y sirve para comunicarse con el método.

La regla es bien simple, se agregan los parámetros como una declaración de una variable, en el ejemplo la variable se llama “x” y es de tipo entero.

Para invocar el método, se hace de una forma por demás sencilla, el método no regresa valores es de tipo void como se observa, entonces solo se coloca el nombre del método y entre paréntesis el valor del parámetro así:
estVelocidad(5);

Con la sentencia anterior el valor de “5” es enviado al parámetro, ese valor llega a la variable “x” del método y entonces la sentencia que está dentro del método, esta:

velX = x;

hace que la variable “velX” tome el valor de 5.

Fácilmente puedo mandar llamar el método y cambiar de velocidad, pensando en el ejemplo de la pelotita, con simplemente llamar el método se establece la velocidad en X, otro ejemplo para invocar el método sería así:

estVelocidad(3);



Se manda llamar el método pero vea ahora, lleva entre paréntesis el valor de "3", este valor se refleja en el parámetro y ahora la variable "velX" toma el valor de "3".

El ejemplo es muy simple pero a lo largo del blog se van a ver las ventajas de usar métodos.

Es posible agregar más parámetros, los necesarios, incluso pueden ser hasa de diferentes tipos solo basta con separarlos con comas, por ejemplo, vea el siguiente método usado para calcular el area de un triangulo, recibe como parámetros dos variables la base y la altura:

private int areaTriangulo(int base, int altura) {

     return ((a*b)/2)

}

El método, tiene parámetros y parte regresa valores de tipo entero que es precisamente el resultado del area del triangulo, para invocar el método basta llamarlo así:

Area = areaTriangulo(5, 6);

Al ejecutar esa línea la variable Area tendrá el valor calculado en el método, el número “5” se transfiere a la variable “base” y el número “6” a la variable “altura”, el método con esos valores hace el calculo ahí indicado y lo regresa a la variable donde se mando llamar el método. Este ejmplo se ve claramente que los parámetros permiten enviar información al método, en ele ejemplo se envía el "5" y el "6" y por cierto el método es capaz de ahora enviar la información a la clase donde se manda llamar.

Bueno espero me haya explicado bien, con esto terminamos la sintaxis de los métodos, espero mostrar algunos ejemplos para reforzar este tema.



Clic AQUI para leer más...!

miércoles, 15 de septiembre de 2010

Métodos creados por el usuario -- Parte I



Hoy se va a seguir trabajando con el mismo código que se vio en el último ejemplo, el de la pelotita que era movida por el teclado del celular, para mostrar otro concepto de la sintaxis de Java, la creación de métodos definidos por el usuario.

Ya se ha trabajado con muchísimos métodos a lo largo del blog, por ejemplo:


  Clase                    Método       
TextField             getString()               
                            setText()                   
Graphics             drawArc()
                            drawString()
                           drawImage()
GameCanvas      flushGraphics()

Todos absolutamente todos los métodos fueron creados por Sun Microsystem cuando desarrollo java y están agrupados en paquetes de clases a los que se tiene acceso por medio de la instrucción import. Hoy se va hablar de métodos pero de otro tipo, no los creados por Sun, si no, los métodos definidos por el usuario.


Métodos Definidos por el usuario

Un método es como una subrutina o un pequeño segmento de código que en términos generales sirve para dividir o descomponer un problema grande en partes más pequeñas que se invocan o se llaman desde la mima clase o desde otras clase

El siguiente segmento de código muestra el método llamado constructor, que se hizo en el post del ejemplo #20 y en el #19 :

El constructor entre otras cosas, carga las imágenes que se van a usar en el programa y crea un subproceso para el control de la animación, se puede dividir esta tarea, en partes bien definidas que son cargar las imágenes y crear el subproceso, se puede entonces crear un par de métodos que haga eso, pero veamos esto con calma.
public Animacion() {
  super(true);
  g = getGraphics();
  try {
     fondo = Image.createImage("/fondo.jpg");
     pelota = Image.createImage("/pelotita.gif");
  } catch (Exception e) { }
  subproceso = new Thread(this);
  subproceso.start();
}


La sintaxis para crear un método definido por el usuario es en términos generales así:

Identificador_de_acceso    valor_de_regreso    Nombre_del_metodo( parametros ) {

         //Código del método

}

Enseguida se explican las cuatro partes que consta el método

1. Identificador de acceso

El identificador de acceso es algo así como la protección que tiene el método y es que el método creado por el usuario puede invocarse desde la misma clase o desde otras clases, el identificador de acceso nos da ciertos niveles de seguridad, existen varios tipos de identificadores de acceso:

• private
• protected
• public
• package

El lector debe elegir un tipo para usarlo en la definición del método, el método creado debe iniciar con una de esas palabras reservadas de Java, ¿pero cúal usar? Enseguida se da una definición superficial de cada uno de estos niveles de acceso.
a) Private

Este es el nivel de acceso más restringido, un método privado solo se puede invocar o solo se tiene acceso desde la misma clase donde está definido, los métodos privados son digámoslo así secretos para todos menos para la clase donde están ubicados, justo este tipo de acceso es el que se va usar en los métodos que vamos a crear, ¿Por qué? Sencillo porque el programa solo consta de una clase (bueno en realidad son dos clases el MIDlet y la clase que hereda de GameCanvas que es donde está todo el código, por eso digo que solo consta de una clase), así que no necesitamos invocar este método desde otros lados, programas que constan de varias clases si requieren de otro identificador de acceso.

Vamos a tomar la definición de la clase vista anteriormente para ir formando nuestro método, entonces, se debe agregar la palabara private al inicio del método así:

private valor_de_regreso Nombre_del_metodo( parametros ) {

    //Código del método

}

b) Protected

Este nivel de acceso permite invocar el método desde la misma clase o desde las subclases, recuerde una subclase es la que deriva de otra y hereda sus métodos y propiedades, por ejemplo la clase del ejemplo #20 se llama Animación y deriva de la clase GameCanvas, Game Canvas es la clase y Animación es la subclase, esto es el concepto de herencia, que por lo pronto no ahondaremos en este concepto.

c) Public

Este identificador de acceso es el más sencillo y se ha visto ya en varios métodos que se han realizado, por ejemplo la definición del método run del ejemplo #19 es así:

public void run( ) {

    //código del método run
}

Note el identificador de acceso public, como siempre va al inicio del método, este tipo de acceso significa que todas las clases de todos los paquetes de clases tienen acceso al método, un paquete de clases, es un grupo de clases que se relacionan, por ejemplo, Java tiene el paquete de clases llamado Game, en donde está ubicada la clase GameCanvas y otras clases más que se relacionan porque sirven para la programación de juegos para el celular, recuerde los paquetes de clases se agregan al programa en Java usando la palabra import.

d) Package

Este nivel de acceso permite invocar métodos desde cualquier clase que este en el mismo paquete.

2. Valor de Regreso

Este es el segundo punto en la definición del método. Java por fuerza requiere que los métodos regresen un valor a la clase donde se invocan, valor se refiere a algún tipo de dato que se calculo o en el método, el tipo de datos son los ya conocidos, por ejemplo int, boolean, float, double, en el caso que el método creado no regrese ningún valor se coloca la palabra reservada void.

Regresando a nuestro ejemplo, deseamos crear un método para cargar las imágenes y otro para crear un subproceso, las imágenes se cargan con una simple instrucción e igual el subproceso, en otras palabras estos métodos no requieren que se regrese ningún valor, entonces se usa el void como valor de retorno, el método que vamos creando toma la siguiente forma:

private void Nombre_del_metodo( parametros ) {

//Código del método

}

En el siguiente post se hablará de los métodos que regresan valores.

3. Nombre del método

El nombre del método es la tercera parte de la definición del método, este nombre es elegido por el usuario, puede ser cualquiera pero recuerde las reglas básicas: no se vale escribir espacios, no se vale iniciar con un número o carácter alfanumérico, solo se vale el guión bajo.

En nuestro ejemplo el método va a cargar las imágenes, así que como nombre usamos: cargarImagenes entonces el método va quedando así:

private void cargarImagenes( parametros ) {

//Código del método

}

4.- Parámetros

La última parte de la definición del método son los parámetros, estos van después del nombre del método, y deben ir entre paréntesis, los parámetros que en algunos casos no son necesario, sirven como una especie de comunicación entre la clase que los invoca y el método creado por el usuario, en otras palabras, los parámetros son el medio para enviar información desde la clase que los invoca al método creado.

En el método que estamos diseñando no se requiere enviar ninguna información de nada, esto significa que no lleva parámetros por ende, los paréntesis van vacios así:

private void cargarImagenes( ) {

//Código del método

}

Listo la definición del método está terminada, ahora solo va el código necesario para cargar la imagen este código se vio arriba en el constructor de la clase Animación, el método completo y terminado queda así:

private void cargarImagenes( ){
   try {
   fondo = Image.createImage("/fondo.jpg");
   pelota = Image.createImage("/pelotita.gif");
   } catch (Exception e) { }
}

El lugar para colocar este código es en cualquier parte dentro de la clase, no importa donde esté Java lo busca.

También en otro post se mostrarán algunos métodos que si llevan parámetros.

Invocación del método

Para que este método se ejecute se debe mandar llamar o invocar desde alguna parte la clase, en este caso obviamente es desde el constructor, para hacerlo basta con colocar el nombre del método seguido de sus parámetros entre paréntesis, así:

cargarImagenes();

Entonces el constructor ya con la llamada al método queda así:

public Animacion() {
   super(true);
   g = getGraphics();
   cargarImagenes( );
   subproceso = new Thread(this);
   subproceso.start();

}

Eso es todo, cuando el NetBeans encuentre la invocación al método, el flujo de programa cambia, busca el método y ejecuta las instrucciones que ahí se indican, al terminar el método el flujo de programa se regresa a donde se quedo, esto queda más claro con una animación, una animación vale más que mil palabras.

La siguiente animación muestra el método creado junto con el constructor, así como se muestra es como Java ejecuta el método, todo inicia en el constructor, las instrucciones que están en el constructor es lo que se ejecuta primero, note como cambia el flujo de programa cuando se encuentra la instrucción para mandar llamar el método y observe también como al terminar el método el flujo de programa regresa a donde se había quedado.







Método para crear el subproceso

Enseguida se muestra la creación de otro método, el método que se diseñará simplemente crea el subproceso, ya sabemos que todo se inicia con el identificador de acceso, igual que el anterior lo colocamos como “prívate”, luego sigue el tipo de retorno, tampoco en este caso se regresa nada así que se coloca la palabra “void”, luego va el nombre del método, lo llamaremos “crearSubproceso”, luego va entre paréntesis la lista de parámetros, este método no los requiere así que los paréntesis van vacios, con lo anterior fácilmente se crea el método así:

private void crearSubproceso(){
   subproceso = new Thread(this);
   subproceso.start();
}

Para invocar el método, como ya se vio, basta con colocar su nombre así:

crearSubproceso()

Código Completo

El siguiente código muestra el constructor, note donde se ubica la instrucción para mandar llamar los métodos, junto con los dos métodos creados en esta sección, recuerde la ubicación de los métodos no lleva un orden pueden estar primero o después del constructor, Java los busca y los ejecuta, este es el código con los métodos creados por el usuario:

public Animacion() {
   super(true);
   g = getGraphics();
   cargarImagenes();
   crearSubproceso();
}

private void cargarImagenes(){
  try {
    fondo = Image.createImage("/fondo.jpg");
    pelota = Image.createImage("/pelotita.gif");
  } catch (Exception e) { }
}

private void crearSubproceso(){
  subproceso = new Thread(this);
  subproceso.start();
}

Observación final

Enseguida vuelvo a repetir el código para el constructor para el ejemplo #20 tal y como se mostro inicialmente:

public Animacion() {
   super(true);
   g = getGraphics();
   try {
      fondo = Image.createImage("/fondo.jpg");
      pelota = Image.createImage("/pelotita.gif");
   } catch (Exception e) { }
   subproceso = new Thread(this);
   subproceso.start();
}

Compare este constructor con todo el código anterior el de los métodos creados, los dos hacen exactamente lo mismo, crear las imágenes y el subproceso, pareciera que no se ve ventaja alguna, y quizá así es para este caso, pero créanme es altamente recomendable pensar en términos de métodos, en términos de dividir el problema en partes, por decirlo de alguna manera, las partes son los métodos, se anima al lector para que así lo haga y en adelante así se harán los video-tutoriales siguientes, son muchas las ventajas de usarlos, como se verá en un futuro.

Próxima entrada del blog

Este tema fue muy largo y aún así nos quedaron dos temas pendientes:

• Los métodos que regresan valores
• Los métodos con parámetros

Esto se abordara en la próxima entrada, que ojala sea esta misma semana.



Clic AQUI para leer más...!

sábado, 4 de septiembre de 2010

Ejemplo #20 Como detectar Eventos de teclado del celular



Hoy se va a mostrar el código para detectar las teclas presionadas por el usuario, se va a seguir trabajando con el código del ejemplo #19 y del ejemplo # 18, para ahora, mover la pelotita con las teclas del celular.

Usando la clase GameCanvas, de una forma por demás sencilla es posible detectar las teclas que se han presionado, algunas de las teclas ya vienen definidas en la clase, y son mostradas en la figura siguiente, con su respectivo nombre en Java:



Las mismas teclas están presentes en los números del teclado del celular, como se observa en la figura:

El método que detecta las teclas presionadas es el siguiente:

getKeyStates();

El método regresa un valor entero que corresponde a la tecla presionada, si regresa un valor entonces se debe declarar una variable así:

int ValorDeTeclado;

Ya con la variable declarada se puede usar el método así:

ValorDeTeclado = getKeyStates

La misma documentación de la clase GameCanvas muestra que con un simple if puedes detectar cualquiera de las teclas, por ejemplo, si deseas saber cuando se presiona la tecla que va hacia arriba (UP, que es la misma que la tecla del número 2) se coloca el if así:

if ((ValorDeTeclado & UP_PRESSED) != 0) {

    // Se ejecuta el código cuando se presiona la tecla UP

}

De igual forma se puede hacer para todas y cada una de las demás teclas.

Ahora vamos a aplicar esto para mover la pelotita del ejemplo anterior, recordando un poquito, este par de instrucciones, mueven automáticamente a la pelotita:

coordX = coordX + velX;
coordY = coordY + velY;

Ahora esas instrucciones o algo parecido debe ir dentro de los ifs que detectan las teclas ya que ahora se desea que la pelotita se mueva con respecto a la tecla presionada, por ejemplo, imagine el lector que la pelotita se encuentra en las coordenadas (150, 100), si se presiona la tecla UP la pelotita debe ir “para arriba”, pero “para arriba” significa la coordenada 0 en Y, recuerde el sistema de coordenadas de Java el primer pixel está en la coordenada (0, 0), entonces cada que se presione la tecla se debe realizar una resta así:

if ((valorDeTeclado & UP_PRESSED) != 0)
    coordY = coordY - velY;

Con eso basta para que la pelotita se mueva hacia arriba, no fueron necesarias las { } cuando menos no ahorita porque solo sigue una instrucción después del if.

Ahora, imagine el lector el que la pelotita esta en la coordenada Y en 100 y se presiona continuamente la tecla UP, llega un momento que la pelotita llega a la coordenada 0, si se deja intacto el código visto en el ejemplo #18 y #19, la pelotita rebota y cambia de dirección (cambiando el signo de la variable velY) eso, no es bueno, porque al cambiar el signo, ahora cambian las condiciones, y la pelotita no haría lo que se desea.

Mejor es, eliminar los ifs que hacían que la pelotita rebote. Ahora si se realiza esto, surge otro problema, regresando a las condiciones anteriores, la coordenada Y en 100 y se presiona continuamente la tecla UP, llega un momento en que la pelotita desaparece, esto debido a que se presiono la tecla UP de tal forma que rebaso la coordenada 0 y como se sigue restando, la coordenada Y se hizo negativa y la pelotita desaparece de nuestra visión.

Para resolver el conflicto, sería mejor que cuando llegue a la coordenada 0, la pelotita no se mueva aunque se siga presionando la tecla UP, esto se hace fácilmente con la instrucción siguiente:

if ((valorDeTeclado & UP_PRESSED) != 0)  {
    if ((coordY >0 )
           coordY = coordY - velY;
}

Otra opción quizá mas fácil es usar la función “max” de la clase Math, esta función, simplemente regresa el valor más alto, de los dos que se ponen como parámetros. Por ejemplo : Math.Max( 10, 5) regresa el valor de 10, otro ejemplo Math.Max(0, -5) regresa el 0, concluimos que siempre que ponga el 0 con un número negativo el valor máximo que regresa siempre va a ser 0, y con esta simple instrucción se resuelve el problema, inclusive si hago la resta de coordY con velY se puede reducir el código a algo tan simple como esto:

if ((valorDeTeclado & UP_PRESSED) != 0)
    coordY = Math.Max(0, coordY - velY);

Por otro lado, si se presiona la tecla hacía abajo (DOWN), Basta con hacer una suma dentro de un if parecido al anterior, pero ahora con DOWN_PRESSED, el código queda así:

if ((valorDeTeclado & DOWN_PRESSED) != 0)
   coordY = coordY + velY;

Pero, el ir para abajo no es tan sencillo, porque no se está tomando en cuenta el alto de la pelotita, el código anterior no funcionaría bien. Para resolver este problema, basta con colocar un if que nos detecte si se ha llegado al borde de la pantalla, algo como esto

if ((ValorDeTecla & DOWN_PRESSED) != 0) {
    if ((coordY + pelota.getHeight()) < alto )
         coordY = coordY + velY;
}

Listo se resuelve el problema en la coordenada Y, algo idéntico es usado para la coordenada X, cuando se presiona la tecla LEFT y RIGHT, no se muestra aquí para no ser repetitivo, pero en el video tutorial se ve claramente cúal es el código.

Bueno eso es todo en el post de hoy, termino presentando el video tutorial, para que como siempre no quede duda alguna en donde deben ir las instrucciones.



Clic AQUI para leer más...!

sábado, 28 de agosto de 2010

Ejemplo #19 Animación usando imágenes

El objetivo de este ejemplo es mostrar la misma animación que el post pasado, pero usando imágenes, la animación del ejemplo #18 se hizo usando figuras creadas con la misma clase Graphics, hoy se crean las imágenes con algún programa de dibujo y se agregan al mismo código visto en el post pasado, el resultado es exactamente el mismo, pero con imágenes se ve mejor el programa, vea la siguiente animación es lo que se pretende hacer.


>

Claro que se ve mejor está que la realizada con puras funciones de Java, para hacerla, se necesitan dos imágenes, por un lado el fondo del MIDlet y por otro lado la pelotita que si lo ven se ve muchísimo mejor que la anterior, según está dibujada en 3D, para realizar estas imágenes se requiere un programa de edición de imágenes, yo las hice usando el programa llamado PhotoImpact X3 de la empresa Corel, pero hay muchos programas algunos muy famosos como el Photoshop, el Corel Draw, incluso hasta el mismo Paint de Windows.

Creación de las imágenes usando el PhotoImpact X3

La figura siguiente muestra una pantalla del PhotImpact X3:


Solo me basto crear un archivo nuevo se le dieron las dimensiones deseadas (más adelante se dirán que dimensiones son) y se rellena con un color de fondo, el color de fondo se agrego usando una textura que ya vienen predefinidas en PhotImpact, se elige la textura deseada desde la Paleta de acceso fácil (se encuentra al lado derecho) y simplemente con dar doble clic en la textura elegida se rellena el archivo y listo ya tengo el fondo del MIDlet con una textura, esté se guarda como archivo jpg y ya.

Tamaño de la imagen de fondo
Algo importante es que la imagen de fondo debe ser exactamente del mismo tamaño que la pantalla del celular o bien pudierá ser más grande pero lo principal es que cubra toda la pantalla.

Fácilmente se puede ver el ancho y alto de la pantalla del celular, puesto que si el lector recuerda el código anterior viene un par de instrucciones que precisamente obtienen este valor, justo son las instrucciones siguientes:

int alto = getHeight();
int ancho = getWidth();

y una instrucción como la siguiente puede mostrar el ancho y el alto en la misma pantalla del celular:

g.drawString("Ancho = " + ancho +" y alto = " + alto, 10, 10, Graphics.TOP | Graphics.LEFT);

Vea el resultado de ejecutar el código con las líneas anteriores, en el emulador que hemos usado a lo largo del blog:



El ancho y alto del celular es 176, ejecute el programa en mi Sony Ericsson 705 y el resultado fue en ancho = 240 y alto = 266.

Si tu celular soporta Java puedes bajar el archivo JAR de este programa para que veas cuanto es el ancho y el alto de la pantalla de tu celular, dando clic aquí lo puedes bajar, este archivo se lo pase a mi celular usando el Bluetooh, también se puede hacer usando el cable USB.


Pelotita
Para realizar la pelotita fue también de lo más simple, con el photimpact se crea un circulo como se ve en la figura, para que se vea mejor se puso en 3D, esta opción la trae el Photo Impact, yo no sé si otros software la tienen, pero supongo que sí, puesto que Photoshop es superior al PhotoImpact.

Ahora vea que pasa si pongo la pelotita en el fondo anterior:

Como se puede observar, las imágenes son cuadradas obviamente y queda un fondo blanco que no es conveniente, porque no se ve bien la pelotita, este problema se resuelve bien fácil, se elije la pelotita con un fondo transparente, esto se puede hacer desde el PhotoImpact simplemente creando el fondo transparente y guardando el archivo como GIF o con formato PNG, el resultado de hacer esto es mostrado en la figura siguiente:



Obviamente se ve mejor, la imagen sigue teniendo el mismo rectángulo pero con el fondo transparente no se nota.

Agregando el código para las imágenes
Se vió algo parecido a lo que se va hacer en este ejemplo pero usando la clase Canvas si lo deseas puedes verlo dando clic aquí.

Bueno, partiendo del código del ejemplo #18 se agregan dos variables de tipo Image así:

Image fondo, pelota;

Para usar la clase Image, hay que hacer la importación del paquete de clases donde está ubicada, en otras palabras se escribe el siguiente código , antes de iniciar la clase:
import javax.microedition.lcdui.Image;

Ahora con este par de instrucciones se hace el enlace del archive físico de la imagen con la variable creada:

fondo = Image.createImage("/fondo.jpg");
pelota = Image.createImage("/pelotita.gif");

Por supuesto como ya se vio en la anterior entrada las imágenes deben estar en la ruta o directorio adecuado ¿no sabes cuál es? Da clic aquí y repasa, este punto ya se vio.

Estas instrucciones lanzan excepciones así que deben estar encerradas en su try y catch así:
try {
   fondo = Image.createImage("/fondo.jpg");
   pelota = Image.createImage("/pelotita.gif");
} catch(Exception e) { }

Es todo ahora simplemente se muestran en la pantalla así:

g.drawImage(fondo, 0, 0, Graphics.TOP | Graphics.LEFT);

y la pelotita así:

g.drawImage(pelota, coordX, coordY, Graphics.TOP | Graphics.LEFT);

También hay que tomar en cuenta el ancho y alto de la pelotita para hacer las comparaciones con el alto y ancho de la pantalla, se puede obtener el alto y ancho de la pelotita fácilmente, la clase Image tiene un par de métodos par ello, basta con este par de instrucciones:

Pelota.getWidth();
Pelota.getHeigh();

Estas se acomodan en los ifs donde se comparan las coordenadas, así:

if ((coordX + Pelota.getWidth()) > ancho || (coordX < 0 )
    velX = -velX;

Bueno eso es todo si existen dudas aquí les muestro el video tutorial para que vean donde se agregan las instrucciones vistas hoy.




Por cierto ya pueden pasar a visitar mi nuevo blog, dedicado a la electrónica, después de todo yo soy ingeniero en electrónica y mi fuerte debe ser la electrónica así que no duden en visitarlo, va creciendo poco a poco tengan paciencia, dando clic aquí lo pueden visitar.



Clic AQUI para leer más...!

miércoles, 18 de agosto de 2010

Ejemplo #18 “Animación usando GameCanvas: Pelota rebotando”



La animación es un proceso de movimiento de imágenes o dibujos, hoy se muestra un pelotita o bolita o circulo, rebotando por toda la pantalla del celular, esa es la primera animación de varias que se van a realizar. La animación siguiente muestra lo que se pretende hacer con Java en el celular:

>


Como hacer la pelotita
Recuerde que la clase Graphics contiene métodos para dibujar ya se han visto algunas de estos métodos, hay una función que me permite dibujar arcos se llama así

fillArc
Es posible realizar un círculo con esta función, esto se hace así porque la clase Graphics no tienen ninguna instrucción para directamente crear un círculo. La función anterior requiere de 4 parámetros, estos se puede ver en la ayuda de J2ME para la clase Graphics, los parámetros son así:

fillArc(int x, int y, int width, int height, startAngle, arcAngle);

Una imagen vale más que 1000 palabras, así que muestro un par de imágenes con la instrucción fillArc.

Aquí hay otra imagen, que muestra incluso dos líneas para que quede bien claro donde se ubica el circulo cuando se dibuja.
El lector puede seguir experimentando con los parámetros si así lo desea. Note que el primer par de parámetros, que en el ejemplo son (10, 10) ubican la posición de una esquina de un rectángulo imaginario, ese es el punto de referencia para iniciar el dibujo del círculo, después siguen las coordenadas (30, 30) que es el ancho y el alto del circulo, y luego va el ángulo de inicio y el ángulo del arco, para que sea un circulo completo se inicia con el ángulo en 0 y se termina con el ángulo en 360.

Por otro lado, en ese par de imágenes anteriores se puede ver que si la bolita se “desplaza” (primero se puso en la coordenada (0,0) y luego en la (10,10) ), podemos decir que la bolita “se movio”, eso es la animación, sensación de movimiento.

Ciclo para la animación
La animación, se puede resumir en lo siguiente: dibujar la pelota en una posición, borrar la pantalla y volver a dibujarla ahora en otra posición, y repetir todo, una y otra vez, ¿Cómo se hace esto? Bien simple con un ciclo, dando clic aquí para ver el post de los ciclos, si así lo deseas.

Por facilidad se usa el ciclo while(), la condición la colocamos en “true”, con eso basta para lograr un ciclo infinito, después de todo se desea que la pelotita rebote “siempre”, entonces el código para el ciclo es así:


while (true) {
   // código para la animación
}


Pero ¿Dónde va el ciclo? Sencillo, en el método run(), después de todo este ciclo se ejecuta cuando se inicia el subproceso, y como se vio en la entrada anterior aquí es donde van las instrucciones para graficar, así que el método run se va formando así:

public void run() {
   while (true) {
       // Código para la animación
    }
}


El método “sleep” del subproceso

Se mencionó arriba que la animación es simplemente dibujar, borrar, volver a dibujar en otra posición, borrar, y repetirlo, pero necesito hacerlo en pausas, es decir, dibujar por un tiempo (algunos milisegundos), luego borrar todo y volver a dibujar en otra posición después de otro tiempo, esto se puede realizar por medio del subproceso, ya se vio en el post anterior algo de los subprocesos, al crear y después de iniciar el subproceso, se puede hacer uso de sus métodos, hay un método llamado “sleep” (ver la documentación de la clase Thread, si se desean ver más detalles), este método me permite hacer una pausa, un ejemplo en código puede ser el siguiente:

subproceso.sleep(100);

Al ejecutar esa instrucción el programa se detiene durante 100 milisegundos, este método debe ser encerrado en un par de instrucciones así:

try {
  subproceso.sleep(10);
} catch (InterruptedException e) { }


El “try y catch” son requeridos por el programa, si no se agregan hay un error de compilación y nunca podre ejecutar el programa. Esas instrucciones, me permiten capturar algún error, en java se llaman excepciones, ya que el método sleep, puede crear errores por eso se usa el “try” y el “catch”, el código va dentro del ciclo while y va quedando así:


public void run() {
  while (true) {
    // Código para la animación
    try {
      subproceso.sleep(100);
    } catch (InterruptedException e) { }
  }
}

No se profundizará sobre las excepciones quizá más adelante se haga un post de esto, por lo pronto nos interesa la animación, así que continuamos.

Variables usadas en la animación
Se vio en la sección anterior, que la pelotita se “mueve” con solo mover el parámetro x y el parámetro y de fillArc, entonces, como inicio se pueden declarar esos parámetros con una variable para después cambiarlos, así:

int coordX = 0;
int coordY = 0

Recuerde que la declaración va al inicio del método, ya con las variables declaradas, se puede crear el circulo con la instrucción fillArc, en este caso es un circulo con 20 pixeles de ancho y alto, esta es la instrucción

g.fillArc(coordX, coordY, 20, 20, 0, 360)

La instrucción va dentro del ciclo, el código toma la forma siguiente:

public void run() {
  int coordX = 0;
  int coordY = 0
  while (true) {
     g.fillArc(coordX, coordY, 20, 20, 0, 360)   

     try {
       subproceso.sleep(100);
    } catch (InterruptedException e) { }

  }
}

¿Ahora que se necesitará para mover la pelotitia? Simplemente desplazar las coordenadas, estas que son variables se pueden desplazar sumandoles un valor, así:
coordX = coordX + 1
coordY = coordY + 1

Otro ejemplo sería así:

coordX = coordX + 5
coordY = coordY + 5

O uno con desplazamientos diferentes,

coordX = coordX + 5
coordY = coordY + 3

Vea los ejemplos, en el primero solo se desplaza la pelotita 1 pixel, el segundo 5 pixeles ¿Qué diferencia hay? Entre 1 pixel o 5 pixeles en el desplazamiento, la animación siguiente nos da la respuesta:

>

Nota: La animación es para fines ilustrativos solamente, está realizada con un programa llamado SwishMax 2, por lo que no se si vaya más rápido o más lento cuando se programe en Java.

Obviamente la pelotita va más rápido con 5 pixeles que con 1, por que los incrementos en las coordenadas son mayores, podemos entonces decir que el sumarle una variable a la coordenada hace que se cambie su velocidad, por comodidad se va a almacenar este desplazamiento en variables también, se declaran así:

int velX = 5;
int velY = 5;


Yo las inicie en 5, el lector puede hacerlo en 1 o en otro valor, queda el código así:
public void run() {
   int coordX = 0;
   int coordY = 0;
   int velX = 5;
   int velY = 5;
 

   while (true) {
     g.fillArc(coordX, coordY, 20, 20, 0, 360)
     try {
       subproceso.sleep(100);
     } catch (InterruptedException e) { }
     coordX = coordX + velX;
     coordY = coordY + velY;
   }
}

Es obvio también, que si se ejecuta este código la pelotita se va de largo ¿Por qué? Ya se imaginará el lector que falta agregar un código que haga que la pelotita rebote esto es que cambie de dirección como se ve en la figura:


Aparte, en la figura se observa donde está el punto (0,0) en el sistema de coordenadas de Java para que el lector lo recuerde, también se muestra el alto y ancho de la pantalla, que es donde la pelotita rebota, entonces bastaría con que yo compare la posición de la pelotita para saber si llego a lo alto de la pantalla (o a lo ancho) y simplemente cambio de dirección.

Entonces, una simple comparación puede detectar si la pelotita llego a lo alto del panel, primero pues vamos a usar un par de variables para obtener el alto y ancho del panel así:

int ancho = getWidth();
int alto = getHeight();

Ahora sí, se inician las comparaciones, que tal un if para “ver “ si ya toco el alto así:

if (coordY > alto) {
  // código para cambiar de dirección
}

Pero vea la figura y recuerde lo que se menciono arriba, el círculo se dibuja tomando como referencia la esquina de un rectángulo, que justo son las coordenadas x e y:



¿Cómo se cambia la dirección?

La respuesta es bien simple, para el ejemplo que se muestra, la pelotita se desplaza hacia abajo por que se suma se suma la velocidad (variable velY) pero que tal si envés de sumar se resta la velocidad, la pelotita se iría hacia arriba.

Entonces para que la pelotita cambie la dirección basta con restar la velocidad, esto se hace simplemente con cambiar el signo de la variable así:

velY = -velY;

Con esa instrucción la pelotita rebotará al llegar a lo alto de la pantalla, el código del método run queda de la siguiente forma al agregar el primer if:

public void run() {
 int coordX = 0;
 int coordY = 0;
 int velX = 5;
 int velY = 5;
 while (true) {
   g.fillArc(coordX, coordY, 20, 20, 0, 360)
   try {
     subproceso.sleep(100);
   } catch (InterruptedException e) { }
   coordX = coordX + velX;
   coordY = coordY + velY;
   if ((coordY + 20) > alto) {
     velY = -velY;
   }
 

 }
}
Ahora vea en la figura el siguiente caso que tiene que ver con la coordenada Y todavía:

La pelotita se dirige a la coordenada 0, de Y, para ese momento la velocidad es negativa obviamente deseamos que rebote de ahí, entonces se requiere otra comparación para hacerlo, así:

if (coordY < 0) {
   velY = -velY;
}
Con eso basta para que detecte el límite de la pantalla y al cambiar de signo la velocidad, la pelotita cambia de dirección.

Es posible unir los dos if’s para la coordenada Y usando el operador OR (operador lógico) de Java, el operador OR en Java es así || el código queda entonces con un solo if de esta forma:

if ((coordY + 20) > alto || (coordY < 0 ))
  velY = -velY;
También quitamos las { }, puesto que sigue solo una instrucción no son necesarias.

Todo lo que se hizo para la coordenada Y se aplica para la coordenada X y el ancho de la pantalla , así que les dejo como va quedando el código para el método run ya con los if’s para las ambas coordenadas

public void run() {
  int coordX =0, coordY=50;
  int velX = 5;
  int velY = 5;
  int ancho = getWidth();
  int alto = getHeight();
  while(true) {
    g.fillArc(coordX,coordY,20,20,0,360);
    try {
      subproceso.sleep(30);
    } catch (InterruptedException e) { }
    coordX = coordX + velX;
    coordY = coordY + velY;
    if ((coordX + 20) > ancho || (coordX < 0) )

       velX = -velX;
    if ((coordY + 20) > alto || (coordY < 0 ))
       velY = -velY; 

    flushGraphics();
  }
}

También en el código anterior se agrego  el método flushGraphics al final del código.

Recuerde la animación es un ciclo de dibujar, borrar, dibujar en otra posición, borrar…. Y así sucesivamente, para terminar falta el borrado el código anterior, no funcionaría como se desea si no es borrada la pantalla, esto se hace colocando el fondo del color que se quiera, en este caso es en color negro, aparte se agrega el código para pintar la pelotita en color azul.

g.setColor(0x000000); //color negro
g.fillRect(0, 0, ancho, alto);
g.setColor(0x0000FF); //color azul


Por fin se muestra el código completo para el método run(), el código para borrar se coloca después del while

public void run() {
  int coordX =0, coordY=50;
  int velX = 5;
  int velY = 5;
  int ancho = getWidth();
  int alto = getHeight();
  while(true) {
    g.setColor(0x000000); //color negro
    g.fillRect(0, 0, ancho, alto);
    g.setColor(0x0000FF); //color azul
   

    g.fillArc(coordX,coordY,20,20,0,360);
    try {
      subproceso.sleep(30);
    } catch (InterruptedException e) { }
    coordX = coordX + velX;
    coordY = coordY + velY;
    if ((coordX + 20) > ancho || (coordX < 0 )

      velX = -velX;
    if ((coordY + 20) > alto || (coordY < 0 ))
      velY = -velY;
    flushGraphics();
  }
}

Vaya este post se me hizo larguísimo, pero ya es todo, fiel a mi costumbre se muestra el video-tutorial completito para que no haya errores de ningún tipo y el lector pueda implementarlo con toda la confianza del mundo.
 




Clic AQUI para leer más...!

sábado, 7 de agosto de 2010

Ejemplo #17 “Hola mundo usando la clase GameCanvas”



Ya se vieron a lo largo del blog, varios video tutoriales donde se muestra como se usa la clase Canvas para dibujar elementos gráficos, incluso en el último ejemplo se gráfica la función seno en el celular, ahora veremos una clase que nos permitirá realizar animaciones fácilmente, se mostrará el ejemplo más sencillo que puede haber para esta clase, el clásico mensaje “Hola Mundo”, así que iniciemos.

La Clase GameCanvas

En este post se muestra la clase GameCanvas diseñada para simplificar el desarrollo de juegos para el teléfono celular. Con esta clase es muy fácil detectar las teclas que son presionadas por el usuario además fácilmente se actualiza la pantalla, sin necesidad de usar la técnica llamada doble buffer, la cual tampoco veremos aquí pues ya no se necesita, además esta clase está optimizada precisamente para la programación de juegos, esté ejemplo y los siguientes mostrarán ejemplos sencillos de su uso.

Se presenta detalladamente las partes de la clase y como se va codificando, quizá sea repetitivo al volver escribir a cada rato la clase, pero me gusta hacerlo así, creo que así queda más claro.

Siguiendo el mismo procedimiento que los ejemplos de la clase Canvas, se crea primero una clase que derive o herede de la clase GameCanvas, en código es así:

public class EjemploGameCanvas extends GameCanvas {
// Código de la clase
}

El nombre de la clase es EjemploGameCanvas, recuerda que en Java para definir la herencia se usa la palabra extends, entonces la clase EjemploGameCanvas hereda todos los métodos y atributos de la clase GameCanvas, por cierto a su vez la clase GameCanvas deriva de la clase Canvas.

Por otro lado la pura definición como está arriba nos marcaría error, puesto que hay que importar el paquete de clases donde se ubica la clase GameCanvas, la instrucción Import lo hace, se codifica como se muestra enseguida y se coloca al iniciar la clase:

import javax.microedition.lcdui.game.*;

Pero eso no es todo, está clase porque así está diseñada, se debe ejecutar en su propio “subproceso”, para implementar esto en Java se usa la interfaz Runnable, para hacerlo se escribe en la definición de la clase el “implements Runnable” así:

import javax.microedition.lcdui.game.*;
public class EjemploGameCanvas extends GameCanvas implements Runnable {
    // Código de la clase
}

Veamos una explicación muy superficial de los subprocesos.

Subprocesos

Para ver el concepto de subproceso se debe pensar en, por ejemplo, el procesador de textos Word, donde precisamente estoy escribiendo este texto, el Word fue programado para que haga varias tareas digamos “al mismo tiempo”, por ejemplo mientras se escribe el texto, Word crea un subproceso para verificar la ortografía la cuál señala con una línea roja, entonces Word se dice que es multitarea, esto es, la realización aparente de poder hacer varias tareas “al mismo tiempo”, aunque esto no es verdad puesto que las computadoras solo tienen un único procesador, pero como estos ejecutan millones de instrucciones por segundo nos dan la ilusión de que lo hace en paralelo

Para dar esta ilusión de ejecutar las instrucciones en paralelo en Java, se usan los subprocesos, en nuestro caso se usan en clase Game Canvas, porque esta clase debe aislarse del resto del código, además así se diseño esta clase, para facilitarnos la vida a la hora de programar animaciones y juegos, por eso se agrega a la definición de la clase el “implements Runnable” ese es el primer paso para crear el subproceso, pero todavía faltan más cosas.

Constructor de la clase

Por otro lado, olvidándonos un momentito de los subprocesos, recuerde algo, todas las clases deben llevar su constructor (método que se llama igual que la clase) y que generalmente sirve para inicializar variables que se usaran a lo largo del programa.

El constructor de la clase que hereda de GameCanvas, según la documentación, requiere un parámetro que es de tipo booleano (verdadero o falso), si es verdadero se suprimen los mecanismos para los eventos de las teclas, si es falso se activan los mecanismos y se pueden detectar fácilmente las teclas que se han presionado, esto se verá después por lo pronto nosotros le vamos agregar al constructor el parámetro “true” puesto que solo se mostrará un mensaje en la pantalla, entonces el constructor para la clase que acabamos de crear es así:

public class EjemploGameCanvas extends GameCanvas implements Runnable {
    public EjemploGameCanvas () {
      super(true); // código del constructor
    }
}
Vea la instrucción

super(true)

Justo ahí se le envía el valor de verdadero (true), la instrucción “super” significa que se manda llamar el constructor de la superclase, recuerde la herencia, Canvas es la superclase de GameCanvas, esté es un requisito para usar la clase GameCanvas, si no se llama el constructor de la superclase simplemente nos marca un error de compilación.

El método run

Regresando a los subprocesos, toda clase que lleve en su definición el “implements Runnable” debe a fuerzas implementar el método run() este método es la clave de los subprocesos, cuando se activa el subproceso, este método es el que se ejecuta, la clase ahora agregando el método run toma la forma siguiente:

public class EjemploGameCanvas extends GameCanvas implements Runnable {
   public EjemploGameCanvas () {
      super(true); // código del constructor
   }
   public void run() {
     //Código del subproceso
   }
}
El Método getGraphics()

Por otro lado, la clase GameCanvas contiene varios métodos, uno de ellos es getGraphics(), este método es el primer paso para iniciar a dibujar en el GameCanvas, el método regresa un objeto tipo grafico con el que posteriormente se dibuja, la instrucción para usarlo es así:

g = getGraphics();

g es el objeto gráfico, pero recuerde, en Java todo se debe declarar antes de usar, para declarar un objeto es bien simple, inicia con el nombre de la clase (en este caso Graphics), seguido por el nombre que yo desee (yo quiero la “g”) la declaración queda así :

Graphics g;

¿Donde va este código?, la declaración la colocamos después de la definición de la clase, y la llamada al método en el constructor que es el método que se ejecuta primero, así se prepara todo para iniciar el dibujo en el GameCanvas, queda entonces la clase así:



public class EjemploGameCanvas extends GameCanvas implements Runnable {
  Graphics g;
  public EjemploGameCanvas () {
  super(true); // código del constructor
    g = getGraphics();
  }
  public void run() {
    //Código para el subproceso
  }
}


Creación del Subproceso

Otra vez regresamos a los subprocesos, no basta con escribir el “implements Runnable” y el método “run” se debe en verdad crear el subproceso, esto se hace creando un objeto de la clase Thread, como se crea el objeto, ya lo vimos, primero se declara y se crea usando la palabra new, esto incluso se puede escribir en una sola línea así:

Thread subproceso = new Thread(this);

O como el objeto g, en dos líneas, con la excepción de que g no requiere la palabra new.

Ya está creado el subproceso con la línea anterior pero mientras no se inicie jamás se va a ejecutar el método run, así que para iniciarlo basta con mandar llamar su método start así:

subproceso.start();

¿Dónde va el código? Nos conviene que se inicie inmediatamente, después de todo nuestro primer ejemplo solo mostrará “hola mundo en la pantalla” y ya, así que de nueva cuenta el constructor es buena idea para este código, queda entonces la clase así:

public class EjemploGameCanvas extends GameCanvas implements Runnable {
  Graphics g;
  public EjemploGameCanvas () {
     super(true); // código del constructor
     g = getGraphics();
     Thread subproceso = new Thread(this);
     subproceso.start();
  }
  public void run() {
   //Código
  }
}

Ahora si a Dibujar

Listo tenemos todos los elementos para empezar a dibujar lo que querramos en la pantalla del celular, usando de por medio el objeto “g” tal y como se hizo con la clase Canvas, esto ya se vio por lo que no entrare en detalles, el código siguiente coloca la pantalla del celular en negro y escribe “hola Mundo usando GameCanvas”, en color magenta creo.

// pantalla en negro
g.setColor(0x000000);
g.fillRect(0, 0, getWidth(), getHeight());
// dibujo de las letras “hola mundo…
g.setColor(0xff00FF);
g.drawString("Hola mundo, con GameCanvas", 0, 60, Graphics.LEFT | Graphics.TOP);

¿Dónde va el código? En el método run() después de todo es el que se ejecuta al iniciar el subproceso, antes de ver donde, veamos otro método de la clase GameCanvas.

El método flushGraphics();

Este método, también de la clase GameCanvas es usado para colocar realmente en la pantalla del celular lo dibujado por el objeto “g”, el código anterior que pinta la pantalla de negro y dibuja el letrero esta en la memoria o como le llaman en el “buffer” y no se puede ver, hasta que se invoque el método flushGraphics(), al hacerlo se ve ahora si lo dibujado, este código va al final, despueés del método drawString, también va en el método run, queda finalmente el código así:

public class EjemploGameCanvas extends GameCanvas implements Runnable {
  Graphics g;
  public EjemploGameCanvas () {
    super(true); // código del constructor
    g = getGraphics();
    Thread subproceso = new Thread(this);
    subproceso.start();
  }
  public void run() {
    // pantalla en negro
    g.setColor(0x000000);
    g.fillRect(0, 0, getWidth(), getHeight());
    // dibujo de las letras “hola mundo…
    g.setColor(0xff00FF);
    g.drawString("Hola mundo, con GameCanvas", 0, 60, Graphics.LEFT |   Graphics.TOP);
   flushGraphics();
  }
}

Video

Enseguida se muestra el video para este ejemplo, recuerde que se requiere el MIDlet principal para mandar llamar la clase que hereda de GameCanvas esto ya se vio en un post anterior, por eso no lo repito aquí, aún así el tutorial muestra todo el procedimiento, todo él código para agregar la clase creada al MIDlet.




Clic AQUI para leer más...!