Aufruf einer Skriptfunktion an eine Taste binden

MacX

Light Guard
Hi,

Code:
void waitForKey()
{
	sys.threadname( "waitForKey" );

	float userBtn, pressedBtn;

	while( 1 ) {

		userBtn = $player1.getButtons();
		pressedBtn = 1 & userBtn; // Attack-Button
		
		if( pressedBtn ) {
			teleport();
			sys.wait( 1 );
		}

		sys.wait( 0.01 );
	}
}

void main()
{
	thread waitForKey();
}

Wie man sieht, starte ich einen Thread und warte, dass der Benutzer attackiert ( bei mir Strg oder LMT ), um die Teleport-Funktion aufzurufen.

Kennt hier jemand eine elegantere Methode einen Funktionsaufruf an eine Taste zu binden?
Bei oben genannter Lösung wird die Teleport-Funktion immer wieder aufgerufen, wenn man die Taste gedrückt hält.

Der Inhalt der Teleport-Funktion soll hier keine Rolle spielen. Der Attack-Button ist nur ein Beispiel.
 

CruSAdeR

Maledict
Du kannst mit noch ner Variable dafür sorgen, dass er nur einmal in die Funktion geht.

ungefähr so:

Code:
void waitForKey()
{
	sys.threadname( "waitForKey" );

	float userBtn, pressedBtn;

	while( 1 ) {

		userBtn = $player1.getButtons();
		pressedBtn = 1 & userBtn; // Attack-Button
	        float pressed = 0;
		
		if( pressedBtn && !pressed) {
	                pressed = 1;
			teleport();
			sys.wait( 1 );
		}
	        else {
	                pressed = 0;
	        }

		sys.wait( 0.01 );
	}
}

void main()
{
	thread waitForKey();
}

Btw. warum nimmst du n float für ne boolsche Operation?
 

MacX

Light Guard
Danke für deine Antwort.
Warum pressedBtn vom Typ float ist? Mir gefiel es so besser, da die Funktion "getButton()" einen float zurück gibt. Natürlich kann pressedBtn auch vom Typ boolean sein, das ändert ja nichts am Resultat. Ansonsten funktioniert dein Vorschlag mit der extra Variable "pressed" nicht, mal abgesehen davon, dass die Variable außerhalb der Schleife definiert werden müsste und auch vom Typ boolean sein kann. Warum es nicht geht kann ich nicht sagen.

-------------------------------------------------------------
Die Buttons sind im Code wie folgt definiert:
Code:
// usercmd_t->button bits
const int BUTTON_ATTACK			= BIT(0);
const int BUTTON_RUN			= BIT(1);
const int BUTTON_ZOOM			= BIT(2);
const int BUTTON_SCORES			= BIT(3);
const int BUTTON_MLOOK			= BIT(4);
const int BUTTON_5			= BIT(5);
const int BUTTON_6			= BIT(6);
const int BUTTON_7			= BIT(7);

Das BIT( x ) Makro sieht so aus:
Code:
#define BIT( num )				( 1 << ( num ) )

Im ersten Post sieht man, wie ich auf die Taste BUTTON_ATTACK geprüft habe.
Will man beispielsweise die Taste "b" als Auslöser haben, so muss man in der DoomConfig.cfg folgendes angeben:
Code:
bind "b" "_button5"

und im Skript
Code:
userBtn = $player1.getButtons();
pressedBtn = 32 & userBtn;

War nur eine kleine Zusammenfassung.
-------------------------------------------------------------
Die Frage im ersten Post ist immer noch aktuell. Wie gesagt, Probleme habe ich ja nicht. Ich hätte nur gerne eine schönere Lösung, falls überhaupt eine existiert.
 
Last edited:

CruSAdeR

Maledict
Öh ja. Die Initialisierung von pressed sollte natürlich außerhalb der Schleife stattfinden. ^^
Aber dann sollte es doch so gehen?
Mit schöner meinst du, dass teleport() nur ein mal pro Tastendruck ausgeführt wird, oder?
 

MacX

Light Guard
Nein, die Variable pressed hat keine Auswirkungen auf den Ablauf. Ich verstehe es ja auch nicht.
Und mit schöner meinte ich kürzer und einfacher. Ein Einzeiler wäre nett.
Habe da gerade noch eine Idee. Wenn es klappt, geb ich bescheid.
 

CruSAdeR

Maledict
Ach das war auch total dämlich. Hätte wohl doch ein bissel mehr drüber nachdenken sollen.

Code:
void waitForKey()
{
    sys.threadname( "waitForKey" );

    float userBtn, pressedBtn;
        float pressed = 0;

    while( 1 ) {

        userBtn = $player1.getButtons();
        pressedBtn = 1 & userBtn; // Attack-Button

        if( pressedBtn && !pressed) {
            pressed = 1;
            teleport();
            sys.wait( 1 );
        }
        else if (!pressedBtn) {
            pressed = 0;
        }

        sys.wait( 0.01 );
    }
}

void main()
{
    thread waitForKey();
}
So, jetzt aber. :) Grade schön finde ich das auch nicht. Aber naja.
 

MacX

Light Guard
Danke dir. Jetzt wird die teleport-Funktion nur einmal aufgerufen, wenn man die Taste gedrückt hält. Der else-Zweig war wohl das Problem. :)
Zur Verkürzung bzw. Entfernung der Funktion "waitForKey" hatte ich noch die Idee meine Taste an den Konsolenbefehl "script" zu binden.
Ich habe es wie folgt getestet:
Code:
bind "b" "script teleport"
Das funktioniert schon mal nicht. Ich würde noch versuchen die Skriptdatei in den scripts-Ordner zu packen und einen namespace drumherum bauen.
Ansonsten lasse ich es so wie es ist.

Danke nochmal!
 

MacX

Light Guard
Ich bin jetzt mal so dreist und wage den Doppelpost.

Wenn man in der DoomConfig.cfg oder einer benutzerdefinierten Konfigurationsdatei folgendes einbaut:
Code:
bind "b" "script teleport()"
So funktioniert der Aufruf der teleport-Funktion beim Tastendruck. Die Klammern fehlten nur. Der ganze Thread von oben würde wegfallen, aber die Funktion wird immer und immer wieder aufgerufen, wenn man die Taste gedrückt hält.

Es ist zwar mein gewünschter Einzeiler, aber der permanente Aufruf beim bleibenden Tastendruck ist in dieser Situation unschön.
Also bleibe ich bei der Lösung mit dem waitForKey-Thread.

Edit: http://www.doom3world.org/phpbb2/viewtopic.php?f=4&t=23133

Das Thema hat sich somit erstmal erledigt.
 
Last edited:
Top