[Tutoriales Palib] 6. Dispositivos de entrada y salida

6. Dispositivos de entrada y salida

Este 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 XD");
}


Aqui estamos diciendo que si la suma de 1+1 es igual a 2. Aparecera el texto de ahi XD.

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 XD.

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 XD. 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 XD

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 XD:

Imagen

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? XD. 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 XD
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>
cuanto tiempo sin un tutorial(ni por parte de plata, ni por parte de amchacon)... XD

oye, ¿que tal va tu proyecto, el de "the way of mouse?"? :-?
amchacon escribió:...

if (Pad.Held.A)&& (Pad.Held.B){
PA_EasyBgLoad(0,2,"Prueba");
}



Eso está mal.. es:
if ( Pad.Held.A && Pad.Held.B){
PA_EasyBgLoad(0,2,"Prueba");
}


Ademas tambien has olvidado poner otro operador logico, el OR que se representa como ||, y que sirve cuando quieres que entre al darse una de las condiciones, es decir

si ocurre A o ocurre B
haz C

se traduce:

if( CondicionA || CondicionB){
C;
}
C suele ser un conjunto de acciones, pero cuando es solo una no es necesario poner las llaves.

Ademas tambien es bueno saber que si pones la exclamacion delante de una condicion, es como poner que sea falso. Es decir, si quieres que entre cuando no se da la condicion A:

if(!CondicionA){
conjunto de acciones;
}

No se que mas poner...
magic black 2009 escribió:cuanto tiempo sin un tutorial(ni por parte de plata, ni por parte de amchacon)... XD

oye, ¿que tal va tu proyecto, el de "the way of mouse?"? :-?

Esque daba pereza XD. Asi que he tardado un poco.

Pos tengo el ordenador de las palib roto. Asi que no puedo compilar... Para la semana lo tendre operativo seguramente...

Suikoden77 escribió:
amchacon escribió:...

if (Pad.Held.A)&& (Pad.Held.B){
PA_EasyBgLoad(0,2,"Prueba");
}



Eso está mal.. es:
if ( Pad.Held.A && Pad.Held.B){
PA_EasyBgLoad(0,2,"Prueba");
}


Ademas tambien has olvidado poner otro operador logico, el OR que se representa como ||, y que sirve cuando quieres que entre al darse una de las condiciones, es decir

si ocurre A o ocurre B
haz C

se traduce:

if( CondicionA || CondicionB){
C;
}
C suele ser un conjunto de acciones, pero cuando es solo una no es necesario poner las llaves.

Ademas tambien es bueno saber que si pones la exclamacion delante de una condicion, es como poner que sea falso. Es decir, si quieres que entre cuando no se da la condicion A:

if(!CondicionA){
conjunto de acciones;
}

No se que mas poner...

Ya empezamos con los problemas XD

Yo de toda la vida lo he puesto en parentesis separados y nunca me ha dado error al compilar:

if (Pad.Held.A)&& (Pad.Held.B){
PA_EasyBgLoad(0,2,"Prueba");
}


Por tanto yo lo he puesto asi...

Los operadores || y ! los conozco, pero no los he puesto porque me parecen menos importantes, para no alargar mas el tutorial y ademas meter mas conceptos de los que he puesto. Pienso que pueden crear confusion entre ellos... A lo mejor cambio luego de opinion y los añado al tutorial XD. Depende del tiempo libre y de las ganas que tenga (hasta para 5-10 lineas soy peresozo XD)....

Saludos!
amchacon escribió:
if (condicion 1)&& (condicion 2){
Suceso...
}


Dios, eres el amo xDDD un facepalm de corazón. Eso no funcionara en tu vida...

Algo como esto mejor:
if ((condicion 1)&& (condicion 2)){
//accion
}


Sobre lo del famoso 1 del while... simple, si solo pones un numero el compilador lo toma como una condicion positiva.

salu2
Ups!. Se me ha olvidado poner los parentesis XD. Gracias por avisar plata... Ahora actualizo...

Saludos
amchacon escribió:Ya empezamos con los problemas XD

Yo de toda la vida lo he puesto en parentesis separados y nunca me ha dado error al compilar:

if (Pad.Held.A)&& (Pad.Held.B){
PA_EasyBgLoad(0,2,"Prueba");
}


Por tanto yo lo he puesto asi...

Los operadores || y ! los conozco, pero no los he puesto porque me parecen menos importantes, para no alargar mas el tutorial y ademas meter mas conceptos de los que he puesto. Pienso que pueden crear confusion entre ellos... A lo mejor cambio luego de opinion y los añado al tutorial XD. Depende del tiempo libre y de las ganas que tenga (hasta para 5-10 lineas soy peresozo XD)....

Saludos!


Hombre... no se compilador estaras usando.. pero creo que eso no debería de funcionar (a lo mejor si.. ya que me parece una forma tan extraña de poner las condiciones que ni si quiera lo habia probado antes...), y no me digas que los otros operadores son menos importantes.. porque no hay ninguno que destaque sobre otro.. es como si tu al hablar no puedes usar "o" o "no", y solo usas "y"... te limitas mucho

yo sigo pensando que antes de creerse el rey de palib la gente deberia afianzar este tipo de conceptos que son muy necesarios..
Actualizado el tutorial con nuevas cosas...

En cuanto suikoden... Como he dicho en el mensaje anterior se me paso poner un parentesis, seria asi:

if ((Pad.Held.A)&& (Pad.Held.B)){
PA_EasyBgLoad(0,2,"Prueba");
}

Ahora si tiene sentido no? [ginyo]

Saludos

PD: el rey de palib, lol
Como te enrrollas amchacon xDDD, esta muy completo, a ver si ago animo xD
Hola, yo personalmente siempre he seguido los tutoriales de Plata porque me han parecido que estaban mas explicados y desarrollados y ademas vienen todos juntos [sonrisa] pero ahora que veo los tuyos me dan también una idea de como se las puede apañar un coder para hacer sus proyectos a y bueno también he seguido los de la wiki XD peo no se se me quedan un poco cortos, bueno yo ya he acabado de leer todos los tutoriales tanto de amchacon como de Plata y de la wiki XD pero sigo esperando mas tutoriales mientras hago practicas [toctoc] [jaja]



Bueno espero que sigais trabajando asi de bien xD. Saludooos [bye]
Enhorabuena por el tuto [oki]

Sigue así!
10 respuestas