Vánoční JavaScript

5. prosince 2002

Vánoce jsou za dveřmi, aranžování vánočních výloh už je v plném proudu. Chcete-li napodobit obchodníky a nabídnout návštěvníkům svých stránek nějaké vánoční „vychytávky“, možná se vám bude hodit následující JavaScriptová hříčka.

Jedná se o jednoduchou hru na způsob známého střílení slepic alias „Moorhun“. Santa Clause, kteří vykukují v následující červené tabulce, můžete chytit kliknutím na obrázek (u uživatelů Netscape kliknutím na tlačítko „STOP“). Pokud se Vám z pěti pokusů podaří chytit alespoň tři, je zobrazeno hlášení o úspěchu a provede se (v této ukázce nezapojené) přesměrování na jinou stránku. V případě neúspěchu je uživatel vyzván k opakování pokusu.

Zdrojový kód

Kompletní zdrojový text (JavaScript i HTML) příkladu je vám k dispozici ve formě textového souboru. Kromě grafiky můžete rovněž změnou parametrů na počátku textu změnit chování celé hry – tj. počet zobazených políček, počet Santa Clausů, které je potřeba chytit pro výhru, a jejich rychlost. Kód neobsahuje žádné složitosti, středně zkušení uživatelé JavaScriptu by s jeho začleněním do stránky a přizpůsobením svým potřebám neměli mít žádné problémy. Pro začátečníky a pro ty, kdo sdílí obvyklou programátorskou nechuť k luštění cizího kódu, je v následujícím textu podrobně popsáno chování všech důležitých funkcí.

Popis zdrojového kódu

Většina příběhu se odehrává v hlavičce stránky. Nejprve definujeme několik pomocných proměnných ve funkci parametrů celého skriptu a pomocí konstruktoru InitArray založíme tři pomocná pole k uchovávání mezivýsledků:

// Pocet policek
var fields=5;
// Pocet policek nutnych na vyhru
var fieldstowin=3;
// Pocet obrazku, ktere se preklapeji
var imageTypes=8;
// Rychlost santa clausu
var image_speed=50;
// Pomocna pole
var fieldStatus = new InitArray(fields, 1);
var fieldValue = new InitArray(fields,0);
var fieldMax = new InitArray(fields,0);
function InitArray(len,startupvalue){
    this.length = len
    for (var i = 0; i < this.length; i++)
        this[i] = startupvalue
}

Obrázky použité pro animaci je vhodné nahrát ze serveru ještě před tím, než je animace spuštěna:

var i;
for(i=0; i<imageTypes; i++ ){
    eval( „tempimage“+i+“ = new Image();“);
    eval( „tempimage“+i+“.src=\“xmas“+i+“.gif\““ );
}

Následují dvě pomocné funkce. První má za úkol vrátit celé náhodné číslo, druhá pomáhá při animaci – záměně obrázků:

// Vraci nahodne cislo x, kde 0<=x<num
function randNum (num) {
    var rnd1 = Math.round( (num-1) * Math.random() )
    return rnd1;
}
// provede preklopeni obrazku
function SwapImage( destImage, imgnr ) {
    destImage.src=“xmas“+imgnr+“.gif“;
}

Velkou část „práce“ má na starosti funkce scrollField. Ta obsluhuje „vykukování“ Santa Clause v políčku, jehož pořadové číslo jí bylo předáno jako parametr. Funkce volá periodicky sama sebe pomocí časovačů, takže na jeden průběh funkcí musí zabezpečit pouze jeden posun obrázku, ať již dolů nebo nahoru. Při „nultém průběhu“, tedy když Santa Claus není vidět, je náhodně stanovena největší výška, po níž „vykoukne“, a ta je uložena do pole fieldMax. Pro zmenšení počtu pomocných proměnných a podmínek je ve funkci použita drobná „finta“, když se Santa Claus pohybuje dolů, je spolu s jeho aktuální pozicí fieldValue snižována také maximální horní mez fieldMax. Dále jsem pro větší přehlednost použil „vícenásobný return“ z funkce. Tento pohrobek Basicu je sice mnohými odsuzovaný jako skrytý programový skok, podle mého názoru však při střídmém použití může občas přispět ke zmenšení a lepší čitelnosti kódu:

function scrollField( fieldnr ) {
    // neanimujeme stopnuta pole
    if(!fieldStatus[fieldnr]) return;
    // Inicializace vylejzani – nastaveni maximalni vysky
    if(fieldMax[fieldnr]==0) {
        fieldMax[fieldnr]=randNum(imageTypes);
        window.setTimeout(‚scrollField(‚ + fieldnr + ‚)‘,image_speed);
        return;
    }
    var myfield = eval(„document.images[‚xmasimg“+fieldnr+“‚]“);
    // Lezeme nahoru
    if(fieldValue[fieldnr]<fieldMax[fieldnr]) {
        fieldValue[fieldnr]++;
        SwapImage( myfield, fieldValue[fieldnr] );
        window.setTimeout(‚scrollField(‚ + fieldnr + ‚)‘,image_speed);
        return;
    }
    // Lezeme dolu
    fieldValue[fieldnr]–;
    fieldMax[fieldnr]–;
    SwapImage( myfield, fieldValue[fieldnr] );
    if (fieldMax[fieldnr]==0) {
        window.setTimeout(‚scrollField(‚ + fieldnr + ‚)‘,1000+200*randNum(8));
    } else {
        window.setTimeout(‚scrollField(‚ + fieldnr + ‚)‘,image_speed);
    }
}

Poslední funkce v hlavičce stránky, stopField, je volána po kliknutí na obrázek nebo na tlačítko STOP. Má za úkol zastavit animaci v příslušném poli (k tomu stačí nastavit příslušný prvek pole fieldStatus na nulu), dále k zobrazení výsledného obrázku pro úspěch či neúspěch a vyhodnocení, zda došlo k ukončení hry. Všechny tyto činnosti jsou vcelku triviální:

function stopField( fieldnr ) {
    // Nepracujeme se stopnutym polem
    if(fieldStatus[fieldnr] == 0) return;
    // Zastavit a zobrazit obrazek dle vysledku
    fieldStatus[fieldnr] = 0;
    var img = eval(„document.images[‚xmasimg“+fieldnr+“‚]“);
    if(fieldValue[fieldnr])
        img.src=“xmas_ok.gif“;
    else
        img.src=“xmas_failed.gif“;
    // Secteni zastavenych a chycenych policek
    var catched=0;
    var stopped=0
    for( i=0; (i<fieldStatus.length); i++ ) {
        if(fieldStatus[i]==0) {
            stopped++;
            if(fieldValue[i]) catched++;
        }
    }
    document.automat.vysledek.value = catched + “ z “ +stopped;
    // Test na konec hry
    if(catched==fieldstowin) {
        alert(„Vyhrál(a) jste! Nyní budete přesměrován(a) na stránku, kde si můžete vyzvednout svou výhru.“);
        alert(„Přesměrování není v této ukázce zapojeno…“);
    } else {
        if(stopped==fields) {
            if(confirm(„Nevyšlo to. Chcete zkusit štěstí znova?“)) location.reload();
        }
    }
}

V těle stránky musíme vytvořit formulář s názvem „automat“, do nějž vložíme tabulku s nadpisy hry (podrobnosti viz výpis zdrojového kódu) a na příslušné místo následující kód. Ten do tabulky vypíše potřebnou sadu obrázků, přiřadí jim jména stylu xmasimg0xmasimgN a pro prohlížeč Netscape vytvoří tlačítka „STOP“:

for(i=0;i<fields;i++) {
    document.write(‚<td align=“center“ bgcolor=“white“><img src=“xmas1.gif“ name=“xmasimg’+i+'“ onclick=“stopField(‚+i+‘)“ width=“32″ height=“32″>‘);
    if(navigator.appName.indexOf(„Netscape“)!=-1)
        document.write(‚<br><input type=“button“ value=“STOP“ name=“stop’+i+'“ onclick=“stopField(‚+i+‘)“>‘);
    document.write(„</td>“);
}

Na konec stránky patří kód, který odstartuje animaci a zajistí vyplnění správné hodnoty do formulářového pole vysledek (toto pole je rovněž součástí formuláře „automat“ a je použito pro zobrazení aktuálního stavu hry). Některé prohlížeče mívají problém s nulováním formulářových polí po reloadu stránky, proto tato poněkud nadbytečná péče:

for(i=0; i<fields; i++ ) {
    scrollField(i);
}
document.automat.vysledek.value = „0 z 0“;

A to je k uvedenému skriptu vše, snad jen několik závěrečných poznámek:

  • Ze zdrojového kódu vyplývá, že ke správné funkci potřebujeme obrázky s jednotlivými fázemi animace, pojmenované xmas0.gifxmas7.gif. Můžete použít obrázky z tohoto příkladu (v zipu jsou k dispozici zde) nebo si vytvořit svoje.
  • Obrázek Santa Clause použitý v animaci byl stažen z veřejně přístupné databáze obrázků, kde jej jeho autor označil jako volně šiřitelný pro zdarma dostupné aplikace, jeho publikace na WWW stránkách by tedy měla být v souladu s autorskými právy.
  • Odpůrcům globalizace navrhuji nahradit Santa Clause politicky korektním dárkovým balíčkem .
  • Připomínka pro úplné začátečníky – nesnažte se z tohoto skriptu udělat hrací automat s reálnými výhrami – JavaScript není bezpečná platforma pro takové použití a mohli byste být překvapeni počtem šťastných „výherců“.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *