e-mail    Debatní kniha    Mapa stránek    Hlavní  
 perličky 
 

Simulátor pohybu myši

RNDr. Dominik Filipp

Pri tvorbe demonštračných programov je niekedy vežmi efektné používať simuláciu pohybu myši. Ide o to, že kurzor myši sa na obrazovke pohybuje a vykonáva činnosť tak, akoby myš bola vedená neviditežnou rukou užívateža. Pritom je dôležité, aby celá činnosť vyzerala úplne realisticky. V tomto článku uvádzam pôvodný program, ako simulovať realistický pohyb myši. Program pracuje tak, že užívatež najprv ovládanie myši nahráva a potom ho spätne vyvoláva už bez používania myši.

Základnou myšlienkou je to, že pri nahrávaní pohybu myši program v krátkych časových intervaloch vzorkuje stav myši a tento zapisuje do súboru. Pri prehrávaní naopak číta stav myši zo súboru v tých istých časových intervaloch, a tak simuluje pohyb myši. Pod stavom myši rozumieme polohu myši (x-ová a y-ová súradnica polohy kurzora) a stav tlačítok. Činnosť myši sa prejavuje jednak pohybom kurzora a jednak výpisom "Stlačené tlačítko!" pri stlačení ktoréhokožvek tlačítka myši.

Celá činnosť je znázornená v hlavnej procedúre main_proc(). V nekonečnom cykle sa v určených časových intervaloch SAMPLE_INTERVAL zapisuje (číta) (podža zvoleného parametra) do (zo) súboru SAMPLE.SCR globálna premenná SAMPLE, v ktorej je definovaný stav myši (premenná SAMPLE je štruktúra SAMPLETYPE uvedená na začiatku programu). Jadrom procedúry main_proc() je funkcia mouse_sampler(). Pri nahrávaní pohybu myši sa stav myši sníma procedúrou mouse_status() a zapisuje do súboru pomocou procedúry record(). Naopak pri prehrávaní-simulácii pohybu, sa stav myši číta zo súboru do premennej SAMPLE prostredníctvom procedúry play() a samotný pohyb myši realizuje procedúrou cursor_move(). Pri stlačení tlačítka sa vypisuje kontrolný výpis, ktorý je uvedený v main_proc().

Otázkou je, aký malý má byť vzorkovací interval, aby simulovaný pohyb kurzora nebol "trhaný". V programe je nastavený interval 0,01 s, čo zaručí plynulý pohyb kurzora. Taktiež zaujímavou otázkou je, ako je to s vežkosťou súboru SAMPLE.SCR, ktorý sa tvorí pri nahrávaní pohybu myši. Výsledok je prekvapujúci; ani pri dlhšom nahrávaní nepresiahne vežkosť záznamového súboru desiatky kilobajtov.

Aj keď podstatou programu sú procedúry main_proc() a mouse_sampler(), uvádzam celý program, na ktorom sa simulácia pohybu myši dá vežmi efektne demonštrovať. Program je vytvorený v borlandskom C a pracuje v grafickom móde. Preto je nutné, aby v aktuálnom adresári bol ovládač EGAVGA.BGI (resp. HERC.BGI).

V tomto odseku v krátkosti vysvetlím ovládanie programu. Najprv sa bude nahrávať pohyb myši. Program spustíme:

>sampler 1 (nahrávanie pohybu myši)

Na monitore sa objaví kurzor. Myšou pohybujeme po celej ploche, resp. stláčame tlačítka myši (pri každom stlačení sa vypíše kontrolný výpis). Ak chceme nahrávanie ukončiť, stlačíme žubovolný kláves na klávesnici.

Pre vyvolanie simulácie práve nahratého pohybu napíšeme:
>sampler 0 (simulácia pohybu myši)

a celý pohyb myši sa zopakuje tak isto, ako bol nahratý v predchádzjúcom prípade. Stlačením žubovolného klávesu sa program ukončí.

Program môže byť implementovaný do vlastných demonštračných programov, ktoré "ožijú" a budú vežmi efektne ovládané rovnako, ako by ich ovládal užívatež. Výhodou tohto prístupu je to, že celá činnosť demonštrácie sa nahráva obvyklým spôsobom pomocou myši a po spustení prehrávania sa táto činnosť zopakuje automaticky. Pri experimentovaní vám prajem príjemnú zábavu.

// Program "SAMPLER.C" na simuláciu pohybu myši // (small model) #include <bios.h> #include <dos.h> #include <stdio.h> #include <stdlib.h> #include <graphics.h> #define SAMPLE_INTERVAL 0.01 // vzork.interval v sek. #define BUFFER_SIZE 4096 #define M_INT 0x33 #define SCRIPT_FILE "SAMPLE.SCR" // záznam.súbor #define PLAY 0 #define RECORD 1 #define CONTINUE 0x00 struct SAMPLETYPE { int xpos, ypos, Button; } SAMPLE; // premenná // na uschovanie stavu myši char Buffer[BUFFER_SIZE], FileAccess[2][4]={"rb", "wb"}; int x, y, Button, LEN; float ElapsedTime, startTime, currentTime, statTime; FILE *F; // aktuálny čas s presnosťou na stotinu sekundy void get_seconds(float *timeLength) { struct time timep; gettime(&timep); *timeLength = ((float) (timep.ti_hund))/100.0; *timeLength += (float)(timep.ti_hour)*3600.0+(float)(timep.ti_min) *60.0+(float)(timep.ti_sec); } // inicializácia časového vzorkovača void init_timer(void) { get_seconds(&startTime); statTime=currentTime=startTime; } // otvorenie súboru a nastavenie bufferovacieho režimu void open_file(char mode) { F=fopen(SCRIPT_FILE, FileAccess[mode]); setvbuf(F, Buffer, _IOFBF, BUFFER_SIZE); } // inicializácia myši void reset_mouse(void) { _AX=0x00; geninterrupt(M_INT); } // zapnutie kurzora myši void mouse_on(void) { _AX=0x01; geninterrupt(M_INT); } // vypnutie kurzora myši void mouse_off(void) { _AX=0x02; geninterrupt(M_INT); } // načítanie stavu myši void mouse_status(int *xpos, int *ypos, int *Button) { int tmp; _AX=0x03; _BX=0x00; geninterrupt(M_INT); tmp=_BX; *xpos=_CX; *ypos=_DX; *Button=tmp & 0x03; } // umiestnenie kurzora myši na dané súradnice void cursor_move(int xpos, int ypos) { _AX=0x04; _CX=xpos; _DX=ypos; geninterrupt(M_INT); } // inicializácia grafického systému // v adresári musí byť ovladač BGI! void init(void) { int graphDriver, graphMode; detectgraph(&graphDriver, &graphMode); initgraph(&graphDriver, &graphMode, ""); } // zápis stavu myši do záznamového súboru SAMPLE.SCR void record(int xpos, int ypos, int Button) { SAMPLE.xpos=xpos; SAMPLE.ypos=ypos; SAMPLE.Button=Button; fwrite(&SAMPLE, LEN, 1, F); } // načítanie stavu myši zo záznamového súboru SAMPLE.SCR void play(int *xpos, int *ypos, int *Button) { fread(&SAMPLE, LEN, 1, F); *xpos=SAMPLE.xpos; *ypos=SAMPLE.ypos; *Button=SAMPLE.Button; } // vykonanie akcie podla stavu myši void mouse_sampler(char mode, int *xpos, int *ypos, int *Button) { get_seconds(&currentTime); if (currentTime-statTime < SAMPLE_INTERVAL) return; statTime=currentTime; if (mode == RECORD) { mouse_status(xpos, ypos, Button); record(*xpos, *ypos, *Button); } else if (mode == PLAY) { play(xpos, ypos, Button); cursor_move(*xpos, *ypos); }; } // základná procedúra void main_proc(char mode) { int key; reset_mouse(); mouse_on(); LEN=sizeof(struct SAMPLETYPE); open_file(mode); init_timer(); do { key=bioskey(1); mouse_sampler(mode, &x, &y, &Button); if (Button) { mouse_off(); moveto(x, y); outtext("Stlacene tlacitko !"); mouse_on(); }; } while(key == CONTINUE); bioskey(0); fclose(F); } void main(int argc, char *argv[]) { char mode; if (argc < 2) { printf("*** SIMULATOR POHYBU MYSI ***\n"); printf("Zadaj parameter ZAZNAM=1, PREHRAVANIE=0"); return; }; mode=(char)atoi(argv[1]); if (mode != RECORD && mode != PLAY) {printf("Nespravny parameter !"); return;}; init(); main_proc(mode); closegraph(); }


Pascal - hlavní
Překladače
Vlastní články
Převzaté články
Věci na stáhnutí
Odkazy k tématu
BP7 buglist
Chyba Run-time 200

BASIC