Allegro - Myš a klávesnice (5. díl) - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kde se koná výstava fotografií Luďka Vojtěchovského?

V dnešní soutěži hrajeme o:



C/C++

Allegro - Myš a klávesnice (5. díl)

18. ledna 2002, 00.00 | To by nebyla ta pravá hra kdyby se nemohla ovládat, že? A proto se v dnešním díle seznámíme s ovládáním klávesnice a myši v herní knihovně Allegro. Nakonec bude jako vždy příklad.


Opět Vás vítám u seriálu o Allegru. Již brzy budeme schopni vytvořit nějakou tu hru, která už bude hratelná, ale každá hra se nějak ovládá. Většinou pomocí klávesnice a myši. My jsme se prozatím seznamovali s grafikou a grafickým výstupem v Allegru. Dneska si ale konečně ukážeme jaké možnosti nám allegro nabízí na vstupní zařízení jako jsou myš a klávesnice.

Poznámka k nové verzi Allegra: Na konci programu už nemusíme psát funkci allegro_exit(); a za konečnou závorkou funkce main() zapíšeme makro END_OF_MAIN();

Tedy malá ukázka:
int main()
{
  // nejaky kod

  return 0;
}
END_OF_MAIN();

Od teď budeme psát programy tímto stylem. Samozřejmě, aby byl program funkční museli bychom přiincludovat soubor allegro.h.

Klávesnice


Když chceme začít používat v Allegru klávesnici či jiná vstupní zařízení musíme to Allegru nějak říct. K tomu slouží funkce:

int install_keyboard();

Ta nám zařídí inicializaci klávesnice a několika proměnných. ( Po této inicializaci už bychom neměli používat standardní funkce jazyka C pro obsluhu klávesnice. Chovají se občas divně. ) Jelikož je řeč o klávesnici tak se budu věnovat pouze klávesnici ( pak zjistíte, že si jsou s myší podobné ). Tedy tato funkce nám inicializuje proměnnou key, což je jednorozměrné pole charů o 128 prvcích.

Hodnota jednotlivých prvků je 0, pokud není zmáčknuta příslušná klávesa a -1 pokud je klávesa zmáčknuta.

Jak poznáme která klávesa je a která není zmáčknuta?
No je to jednoduché. Allegro nám dává k dispozici přes sto definic. Pro každou klávesu minimálně jednu.

Definice na rozdíl o proměnných jsou psána velkými písmeny např.: KEY_ENTER. Tedy stylem: nejdříve slovíčko KEY pak podtržítko a pak příslušný název klávesy na klávesnici.

V manuálu k Allegru jsou k dispozici tyto možnosti:

      KEY_A ... KEY_Z,
      KEY_0 ... KEY_9,
      KEY_0_PAD ... KEY_9_PAD,
      KEY_F1 ... KEY_F12,

      KEY_ESC, KEY_TILDE, KEY_MINUS, KEY_EQUALS,
      KEY_BACKSPACE, KEY_TAB, KEY_OPENBRACE, KEY_CLOSEBRACE,
      KEY_ENTER, KEY_COLON, KEY_QUOTE, KEY_BACKSLASH,
      KEY_BACKSLASH2, KEY_COMMA, KEY_STOP, KEY_SLASH,
      KEY_SPACE,

      KEY_INSERT, KEY_DEL, KEY_HOME, KEY_END, KEY_PGUP,
      KEY_PGDN, KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN,

      KEY_SLASH_PAD, KEY_ASTERISK, KEY_MINUS_PAD,
      KEY_PLUS_PAD, KEY_DEL_PAD, KEY_ENTER_PAD,

      KEY_PRTSCR, KEY_PAUSE,

      KEY_ABNT_C1, KEY_YEN, KEY_KANA, KEY_CONVERT, KEY_NOCONVERT,
      KEY_AT, KEY_CIRCUMFLEX, KEY_COLON2, KEY_KANJI,

      KEY_LSHIFT, KEY_RSHIFT,
      KEY_LCONTROL, KEY_RCONTROL,
      KEY_ALT, KEY_ALTGR,
      KEY_LWIN, KEY_RWIN, KEY_MENU,
      KEY_SCRLOCK, KEY_NUMLOCK, KEY_CAPSLOCK

A jak se to používá?
Naprosto jednoduše. Jméno definice použijeme jako index v poli charů key.

Tedy například:
if (key[KEY_SPACE])
  printf("Je stisknuta klávesa SPACE - Mezerník");
else 
  printf("Není stisknuta klávesa SPACE - Mezerník");

A tak to podobně funguje i s dalšími klávesami. Jako index stačí dosadit jednu z výše uvedených definic a tak si s přehledem "odchytit" stavy kláves.
Více si ukážeme na příkladu na konci této kapitoly.

Myš

Se v poslední době stává čím dál tím více standardem v herním průmyslu. Pomalu už nevyjde nová hra, která by nepodporovala ovládání (alespoň z části) pomocí myši. My se proto taky seznámíme s tímto (dalo by se říci dnešním standardem IBM PC) zařízením více. Nebo spíše s jeho odchytáváním událostí ( klikáním, pohybem atd ).

Tak jako u klávesnice existuje funkce pro zapnutí tak samozřejmě tomu je tak i u myši. Slouží k tomu funkce:

int install_mouse();

Pokud proběhne vše v pořádku vrací funkce číslo různé od -1 a při chybě teda vrací -1.
(Pokud chceme myš vypnou slouží k tomu funkce void remove_mouse(); )

Tato funkce nám inicializuje několik proměnných. Jako první bych uvedl tyto:

extern volatile int mouse_x;
extern volatile int mouse_y;
extern volatile int mouse_z;
extern volatile int mouse_b;
extern volatile int mouse_pos;

První dvě proměnné jsou jasné. Jsou to X-ová a Y-ová souřadnice myši. mouse_pos uchovvá taky souřadnice a to tak, že v horním slově (wordu) souřadnici X a v dolním slově (wordu) souřadnici Y ( upozorňuji na to, že velikost sizeof(int) jsou 4 byty ).

mouse_z nám udává polohu scrolovacího kolečka na myši. Mě se to ale bohužel nepovedlo rozchodit.

A jako poslední nejzajímavější je proměnná mouse_b, která nám v sobě uchovává stavy tlačítek. Pokud je 0. bit nastaven na jedna je stisknuté levé tlačítko, pokud je 1. bit nastaven na jedna je stisknuté pravé tlačítko a pokud je 2. bit nastaven na jedna je stisknuté prostřední tlačítko.
Pro zjištění je asi nejjednodušší použít logický bitový součin.

Např.:
if (mouse_b & 1)
  printf("Je stisknute leve stacitko");

if (mouse_b & 2)
  printf("Je stisknute prave stacitko");

if (mouse_b & 4)
  printf("Je stisknute prostredni stacitko");

Tyto informace jsou pro nás bohatě dostačující co se týče pozice a události tlačítek, ale teď k tomu co je ještě potřeba zavolat, aby se nám kurzor objevil na obrazovce.

K tomu slouží funkce:

void show_mouse(BITMAP *bmp);


která jako parametr bere BITMAPu na kterou si přejeme kurzor myši zobrazit.
Volání může vypadat například takto: show_mouse(screen);

Opak této funkce, tedy pro opětovné skrytí kurzoru je funkce:

show_mouse(NULL);


A teď ještě k dalším funkcím v Allegru pro práci s myší.

Nastavení pozice kurzoru na námi zadané souřadnice:

void position_mouse(int x, int y);


Nastavení citlivosti myši:

void set_mouse_speed(int xspeed, int yspeed);


Jako parametry jsou hodnoty zvlášť pro x-ovou a y-ovou souřadnici. Standardně je pro obě souřadnice hodnota 2. Vyšší hodnota znamená vyšší citlivost ( tedy pro přemístění kurzoru ujedeme větší vzdálenost na podložce ) a nižší hodnota znamená přesný opak.

Rozsah myši si můžeme taky navolit podle nás:

void set_mouse_range(int x1, int y1, int x2, int y2);


Této funkci dáme parametry souřadnice obdélníku v jakém se může naše myš ( nebo spíše kurzor ) pohybovat. Pokud tedy chcete např., aby se kurzor pohyboval pouze v horní polovině obrazovky dosáhnete toho voláním této funkce s těmito parametry:

set_mouse_range(0, 0, (SCREEN_W / 2) - 1, (SCREEN_H / 2) - 1);


A nyní ještě něco ke kurzorům
To znamená např.: jak si změním kurzor na svůj => třeba na křížek a taky jak si změním v kurzoru pozici, která mi udává souřadnice. Je blbý, aby křížek reagoval na levý horní roh :), když má reagovat na prostředek.

Ke změně slouží funkce:

void set_mouse_sprite(BITMAP *sprite);


Tato funkce bere jako parametr BITMAPu, kterou si můžete nakreslit v nějakém graf. programu anebo si ji jednoduše namalovat pomocí Allegra.

A reakci kurzoru nastavíme pomocí:

void set_mouse_sprite_focus(int x, int y);


Jako parametry máme samozřejmě pozici v naší BITMAPě. Defaultní nastavení je 0, 0.

Dneska jsme si toho ukázali hodně z toho co Allegro nabízí. Pokud chcete vědět ještě více není nic jednoduššího než se podívat do manuálu Allegra. Anebo si taky můžete prohlédnout ukázkové programy v Allegru.

Příklad:

Pro lepší pochopení si uvedeme opětovný příklad na dnění funkce.

Ovládání:

R - zvětšuje intenzitu červené barvy max. 255
Shift + R - zmenšuje intenzitu červené barvy min. 0

G - zvětšuje intenzitu zelené barvy max. 255
Shift + G - zmenšuje intenzitu zelené barvy min. 0

