Mejorar KEY

Started by panreyes, June 29, 2010, 11:07:48 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

panreyes

Actualmente sólo podemos saber si está siendo pulsada o no.
Me gustaría mejorarla al más puro estilo de eventos javascript o actionscript con algo tipo onDown, onUp, y onPress que es lo que hay actualmente.

Parecerá una chorrada, pero nos evitaríamos cientos de esto:
if(key(_enter))
  while(key(_enter)) frame; end
  loquesea();
end


Sería ideal tener esto:
if(key(_enter,down))
  loquesea();
end


¿Sería difícil de implementar? ¿Hay alguna razón por la que no se deba hacer así? :)

Drumpi

Hombre, por lo que a mi respecta, ya tengo elegido un método muy efectivo para hacer eso (lo que ya todos sabemos de tener una variable que vale 0 si no está pulsada, y aumentar su valor en 1 unidad a cada frame si lo está), y me ha salvado de más de un apuro a la hora de redefinir teclas, joysticks y demás.

Pero no es mala sugerencia para los novatos. Habría que comprobar su viabilidad.
Lo mismo se puede montar un módulo aparte.
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)

SplinterGU

las teclas solo dan pulsado cuando se tiene el evento down... y se liberan en el evento up.

podes armar una funcion para hacer eso muy simple, en codigo .prg.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

Tengo por ahí un .prg que se ocupa de eso, pero su funcionamiento no me gustaba demasiado, sólo servía para procesos que deban bloquearse totalmente en espera de que se presione/libere una tecla.

Yo la verdad es que también pienso que deberían venir en mod_key esas funciones. Sería mucho más cómodo hacerlo con una llamada a función y no tener que armar el .prg cada vez y usar una función con todas sus locales para detectar el just_pressed y el just_released

Splinter, con eso que dices de armar la función, ¿Te refieres a algo así?

FUNCTION int key_released ( int key_code )
BEGIN
   IF ( NOT key ( key_code ) )
      RETURN FALSE;
   END
   LOOP
      IF ( NOT key ( key_code ) )
         RETURN TRUE;
      END
      FRAME;
   END
END


Eso no lo veo bien, porque la función tiene FRAME y bloquearía al proceso que la invoca, ¿Cómo propondrías el código para detectar si una tecla ha sido liberada usando FUNCTION y sin bloquear al proceso que la invoca? ???
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

FreeYourMind

Efectivamente Windgate, usar el frame; como bloquea el proceso que lo invoca no es una solución buena ....

Tambien estoy de acuerdo que deberia venir nativo este proceso de bloqueo.

Y por cierto ya lo he hecho de tantas formas que ya ni se poner ejemplos :)

JMP

#5
Tengo hecha una funcion que podria sevir,

const
    _PRESS = 0;
    _RELEASED = 1;
end
global
byte released_c=0;
byte press_c=0;
end
FUNCTION int keys ( int key_c ,int mode )

BEGIN
SWITCH ( MODE )
CASE _RELEASED:
IF ( key ( key_c ) )
released_c = 1;
RETURN FALSE;
END
IF ( !KEY ( key_c ) && released_c == 1 )
released_c = 0;
RETURN TRUE;
END
END
CASE _PRESS:
IF ( KEY ( key_c ) && press_c !=1 )
press_c = 1;
RETURN TRUE;
END
IF ( !KEY ( key_c ) && press_c == 1 )
press_c = 0;
RETURN FALSE;
END
END
END
END


y para utilizarlo por ejemplo con el released
IF ( keys ( _up , _released )==TRUE )
say ( "!");
end

SplinterGU

#6
Quote from: Windgate on June 30, 2010, 09:16:01 AM
Tengo por ahí un .prg que se ocupa de eso, pero su funcionamiento no me gustaba demasiado, sólo servía para procesos que deban bloquearse totalmente en espera de que se presione/libere una tecla.

Yo la verdad es que también pienso que deberían venir en mod_key esas funciones. Sería mucho más cómodo hacerlo con una llamada a función y no tener que armar el .prg cada vez y usar una función con todas sus locales para detectar el just_pressed y el just_released

Splinter, con eso que dices de armar la función, ¿Te refieres a algo así?

FUNCTION int key_released ( int key_code )
BEGIN
   IF ( NOT key ( key_code ) )
      RETURN FALSE;
   END
   LOOP
      IF ( NOT key ( key_code ) )
         RETURN TRUE;
      END
      FRAME;
   END
END


Eso no lo veo bien, porque la función tiene FRAME y bloquearía al proceso que la invoca, ¿Cómo propondrías el código para detectar si una tecla ha sido liberada usando FUNCTION y sin bloquear al proceso que la invoca? ???

no, asi no...

pongo el pseudocodigo, no tengo mucho tiempo.



import "mod_key";
import "mod_video";
import "mod_text";
import "mod_proc";

global
    _key_use = 0;
    _key_state[127][1];
end

#define _key_pressed    0
#define _key_down       1
#define _key_up         2

process _key_get_states()
private
    i;
begin
    priority = 1000;
    loop
        _key_use ^= 1;
        for ( i = 0; i < 127; i++ )
            _key_state[ i ][ _key_use ] = key( i );
        end
        frame;
    end
end

function int _key(int k, int ev)
begin

    if ( !exists( type _key_get_states ) ) _key_get_states(); end

    switch( ev )
        case _key_down:
            return ( _key_state[ k ][ _key_use ] && !_key_state[ k ][ _key_use ^ 1 ] );
        end

        case _key_up:
            return ( !_key_state[ k ][ _key_use ] && _key_state[ k ][ _key_use ^ 1 ] );
        end
    end

    return ( _key_state[ k ][ _key_use ] );
end

private
a,b,c;
begin

    write_int(0,0,0,0,&a);
    write_int(0,0,10,0,&b);
    write_int(0,0,20,0,&c);

    while( !_key( _ESC, _key_pressed ) )

        a = _key( _SPACE, _key_down );
        b = _key( _SPACE, _key_up );
        c = _key( _SPACE, _key_pressed );

        frame;
    end

    let_me_alone();

end


demasiado tonto el codigo.

amigo wind, no necesitas escribir contantemente el codigo, solo lo pones en un .inc o un .h y lo incluyes, si lo necesitas en tu proyecto.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

edite el codigo, para acortarlo un poquito, quite unos if else y los reemplace por un return directo
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

#8
es importante el let_me_alone(); otra opcion al codigo, que podria ser un poquito mas eficiente y no necesite el let_me_alone.


import "mod_key";
import "mod_video";
import "mod_text";
import "mod_proc";

global
    _key_use = 0;
    _key_state[127][1];
end

#define _key_pressed    0
#define _key_down       1
#define _key_up         2

process _key_init()
private
    i;
    pid;
begin
    if ( ( pid = exists( type _key_init ) ) && pid.id != id ) return; end

    priority = 1000;

    loop
        _key_use ^= 1;
        for ( i = 0; i < 127; i++ )
            _key_state[ i ][ _key_use ] = key( i );
        end
        frame;
    end
end

function _key_exit()
begin
    signal( type _key_init, s_kill );
end

function int _key(int k, int ev)
begin
    switch( ev )
        case _key_down:
            return ( _key_state[ k ][ _key_use ] && !_key_state[ k ][ _key_use ^ 1 ] );
        end

        case _key_up:
            return ( !_key_state[ k ][ _key_use ] && _key_state[ k ][ _key_use ^ 1 ] );
        end
    end

    return ( _key_state[ k ][ _key_use ] );
end

private
a,b,c;
begin

    _key_init();

    write_int(0,0,0,0,&a);
    write_int(0,0,10,0,&b);
    write_int(0,0,20,0,&c);

    while( !_key( _ESC, _key_pressed ) )

        a = _key( _SPACE, _key_down );
        b = _key( _SPACE, _key_up );
        c = _key( _SPACE, _key_pressed );

        frame;
    end

    _key_exit();

end


debo decir que a diferencia de todos los codigos que pusieron, esto no frena ningun proceso, mantiene estados independientes y constantes para todas las teclas, y es generico.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

Aún no termino de entender el código, estoy en ello :P pero funciona tan perfectamente que me lo quedo para mí para siempre y te doy un Karma Splinter, por ser tan groso ;D
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

Quote from: Windgate on June 30, 2010, 08:43:34 PM
Aún no termino de entender el código, estoy en ello :P pero funciona tan perfectamente que me lo quedo para mí para siempre y te doy un Karma Splinter, por ser tan groso ;D

:)

gracias
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

Parece que ultimamente estais resolviendo cosas que iba a implementar en mi actual juego, en este caso voy a probar vuestras funciones en lugar de buscar la forma como lo tenia en los juegos antiguos :)

Por cierto, aprovecho para hacer una pregunta:

Cuando arrastramos la ventana de nuestrio juego Bennu en modo ventana, el juego (objetos, musica, etc) se congela.
No habria forma, ni que fuera por configuración inicial, de que todo el timing del juego siguiera su desarrollo normal (aunque no se pintará nada) mientras la pantalla es arrastrada/movida de lugar ?

Cuando se minimiza la ventana creo que el juego sigue su desarrollo normal, púes seria tener el mismo comportamiento.

SplinterGU

creo que no hay control sobre eso del movimiento de la ventana.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

No duermes ? A nivel de SDL no habrá nada al respeto ?

SplinterGU

no, a nivel sdl no vi nada.

bue, mira quien habla... que haces a esta hora despierto? (o sera que ahi es de dia?) la verdad es que me deprime dormir... pero en un rato tengo que hacerlo.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2