Joystick, tema serio

Started by Futu-block, November 26, 2018, 01:16:22 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Futu-block

Despues de dar muchas vueltas, falta de documentación y mas cositas, ya he dao con el tema de como funciona el Joystick y se las trae tela :-\

Empecemos con un código fácil o por lo menos eso creo yo:
Process Main()
begin
    Full_Screen=false;
    set_mode(320,240,32);
    graph = load_png("aa.png");
    x = 160;
    y = 120;
   
    loop
        if(joy_getaxis(0,0)> 5000)
            x++;
        end
        if(joy_getaxis(0,0)> -5000)
            x--;
        end
        if(joy_getaxis(0,1)> 5000)
            y++;
        end
        if(joy_getaxis(0,1)> -5000)
            y--;
        end
        if (x => 325) x = 160; end
        if (x =< -5) x = 160; end
        if (y => 245) y = 120; end
        if (y =< -5) y = 120; end

        if(joy_getbutton(0,0)) size = 50; end
        if(joy_getbutton(0,1)) size = 100; end
        if(joy_getbutton(0,2)) size = 150; end
        if(joy_getbutton(0,3)) size = 200; end
        if(joy_getbutton(0,4)) size = 250; end
        if(joy_getbutton(0,5)) size = 300; end
        if(joy_getbutton(0,6)) size = 350; end
        if(joy_getbutton(0,7)) size = 400; end
        if(joy_getbutton(0,8)) size = 450; end
        if(joy_getbutton(0,9)) size = 500; end

        if(key(_esc)) exit(); end
        frame;
    end
end

Suficiente para mi, pues con esto ya compruebo si me funciona lo mas importante y que es lo que quiero, los botones y los ejes...los botones ya iré viendo sobre la marcha, van todos aunque no son 10, el tema está en los ejes, expresado de esa forma me mueve el punto verde hacia arriba a la izquierda solo, y si pulso se bloquea el movimiento (quizas dandole +=2 se contrarresta, pero yo no quiero eso):


¿como he de hacerlo para que no se mueva solo?¿habría que calibrarlo?
¿como y pa que? si es un pad usb mas generico que toas las cosas
¿para que sirven el getaxis si le he puesto un valor de 5000 y se lo pasa por el forro?
¿como se puede ''desanalogizar'' y ponerlo binario, o pulsa o no pulsa? ??? ??? ??? 

JaViS

#1
> ¿como he de hacerlo para que no se mueva solo?¿habría que calibrarlo?
Le ponés un valor minimo de get axis para que no tome los valores muy chiquitos


> ¿como y pa que? si es un pad usb mas generico que toas las cosas
Cada gamepad maneja valores diferentes, por eso hace falta configurarlo


>¿para que sirven el getaxis si le he puesto un valor de 5000 y se lo pasa por el forro?
5000 es un valor medio chico. yo uso 20000


> ¿como se puede ''desanalogizar'' y ponerlo binario, o pulsa o no pulsa?
probá diferentes valores
Working on Anarkade. A couch multiplayer 2D shooter.

Futu-block

#2
osea, que le haga un
if (joy_getaxis(0,0) >10000 and joy_getaxis(0,0) < 20000)

gracias, karma++

JaViS

Pegale una ojeada a http://forum.bennugd.org/index.php/topic,4728.0.html


yo ya hice mucho del trabajo para estandarizar el input en Anarkade, quizas te sirve.
Working on Anarkade. A couch multiplayer 2D shooter.

Futu-block

Eso es lo que iba a preguntar, porque se que hay códigos para que sirva el teclado paralelo con el joystick y no lo comprendo...
Al parecer hay que hacer una función que cuando se pulse una tecla mande una señal equivalente a la pulsación del joystick o algo asi

JaViS

Quote from: Futu-block on November 26, 2018, 04:38:53 PM
Eso es lo que iba a preguntar, porque se que hay códigos para que sirva el teclado paralelo con el joystick y no lo comprendo...
Al parecer hay que hacer una función que cuando se pulse una tecla mande una señal equivalente a la pulsación del joystick o algo asi


Eso es justamente lo que resuelve la libreria. El modo de usarla es primero definir la accion, por ejemplo SHOOT, y luego asignar modos de input a esa accion, independiente de si es teclado, joystick, o un trigger por codigo. Luego, solo checkeas que la accion Shoot se haya disparado, sin importar de donde viene.