B - zvětšuje intenzitu modré barvy max. 255
Shift + B - zmenšuje intenzitu modré barvy min. 0

ESC nebo pravé tlačítko myší - konec programu

Levé tlačítko - kreslí buď tečky nebo lomenou čáru

Enter - mění druh kreslení - viz levé tlačítko

Poznámka:
V programu je malý obdélník. Pokud se kurzor objeví uvnitř tak se obrázek kurzoru změní na standardní šipku a pokud se objeví pryč z obdélníku objeví se místo šipky křížek. Kurzor se může pohybovat pouze v rozmezí horní poloviny obrazovky.

Program:

#include <dos.h>
#include <stdlib.h>
#include "allegro.h" // hlav. soubor. allegra - to už ani nemusím psát :)

// Bitmapa pro kurzor myši
BITMAP *mouse;
PALETTE pal;

int main()
{
  int i, maluju = 0, comalujes = 1, jeenter = 0;
  int zmenit = 1;
  int x_old = 0, y_old = 0, x = 0, y = 0;
  int r=255, g=255, b=0;

  allegro_init();
  install_mouse();
  install_keyboard();

  set_color_depth(16);

  i = set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);

  if (i<0)
  {
    allegro_exit();
    printf("CHYBA");

    return 0;
  }

  // nahraje kuszor mysi a upravi fokus
  mouse = load_bitmap("mousesprite.bmp",  pal);
  set_mouse_sprite(mouse);
  set_mouse_sprite_focus(9, 8);

  // zobrazi kuzor a nastavi rychlost a rozsah
  show_mouse(screen);
  set_mouse_speed(5,5);
  set_mouse_range(0, 0, SCREEN_W - 1, SCREEN_H/2 - 1);
  position_mouse(0, 0);

  // kresli obdelnik
  rect(screen, 100, 100, 200, 200, makecol(255, 0, 0));

  while (1)
  {
    // jeli mys v obdelniku ukaze se defaultni kurzor
    if (mouse_x > 100 && mouse_x < 200 && mouse_y > 100 
        && mouse_y < 200 && zmenit)
    {
      zmenit = 0;
      set_mouse_sprite(NULL);
    }

    // neni-li in a je tedy out tak se nahraje muj kurzor
    if (!(mouse_x > 100 && mouse_x < 200 && mouse_y > 100 
        && mouse_y < 200) && !zmenit)
    {
      zmenit = 1;
      set_mouse_sprite(mouse);
    }

    // pokud zmacknu uziv. tlac. tak malujeme
    if (mouse_b & 1)
    {
      maluju = 1;
      show_mouse(NULL);

      // malujeme tecky nebo cary
      if (comalujes)
        putpixel(screen, mouse_x, mouse_y, makecol(r, g, b));
      else
      {

        x = mouse_x;
        y = mouse_y;

        line(screen, x_old, y_old, x, y, makecol(r, g, b));

        x_old = x;
        y_old = y;
      }

    }
    else
      if (maluju == 1)
        maluju = 0 ;

    if (maluju == 0)
    {
      maluju = 2;
      show_mouse(screen);
    }

    // menime barvu RED
    if (key[KEY_R])
    {
      if (key_shifts & KB_SHIFT_FLAG)
        r--;
      else
        r++;

      if (r>255)
        r=255;
      if (r<0)
        r=0;
    }

    // menime barvu GREEN
    if (key[KEY_G])
    {
      if (key_shifts & KB_SHIFT_FLAG)
        g--;
      else
        g++;

      if (g>255)
        g=255;
      if (g<0)
        g=0;
    }

    // menime barvu BLUE
    if (key[KEY_B])
    {
      if (key_shifts & KB_SHIFT_FLAG)
        b--;
      else
        b++;

      if (b>255)
        b=255;
      if (b<0)
        b=0;
    }

    // takovy trik aby se funkce pri drzeni
    // klavesy neopakovala
    if (key[KEY_ENTER] && !jeenter)
    {
      jeenter = 1;
      comalujes = !comalujes;
    }

    // tady vime ze je klavesa odmacknuta
    if (!key[KEY_ENTER])
      jeenter = 0;

    // prave tlacitko mysi nebo ESCape je konec
    if ((mouse_b & 2) || key[KEY_ESC])
      break;

    // aby se barvy menily pomaluji a slo to postrehnout
    delay(5);
    clear_keybuf();
  }

  destroy_bitmap(mouse);
  return 0;
}
END_OF_MAIN();

Minule jsem se zmínil, že si uděláme "velký" příklad, který bude obsahovat vše co jsme se doposud naučili, ale vzhledem k rozsáhlosti dnešního článku jsem se rozhodl vyhradit pro to nový díl o Allegru, který ponese hrdě už číslo 6. Tedy příště se těšte už na větší aplikaci.

Zdrojový příklad si můžete stáhnou zde.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » C/C++  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: