6. Dispositivos de entrada y salidaEste tutorial aprenderemos a usar los botones y el stylus con nuestros homebrews, es una parte basica muy importante.
Es algo más largo de la cuenta y mas dificil que los tutoriales anteriores.Asi que atentos
6.1 La estructuras condicionales
Veremos las formas mas basicas para expresar condiciones en C. Eso lo usaremos mucho en este tutorial. Empezaremos por la estructura if que es la mas basica y importante.
Lo primero es saber para que sirve y que es la "estructura if".
La estructura if es asi:
if (condicion) {
Suceso que ocurre
}
Esto es muy sencillo, si se cumple la condicion que esta entre parentesis (por ejemplo, que mantengas pulsado el boton A) ocurre un suceso determinado.
Os pongo un ejemplo:
if (1+1 == 2) {
PA_OutputSimpleText(1,5,5,"La ds sabe sumar y todo
");
}
Aqui estamos diciendo que si la suma de 1+1 es igual a 2. Aparecera el texto de ahi
.
Supongo que os habreis dado cuenta que he puesto dos veces el igual. Hay que ponerlo dos veces para que compruebe la igualdad. Si no lo hara.
Os pongo otro ejemplo de if por si no os ha quedado del todo claro:
if (Pad.NewPress.A){
PA_OuputSimpleText(1,5,5,"Has pulsado el boton A");
}
Le estamos diciendo que si pulsamos el boton A (Pad = botón NewPress = Pulsacion y A es igual al boton A). Nos saldra un texto...
Por ultimo queda por decir algunos operadores para el if, por ejemplo para expresar una doble condicion habria que poner:
if ((condicion 1)&& (condicion 2)){
Suceso...
}
Ejemplo:
if ((Pad.Held.A)&& (Pad.Held.B)){
PA_EasyBgLoad(0,2,"Prueba");
}
Con esto le estamos diciendo que si mantenemos pulsado el boton A y B (hold = mantener). Se nos cargara un fondo.
Otro operador es el || que seria como decir "o". Para ocurra la accion tiene que cumple una de las dos condiciones. Ejemplo:
if ((Pad.Held.A) || (Pad.Held.B)){
PA_EasyBgLoad(0,2,"Prueba");
}
Para que se carge el fondo, tienes que mantener pulsado el boton A o el boton B...
Y el ultimo operador que vamos a ver es el ! que seria como decir "no". Si la condicion que hemos puesto no se cumple. Comienza la accion. Un ejemplo:
if (!Pad.Held.A){
PA_EasyBgLoad(0,2,"Prueba");
}
Si no matenemos pulsado el boton A. Se nos cargara el fondo <img class="inlineimg" src="http://www.espalnds.com/foros/images/smilies/smile.gif" border="0" />
Una vez terminados de dar los operadores.Pasaremos a otra cosa, hablaremos del while. Funciona de la misma manera que el if. Solo que este se repite continuamente mientras que la condicion este activa.
Un ejemplo:
while (1+1 == 2){
PA_OutputSimpleText(1,5,5,"Hola!");
}
Con esto estamos diciendo, que mientras que la suma de 1+1 sea dos. El codigo entre los corchetes ( { y } ) se repetira continuamente. Este ejemplo no tiene sentido, pero es un ejemplo al menos
.
6.2 Botones y Stylus Sabiendo la estructura if. Usar los botones es muy facil. Tendremos que poner lo siguiente en la condicion:
Códigos para los botones:
Pad.Newpress.botón: La accion comienza cuando pulsas el boton que has indicado (A,B,X,Y,L,R, Start, Select y up,left,right,down para el pad)
Pad.Held.botón: La accion comienza cuando mantienes pulsado un boton, que pueden ser cualquiera de los antes citados
Pad.Released.botón: La accion comienzas cuando sueltas el boton, es decir. Lo mantienes pulsado y en el momento justo que lo sueltas, se activa la accion.
Códigos para el stylus: Stylus.Newpress Como con los botones.
Stylus.Held Como los botones.
Stylus.Released Como los botones.
Bien, antes de pòner el ejemplo que siempre pongo. Os voy a comentar una cosa, os acordais del codigo minimo que tiene que haber en una aplicacion de palib?:
#include <PA9.h>
int main(int argc, char ** argv)
{
PA_Init();
PA_InitVBL();
while (1)
{
PA_WaitForVBL();
}
return 0;
}
Pos bien, situaremos la estructura if (para usar los botones) dentro del while (1).
Por que?. Pos como dijimos antes, en un while el codigo que hay entre los parentesis se repite continuamente si la condicion es cierta. La condicion que esta puesta es... Es dificil de explicar, pero resumo que esa condicion siempre se cumple y que por tanto ese while se repite siempre.
Que por que no lo situamos como lo hemos hecho siempre?. Sencillo, el nds se ejecuta de forma lineal, de forma que cuando pasamos la linea del codigo donde esta el if, por mucho que pulsemos los botones no nos servira
. Si lo metemos dentro del while, como se ejecuta continuamente, podremos pulsarlo en cualquier momento...
Bueno pasemos al ejemplo de marras:
#include <PA9.h>
int main(int argc, char ** argv)
{
PA_Init();
PA_InitVBL();
PA_InitText(1, 1);
PA_InitText(0, 1);
PA_OutputSimpleText(1,10,20,"Bienvenidos al testeador de botones de amchacon");
PA_OutputSimpleText(1,10,25,"Pulsa un boton para empezar");
while (1)
{
if (Pad.Held.A){
PA_OutputSimpleText(0,10,12,"Esta pulsando el boton A");
}
if (Pad.Held.B){
PA_OutputSimpleText(0,10,12,"Esta pulsando el boton B");
}
if (Pad.Held.X){
PA_OutputSimpleText(0,10,12,"Esta pulsando el boton X");
}
if (Pad.Held.Y){
PA_OutputSimpleText(0,10,12,"Esta pulsando el boton Y");
}
if (Pad.Held.L){
PA_OutputSimpleText(0,10,12,"Esta pulsando el boton L");
}
if (Pad.Held.R){
PA_OutputSimpleText(0,10,12,"Esta pulsando el boton R");
}
if (Stylus.Held){
PA_OutputSimpleText(0,10,12,"Esta tocando la pantalla tactil");
}
PA_WaitForVBL();
}
return 0;
}
Ale!. Y ahora a otra cosa
Aprenderemos ahora a usar el stylus para realizar acciones (si tocas en este punto con el stylus. Ocurrira tal cosa, si tocas el sprite se movera.... Etc)
Esto es bastante facil, si queremos que la accion ocurra cuando el stylus pulse las coordenadas 40,40:
if ((Stylus.X == 40)&& (Stylus.Y == 40)){
PA_OutputSimpleText(0,8,8,"Ola!");
}
El "Stylus.x" se refiere a la posicion x del stylus y el stylus.y a la posicion y del stylus.
Facil no?. Si queremos que pulse cualquier punto de una zona:
if((Stylus.Y>0) && (Stylus.Y<40)&& (Stylus.X>0) && (Stylus.X<40)){
PA_OutputSimpleText(0,8,8,"Ola!");
}
Los signos < y > significan mayor o menos que...
Con esto haremos que si pulsamos con el stylus entre las coordenadas 0-40 se active la accion ( si el stylus es mayor que 0 y menor que 40 se cumple la accion. Por tanto, cualquier pulsacion entre 0 y 40 cumplira la accion ).
En ocasiones querremos que la accion empieze cuando pulsamos un sprite, nada mas facil:
if (PA_SpriteTouched(numero de sprite)){
PA_OutputSimpleText(1,5,5,"Hola!
}
Facil no?. Pasamos a otra cosa entonces...
6.3 Mover un sprite Ya repasando algo del tutorial anterior, vamos a aprender a mover los sprites. Tanto con el stylus como con los botones.
Este sprite es el ideal, supongo que os sonara del tutorial anterior
:
Empezamos con moverlo con el stylus (tactil). Que es mas facil...
6.3.1 Mover un sprite con el stylus Es tan facil como poner esto en el while:
PA_MoveSprite(0//Numero de sprite
);
Facil no?
. Como siempre pongo el codigo entero para evitar dudas:
#include <PA9.h>
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
int main(int argc, char ** argv)
{
PA_Init();
PA_InitVBL();
PA_LoadSpritePal(0,0,(void*)sprite0_Pal);
PA_CreateSprite(0,0,(void*)Mouse_Sprite,OBJ_SIZE_32X32,1,0, 50, 50);
while (1)
{
PA_MoveSprite(0);
PA_WaitForVBL();
}
return 0;
}
Y listo, lo podreis mover con el stylus...
6.3.2 Mover un sprite con el Pad Esto es ligeramente mas dificil. Usaremos las variables para logra este fin...
Que son las variables?. Digamos que es una forma de almacenar datos ya sea un caracter, un valor, un digito etc... La variable que usaremos sera para un numero (la posicion del sprite). Para crearla:
s32 Y_aqui_el_nombre_que_querramos_ponerle_a_la_ variable_sin_espacios = El numero que quieras ponerle
Creare dos variables, una para la posicion x del sprite y otra para la posicion y. Las llamare X y Y para que sea mas facil distinguirlas. Y le daremos el valor inicial que queramos:
s32 x = 10
s32 y = 10
Y para que vamos a usar una variable?. Muy sencillo, como he dicho guardaremos la posicion del sprite en esa variable, y luego cuando pulsemos arriba, izquierda, derecha, abajo modificaremos su valor y por tanto haremos que el sprite se mueva.
Para fijar la posicion del sprite en las variables basta con poner esto en el while:
PA_SetSpriteXY(0, 0, x, // Fijaremos la coordenada x del sprite en la variable x
y);// Lo mismo pero en la coordenada y.
Bien, para modificar el valor del sprite al pulsar los botones del pad. Podremos usar un if:
if (Pad.Held.Up){
y += 1 //Sumamos un valor a la y. En c se suma asi...
}
Pero yo personalmente prefiero usar esto, que ocupa menos codigo y es mas funcional:
x += Pad.Held.Right - Pad.Held.Left;
y += Pad.Held.Down - Pad.Held.Up;</p>
La razon de esto puede ser algo complicada si no sabes C. Pero si quereis, os lo explico en un rato (no es muy dificil).
Para entenderlo hemos de saber que las condiciones de los botones tienen dos valores. El 1 que significa activo y el 0 que significa que no lo esta.
Asi seria:
Códigos para los botones:
Pad.Newpress.botón: Cuando pulsas un nuevo boton, da un valor de 1.
Pad.Held.botón: Mientras mantienes pulsado, da un valor de 1
Pad.Released.botón: Cuando sueltas un boton, da un valor de 1
Códigos para el stylus: Stylus.Newpress Como con los botones.
Stylus.Held Como los botones.
Stylus.Released Como los botones.
Sabiendo esto, veamos otra vez el codigo:
x += Pad.Held.Right - Pad.Held.Left;
y += Pad.Held.Down - Pad.Held.Up;
Nos fijamos en la linea de la x:
x += Pad.Held.Right - Pad.Held.Left;
Si matenemos pulsado el boton derecho del pad y el izquierdo no. Los valores serian asi:
x += 1 - 0;
El resultado de la resta seria:
x += 1
La x se incrementa en 1 mientras que el boton derecho se mantenga pulsado. Como bien sabemos, esta variable representa la posicion x del sprite por tanto el sprite se moveria hacia la derecha <img class="inlineimg" src="http://www.espalnds.com/foros/images/smilies/wink.gif" border="0" /> (al incrementar la x...)
Si manteniesemos pulsado el boton izquierdo, los valores serian asi:
x += 0 - 1;
Resultado:
x += - 1;
La x disminuiria en 1 mientras el boton izquierdo se mantuviera pulsado <img class="inlineimg" src="http://www.espalnds.com/foros/images/smilies/wink.gif" border="0" />. Por tanto el sprite se moveria hacia la izquierda (al disminuir la x...)
Con la siguiente linea pasa exactamente igual:
y += Pad.Held.Down - Pad.Held.Up;
y += 1 - 0;
y += 1;
Etc...
Una vez todo explicado. Pongo todo el codigo para que os quede todo claro:
#include <PA9.h>
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
s32 x = 10;
s32 y = 10;
int main(int argc, char ** argv)
{
PA_Init();
PA_InitVBL();
PA_LoadSpritePal(0,0,(void*)sprite0_Pal);
PA_CreateSprite(0,0,(void*)Mouse_Sprite,OBJ_SIZE_32X32,1,0, 50, 50);
while (1)
{
x += Pad.Held.Right - Pad.Held.Left;
y += Pad.Held.Down - Pad.Held.Up;
PA_SetSpriteXY(0, 0, x,y);
PA_WaitForVBL();
}
return 0;
}
Y listo, ya hemos terminado.
Podreis aprovechar todo lo que habeis aprendido en este tutorial para hacer practicas por vosotros mismos (hacer un testeador de botones, un pequeño minijuego...). Con lo que ya sabeis podreis hacerlo sin problemas <img class="inlineimg" src="http://www.espalnds.com/foros/images/smilies/wink.gif" border="0" />
Saludos</p></p>