2012-06-21 21 views
10

Pierwszy raz plakat i perl noobie.Jak zatrzymać wejście w Perlu?

Robię grę refleksyjną. Oto wynik -

__________________________________________________________________________ 
Reflex game initiated. Press ENTER to begin the game, and then press ENTER 
after the asterisks are printed to measure your reflexes!. 


************************* 

Your result: 0.285606 seconds. 
logout 

[Process completed] 
__________________________________________________________________________ 

Jest jeden mały problem choć - Nie ma 0-10 sekund (na podstawie zmiennej losowej) po naciśnięciu Enter, aby rozpocząć grę, a przed gwiazdy są drukowane. W tym czasie, jeśli gracz naciśnie klawisz ENTER, jest on rejestrowany jako czas odruchu. Potrzebuję więc sposobu, aby powstrzymać mój kod przed odczytaniem przycisku ENTER przed wydrukowaniem gwiazd. Kod -

#!/usr/bin/perl 

use Time::HiRes qw(sleep); 
use Time::HiRes qw(gettimeofday); 

#random delay variable 
$random_number = rand(); 

print "Reflex game initiated. Press ENTER to begin the game, and then press ENTER after   the asterisks are printed to measure your reflexes!.\n"; 

#begin button 
$begin = <>; 

#waits x milliseconds 
sleep(10*$random_number); 

#pre-game 
$start = [ Time::HiRes::gettimeofday() ]; 

print "\n****************************\n"; 

#user presses enter 
$stop = <>; 

#post game 
$elapsed = Time::HiRes::tv_interval($start); 

#delay time print 
print "Your result: ".$elapsed." seconds.\n"; 
+0

gwiazdki nie zostały wydrukowane na wyjściu, przepraszam za to. znajdują się dokładnie pomiędzy "twoimi odruchami" i "drukowanymi na miarę twoich odruchów". – user1472747

+0

możliwy duplikat bufora STDIN [Flushing Perl] (http://stackoverflow.com/questions/7602861/flushing-perl-stdin-buffer) – pilcrow

Odpowiedz

4

Powtarzanie od original answer przez CanSpice:

Wygląda Term::ReadKey może pomóc.

#!perl 

use strict; 
use warnings; 
use 5.010; 

use Term::ReadKey; 

say "I'm starting to sleep..."; 
ReadMode 2; 
sleep(10); 
ReadMode 3; 
my $key; 
while(defined($key = ReadKey(-1))) {} 
ReadMode 0; 
say "Enter something:"; 
chomp(my $input = <STDIN>); 
say "You entered '$input'"; 

Oto co się dzieje:

  • ReadMode 2 oznacza "umieścić tryb wprowadzania w trybie zwykłym, ale wyłączyć echo". Oznacza to, że każde uderzenie w klawiaturę, które użytkownik wykonuje podczas korzystania z kosztownego kosztowo kodu, nie zostanie wyświetlone na ekranie. To wciąż pobiera weszła w buforze STDIN jest jednak tak ...
  • ReadMode 3 okazuje STDIN w trybie cbreak, czyli STDIN niby dostaje przepłukać po każdym naciśnięciu klawisza. Właśnie dlatego ...
  • while(defined($key = ReadKey(-1))) {} dzieje się. Spowoduje to wypróżnienie znaków wprowadzonych przez użytkownika w trakcie kosztownego kosztowo kodu. Następnie ...
  • ReadMode 0 resetuje STDIN, i można odczytać z STDIN, jakby użytkownik nie uderzył w klawiaturę.

Kiedy uruchomić ten kod i huk na klawiaturze podczas sleep(10), a następnie wprowadzić jakiś inny tekst po wierszu, tylko wypisuje tekst wpisany po pojawieniu się monitu.

Ściśle mówiąc ReadMode 2 nie jest potrzebny, ale umieściłem go tam, aby ekran nie był zapełniony tekstem, gdy użytkownik wpada na klawiaturę.

+3

Niektóre wyjaśnienia byłyby miłe. – TLP

+0

Dodano wyjaśnienie. – ZnArK

+0

Ta odpowiedź (kod i objaśnienie) jest dosłownie kopiowana z "Oryginalnej odpowiedzi", z wyjątkiem cytatu wstępnego i odnośnika do edycji/linku. Być może zamiast powtarzać odpowiedzi, powinniśmy zamknąć pytanie jako dupę? – pilcrow