If you're seeing this message, it means we're having trouble loading external resources on our website.

Jeżeli jesteś za filtrem sieci web, prosimy, upewnij się, że domeny *.kastatic.org i *.kasandbox.org są odblokowane.

Główna zawartość

Interaktywne sceny

Teraz, gdy wiemy już jak tworzyć ciekawe animowane sceny, pora nauczyć się jak radzić sobie z innym rodzajem nie-statycznych scen: takich, które odpowiadają na interakcję użytkownika. Na przykład, chcemy narysować scenę, w której Winston ma dzieci (oczywiście dzieje się to po jego karierze gwiazdy rocka) -- ale chcemy też, by użytkownik mógł za pomocą kliknięcia dodać Winstonowi WIĘCEJ dzieci. Ponieważ nikomu nie przeszkadza mieć więcej Winstoniontek, prawda?
Oto jak ta scena wyglądałaby jako samodzielny program. Program rysuje statyczną część sceny, następnie w mouseClicked rysuje obrazki dzieci Winstona w lokalizacji, w którą kliknęliśmy kursorem, ustawiając je nad wszystkim, co do tej pory zostało narysowane.
Ale jak to połączyć z naszym programem zawierającym wiele scen? Zacznijmy od ujęcia całego kodu rysującego statyczne elementy w funkcję rysującą drawScene5() i dodania mechanizmu zmiany scen do mouseClicked:
var drawScene5 = function() {
    currentScene = 5;
    background(173, 239, 255);
    fill(7, 14, 145);
    textSize(39);
    text("Winstonowi urodziły sie dzieci!", 10, 47);
    ...
};

mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
    } else if (currentScene === 5) {
        drawScene1();
    }
};
Sprawdźmy, jak to wygląda w naszym programie:
Ale jak połączymy funkcjonalności mouseClicked? Zdefiniowaliśmy już przecież mouseClicked w naszym kodzie, a nie możemy zdefiniować go dwa razy. W JavaScripcie ostatnia definicja funkcji "wygrywa", nadpisując wszystkie wcześniejsze definicje. Oznacza to, że musimy znaleźć dobre miejsce do umieszczenia naszego kodu rysującego dziecko w aktualnej wersji mouseClicked. Rozważmy kilka sposobów:
1. Możemy umieścić odpowiednią linię na samej górze treści funkcji:
mouseClicked = function() {
  image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
  ...
};
Będzie to wywoływane ZA KAŻDYM RAZEM, gdy użytkownik kliknie myszką na ekran, nawet jeśli to nie jest scena powiązana z dziećmi (a będzie to dziwne, gdy mały Winston będzie miał dzieci). Odpada.
2. Możemy umieścić tą linię w części ograniczonej warunkiem currentScene === 4:
mouseClicked = function() {
  if (currentScene === 1) {
    drawScene2();
  } else if (currentScene === 2) {
    drawScene3();
  } else if (currentScene === 3) {
    drawScene4();
  }  else if (currentScene === 4) {
    drawScene5();
    image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
  } else if (currentScene === 5) {
    drawScene1();
  }
};
W końcu to tutaj wywołujemy drawScene5(), a dzieci powinny być dodawane do sceny piątej. Ale pomyślcie o tym: oznaczałoby to, że zawsze rysujemy dodatkowe dziecko podczas rysowania tej sceny. Oznacza to także, że nigdy nie narysujemy więcej dzieci, ponieważ currentScene zostałoby ustawione na wartość 5, a kod zawarty w powyższym warunku już nie byłby więcej wykonywany.
3. Możemy umieścić tą linię w części ograniczonej warunkiem currentScene === 5:
mouseClicked = function() {
  if (currentScene === 1) {
    drawScene2();
  } else if (currentScene === 2) {
    drawScene3();
  } else if (currentScene === 3) {
    drawScene4();
  }  else if (currentScene === 4) {
    drawScene5();
  } else if (currentScene === 5) {
    image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    drawScene1();
  }
};
Oznacza to, że nie rysowalibyśmy dzieci aż do pierwszego kliknięcia po narysowaniu sceny. Ale jak widać z linii następnej, dziecko od razu byłoby zastąpione przez pierwszą scenę.
To jest ten moment, kiedy zauważamy fatalny błąd w naszym pomyślne na włączenie tej dodającej dzieci sceny do reszty naszych scen: używamy dokładnie tego samego typu interakcji - kliknięcie w dowolnym miejscu ekranu - by zmieniać scenę, jak również dokonywać interakcji wewnątrz sceny. Teraz mamy styczność z naprawdę ciężkim orzechem do zgryzienia, tak więc musimy rozważyć bardziej radykalne sposoby zintegrowania naszej sceny.
4. Możemy przestać ponownie rysować scenę pierwszą na końcu, zamiast tego prosząc użytkownika o zrestartowanie całego programu. Jasne, to zadziała, ale tylko pod warunkiem, że nasza interaktywna scena będzie ostatnią ze wszystkich. Co się stanie, jeśli tego typu scenę chcielibyśmy umieścić wcześniej? Ten sposób nie przejdzie.
5. Możemy użyć innego sposoby interakcji - na przykład mouseDragged.  To zadziała, ponieważ przeciąganie obiektu nie powoduje dodatkowo zdarzenia kliknięcia. Wciąż jednak musimy sprawdzić, czy currentScene === 5, by upewnić się, że nasze przeciąganie nie narysuje dzieci w innych scenach:
mouseDragged = function() {
    if (currentScene === 5) {
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    }
};
Wypróbujcie to poniżej, upewniając się, że przeciągacie na ostatniej scenie:
Doszliśmy do jakiegoś rozwiązania, chociaż trochę jestem zaniepokojony tym, z jak dużą liczbą dzieci może skończyć Winston. Ogólnie rzecz biorąc, nie jest to rozwiązanie optymalne, gdyż ten sposób ogranicza nas do projektowania scen, które nie odpowiadają na kliknięcia myszką. Nie chcemy mieć tego rodzaju ograniczenia, musi istnieć lepszy sposób.
A może rozróżniać kliknięcia myszką na podstawie lokalizacji kursora, tak aby kliknięcie w jednym miejscu zmieniało scenę, a w innym odpowiadało za interakcję wewnątrz sceny? Wiecie, tak jak z przyciskami! W rzeczywistości, większość programów posiadających wiele scen właśnie tak rozwiązuje ten problem, o czym porozmawiamy następnym razem.

Chcesz dołączyć do dyskusji?

Na razie brak głosów w dyskusji
Rozumiesz angielski? Kliknij tutaj, aby zobaczyć więcej dyskusji na angielskiej wersji strony Khan Academy.