Working on Anarkade. A couch multiplayer 2D shooter.

Drumpi

¿Por qué no usas WRITE_INT para ver lo que devuelve joy_getaxis(0,0) antes de ponerte a escribir valores aleatorios? Te puedes llevar una sorpresa.

Secundo a Javis: es fundamental que tengas un proceso que transforme cualquier tipo de input (teclado, mando, ratón, pantalla táctil) a valores true/false en un array, o +/-1 o lo que te venga en gana. Así, si el día de mañana pasas de PC a Wiz, sólo tienes que cambiar ese módulo, ya que tu personaje sigue leyendo del array.

Ya te lo comenté con el Echo: tengo un array llamado Teclas de 10 posiciones, que son las constantes K_Up, K_Down... K_Jump, K_Fire, y compruebo si valen true o false (bueno, en mi caso, si valen 1 o más). Según si es PC, GP2X o Wiz, tengo un proceso llamado Control_teclas, Control_teclasGP2X y otro Control_TeclasWiz, y llamo al que necesito según el OS_ID. El primero usa la mod_joy, y el segundo y el tercero usan Key con valores diferentes según la máquina, pero el prota sólo comprueba el valor de Teclas.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Futu-block

Sí, todo eso está muy bien pero me ponéis un ejemplito que pueda estudiar yo ese código
Más que nada porque no se cuantos valores tiene cada variable y porqué
En la wiki viene las órdenes y lo explica ajín en inglés y eso pero como un código, nada
El que tengo llama a una función de una forma muy rara que no pone return ni na
Cuándo pongo que si pulso una tecla es igual que joygetbutton y no funciona...

Que me lío si no lo entiendo, y prefiero entenderlo, tu sabe

warrior_rockk

A lo que se refieren es que independices la comprobación de controles de si es teclado o joystick.
Ejemplo simple para usar indistintamente teclado y/o joystick:


-Te creas un array de controles de tamaño fijo de los controles que quieras chequear (arriba, abajo, izquierda, derecha por ejemplo): bool controles[4];
-Te creas unas constantes para referirte a las posiciones del array mas fácilmente: define ctrArriba 0   define ctrAbajo 1  define ctrIzquierda  etc...
-Creas una función que se ejecute cíclicamente que compruebe el control tanto de joystick como de teclado:





#define ctrArriba       0     
#define ctrAbajo       1 
#define ctrIzquierda    2
#define ctrDerecha       3


bool controles[4];


function checkControls()
begin
   
   controles[ctrArriba]    = (key(_up)    || joy_getaxis(0,1) == -32768    || joy_gethat(0,0) == 1);
   controles[ctrAbajo]     = (key(_down)    || joy_getaxis(0,1) == 32767    || joy_gethat(0,0) == 4);
   controles[ctrIzquierda] = (key(_left)    || joy_getaxis(0,0) == -32768    || joy_gethat(0,0) ==8);
   controles[ctrDerecha]     = (key(_right)    || joy_getaxis(0,0) == 32767    || joy_gethat(0,0) == 2);

end;



Luego, en tu juego, comprobarás el array de controles en vez de las interfaces físicas.

Futu-block

vale, el array sin problemas, las constantes tambien, la función es la que no la entiendo mucho...
no tiene return, no devuelve nada, ¿cuando se invoca? o se ejecuta una vez y trabaja a full, no hay if, no lo entiendo...
perate que lo analizo:

