W tej części poradnika zajmiemy się połączeniem wykonanych do tej pory elementów, czyli animacji napisanych w Processingu, animacji stworzonej w After Effects i miniatury sześcianu do interakcji. Będziemy rozwijać stworzony w części drugiej sketch. Jeżeli czytanie zaczynasz od tej części, pobierz sketch tutaj.
Stwórz nową zakładkę w Processingu (Ctrl+Shift+N lub Cmd+Shift+N na macOS) o nazwie interaction. W tej zakładce umieścimy kod odpowiedzialny za interakcję z mappingiem.
Nasz mapping składa się z trzech tekstur, na każdej z nich możemy rysować różne animacje – interakcja będzie polegała na zmianie animacji na ściance po dotknięciu odpowiadającej jej ścianki na miniaturowym sześcianie. Zacznijmy od stworzenia tablicy, w której przechowamy informację o tym, która animacja ma być rysowana na której ściance. Pierwszy element tablicy zawiera numer animacji, która ma być rysowana na górnej ściance, drugi element zawiera numer animacji na lewej ściance, a trzeci na ściance prawej.
int animationToTexture[] = {0, 0, 0};
animationToTexture
– poszczególne pozycje w tablicy zawierają numer animacji, którą należy narysować na odpowiadającej jej pozycji. Do dyspozycji mamy trzy animacje – glitch, feedback i strobo. Umówmy się, że przypiszemy im kolejne liczby zaczynając od 0. Animacji glitch odpowiada liczba 0, feedback będzie miał numer 1, a strobo numer 2. Dodaj poniższą funkcję do zakładki interaction:
void drawAnimations() {
for (int i = 0; i < animationToTexture.length; i++) {
switch (animationToTexture[i]) {
case 0: drawGlitch(i);
break;
case 1: drawFeedback(i);
break;
case 2: drawStrobo(i);
break;
}
}
}
Teraz należy wywołać stworzoną funkcję drawAnimations w głównej funkcji draw() naszego sketcha, zamiast bezpośrednio wywoływać tam funkcje rysujące konkretne animacje.
void draw() {
background(0);
drawAnimations();
mapper.drawContent(textures);
mapper.drawGUI();
}
Po uruchomieniu sketcha, na każdej ściance powinna zostać narysowana animacja glitch – początkowe wartości w tablicy animationToTexture to 0. Teraz zmień wartości w tablicy np na 0, 1, 2.
int animationToTexture[] = {0, 1, 2};
Po uruchomieniu zobaczysz, że na każdej ściance rysowana jest inna animacja. Aby zmieniać animacje wystarczy zmieniać wartości w tablicy animationToTexture. Teraz napiszemy funkcję zmieniającą te wartości po dotknięciu ścianki miniaturowego sześcianu.
W poprzednim artykule skonfigurowaliśmy płytkę TouchBoard w taki sposób, aby po wykryciu dotyku wysyłała do komputera sygnały takie same jak w przypadku naciśnięcia klawiszy na klawiaturze. O takim zdarzeniu Processing informuje nas wywołując funkcje keyPressed https://processing.org/reference/keyPressed_.html i keyReleased https://processing.org/reference/keyReleased_.html, dodatkowo dostępna jest wbudowana zmienna key https://processing.org/reference/key.html zawierająca symbol odpowiadający wciśniętemu klawiszowi.
Podłącz stworzony wcześniej obiekt do interakcji do komputera, otwórz notatnik i sprawdź, jakie literki pojawiają się po wciśnięciu jakich ścianek miniaturowego sześcianu. W naszym przypadku są to:
- H dla górnej ścianki
- U dla lewej ścianki
- J dla prawej
Stwórzmy teraz funkcję, która na podstawie wciśniętego klawisza będzie zmieniać wartości w tablicy animationToTexture (Uwaga: Zmienna key w naszym przypadku zawiera małe wersje powyższych liter, takich też użyjemy w funkcji, możesz sprawdzić jakie klawisze rozpoznaje twója wersja Processingu wypisując wykryty klawisz w konsoli):
void toggleAnimations() {
println(“Key: ” + key); // sprawdzenie jaki klawisz jest wykryty
if (key == 'h') {
animationToTexture[0] = ++animationToTexture[0] % 3;
}
if (key == 'u') {
animationToTexture[1] = ++animationToTexture[1] % 3;
}
if (key == 'j') {
animationToTexture[2] = ++animationToTexture[2] % 3;
}
}
W funkcji tej chcemy aby animacje były zmieniane w kółko, do tego idealnie nadaje się operator % (modulo), operator preinkrementacji spowoduje, że wartość elementu tablicy zostanie zwiększona o 1 jeszcze przed przekazaniem jej do modulo. Stworzoną funkcję wywołamy w funkcji keyReleased naszego sketcha – zostanie ona wywołana dopiero w momencie oderwania palca od ścianki sześcianu, gdybysmy wywołali ją w funkcji keyPressed animacje zmieniały by się bardzo szybko przez cały czas dotykania ścianki co skutkowałoby niezbyt atrakcyjnym efektem.
void keyReleased() {
mapper.onKeyReleased();
toggleAnimations();
}
Po uruchomieniu sketcha animacje powinny zmieniać się po dotknięciu ścianek miniaturowego sześcianu. Jeżeli chcesz korzystać z mappingu bez tworzenia obiektu do interakcji, możesz wciskać klawisze na klawiaturze komputera – pamiętaj, że nasza funkcja toggleAnimations reaguje na wciskanie wielkich liter – użyj kombinacji np Shift+H tak jak podczas pisania tekstu aby uzyskaćn wielką literę. Możesz też zmodyfikować funkcję toggleAnimations tak, aby reagowała na wybrane przez Ciebie klawisze, np kolejne małe litery.
Kolejną modyfikacją, będzie dodanie do sketcha animacji stworzonej w After Effects. Aby odtworzyć wideo w Processingu potrzeba użyć biblioteki Video https://processing.org/reference/libraries/video/index.html
Z górnego menu w Processingu wybierz Sketch->Import library->Video
W karcie interaktywny_mapping nad funkcją setup() stwórz zmienną movie. Video musi zostać zainicjalizowane podczas startu sketcha w funkcji setup(). Aby wczytać plik video umieść go w folderze data/ naszego sketcha, w Processingu mamy dostęp do plików w folderze data bezpośrednio po ich nazwie. Po wczytaniu pliku wywołamy funkcję loop na naszym video, aby odtwarzało się w pętli. Należy również pamiętać, aby w głównej funkcji draw() wczytywać kolejne klatki pliku video.
...
Movie movie;
void setup() {
fullScreen(P2D, 2);
movie = new Movie(this, "video.mp4");
movie.loop();
...
}
void draw() {
background(0);
if (movie.available()) {
movie.read();
}
...
}
Przejdźmy teraz do zakładki content, gdzie stworzymy funkcję rysującą video na teksturze w analogiczny sposób, w jaki rysowane są wcześniejsze animacje. Stwórz funkcję drawVideo:
void drawVideo(int gIndex) {
PGraphics g = textures[gIndex];
g.beginDraw();
g.image(movie, 0, 0, g.width, g.height);
g.endDraw();
}
Zmodyfikujemy teraz funkcje w zakładce interaction tak, aby uwzględniały nowo dodaną funkcję drawVideo.
W funkcji drawVideo dodamy kolejny warunek – jeżeli wartość elementu tablicy animationToTexture wyniesie 3 będziemy wywoływać funkcję drawVideo dla tekstury.
void drawAnimations() {
for (int i = 0; i < animationToTexture.length; i++) {
switch (animationToTexture[i]) {
case 0: drawGlitch(i);
break;
case 1: drawFeedback(i);
break;
case 2: drawStrobo(i);
break;
case 3: drawVideo(i);
break;
}
}
}
Teraz zwiększymy zakres dozwolonych wartości podczas przełączania animacji w funkcji toggleAnimations z 3 na 4:
void toggleAnimations() {
if (key == 'h') {
animationToTexture[0] = ++animationToTexture[0] % 4;
}
if (key == 'u') {
animationToTexture[1] = ++animationToTexture[1] % 4;
}
if (key == 'j') {
animationToTexture[2] = ++animationToTexture[2] % 4;
}
}
Po uruchomieniu sketcha powinieneś zobaczyć dodane wideo pomiędzy pozostałymi animacjami.
Jeżeli zastanawiasz się w jaki sposób rozwijać dalej swój mapping, możesz dodać więcej animacji lub poeksperymentować z przejściami między nimi.
Ukończony projekt możesz pobrać tutaj.
0 komentarzy