controles[ctrArriba] = (key(_up) vendrá a decir que cada vez que cada vez que pulse la tecla arriba el array controles[0] vale... no se, ¿true?, 1, aqui me pierdo, luego no se pa que vale el || pero me supongo que significará algo como ''o tambien''...
lo que si veo una equivalencia o correspondencia en el array, pero ¿como uso ese array?
me supongo que con algo como  '' if (controles[ctrArriba]) y--; end

lo siento, pero soy muy torpe y me gusta entender las cosas

Pd: gracias por la ayuda

Drumpi

Bueno, tal como él lo ha escrito, debes llamar a la función a cada frame, antes de hacer nada.
Sí, el || es un OR lógico, por lo que controles[ctrArriba] vale true si se pulsa key(_up), el axis 1 del joy 0 vale -32786, o si el hat 0 del joy 0 vale 1, cualquiera de las tres.

Personalmente yo crearía un process, con un loop infinito y su frame dentro, y le daría la máxima prioridad para que se ejecute antes que cualquier otro proceso. Y usaría constantes, que me gustan más, algo así (te lo escribo sin comprobar):

const
    tecla_arriba = 0;
    tecla_abajo = 1;
    tecla_izquierda = 2;
    tecla_derecha = 3;
    tecla_salto = 4;
    tecla_last = 5; //esto no es una tecla, es el máximo de posiciones del siguiente array, por si luego quieres añadir más botones

    byte teclas[teclas_last];

process comprueba_teclas_keyboard ()
begin
    priority = 10000;
    loop
        if (key(_up)) teclas[tecla_arriba] = true; else teclas[tecla_arriba] = false; end
        if (key(_down)) teclas[tecla_abajo] = true; else teclas[tecla_abajo] = false; end
        if (key(_left)) teclas[tecla_izquierda] = true; else teclas[tecla_izquierda] = false; end
        if (key(_right)) teclas[tecla_derecha] = true; else teclas[tecla_derecha] = false; end
        if (key(_space)) teclas[tecla_salto] = true; else teclas[tecla_salto] = false; end
        frame;
    end
end


Lo llamas al principio, junto al set_mode, y ya te olvidas por el resto del programa... mientras no hagas un LET_ME_ALONE. Nunca hagas un LET_ME_ALONE.
Incluso, puedes crear otro que sea "comprueba_teclas_joy_analógico" y en lugar de usar key(_loquesea) usas joyaxis.

Luego, en tu prota, puedes poner una línea tal que:

if (teclas[tecla_derecha]) x++; end

Para que ande a la derecha, y listo.

¿Quieres más versatilidad? puedes hacer que la posición del array 10 compruebe si se ha pulsado enter. Si creas las constantes:
teclas_pausa = 10;
  teclas_aceptar = 10;


Sí, con el mismo número. Así, durante el juego puedes comprobar
if (teclas[tecla_pausa])
Y en el menú
if (teclas[tecla_aceptar])
Y en ambos casos comprueban si se ha pulsado la misma tecla, pero en el código tienen nombres diferentes que te dicen para qué sirven en ese momento... o si se cambia la tecla, por lo que sea (por ejemplo, queremos que aceptar sea el espacio) sólo tienes que cambiar el valor de la constante (hacer que teclas_aceptar valga 5 en lugar de 10) y no se cambia el botón de pausa en el juego.

Obviamente, en mis códigos esto va tres pasos más alla, porque incluyo el valor de KEY en el array teclas, y el botón del mando. Y ya sabemos que GP2X, WIZ y los PC no tratan las diagonales de los mandos de la misma manera.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Futu-block

vale, creo que lo voy entendiendo ya, a mi gusto siempre es mejor un proceso que recule y reconduzca las teclas/botones del joystick/pad a mi antojo

No entiendo lo de priority pero será alguna variable de bennu que todavía no he llegado a ver, al parecer cuanto mas alto el número mas prioridad, creo yo

Muy bien lo de pausa y aceptar con las misma tecla para que tenga varias funciones, eso me dá ideas suculentas, jijiji

panreyes

Yo he venido aquí a hablar de mi libro:
https://bitbucket.org/panreyes/pixtudiopm/src/3234224ff2d336099bc254f6f1ff800008c266bf/projects/common-src/controles.pr-?at=master&fileviewer=file-view-default

"controles.pr-" permite lo siguiente:
- Leer teclado y gamepads como si fueran lo mismo.
- mod_gamecontroller: mejor gestión de gamepads incluida en SDL2 (requiere PixTudio o backportear el módulo mod_gamecontroller).
- Gamepad táctil para móviles: desde un FPG o generado automáticamente.
- Conexión, desconexión y reconexión de gamepads ingame.
- Un meta gamepad "cero" que corresponde a todos los gamepads que haya.
- Posibilidad de saber cuántos botones está pulsando cada jugador

Qué no incluye:
- Eventos (dejado de pulsar, recién pulsado, pulsando, etc...)
- Documentación decente
- Código ligeramente decente
- Separación del resto del framework de PiXJuegos de forma decente
- Vergüenza de haber publicado semejante burrada de código xD

Aunque sea código feo, es muy funcional. Es lo que uso en eXplosive Dinosaurs y me va genial.

Futu-block

me parece genial, no dudes de robarme cualquiera de mis juegos y lo exportes a lo que tu quieras

y tranquilo que no te voy a pedir pasta hasta que no ganes mas de un millon, ja ja ja