A String osztály
Már használtunk stringet pl. képfájl betöltésére vagy szöveg kiírására, ezek kódjai:
println("printing some text to the message window!");
PImage img = loadImage("filename.jpg");
A string karaktert vagy karakterláncot jelent. A karakterek értéket is tárolnak, tehát a string is adat.
Ha nem lenne string osztályunk akkor ilyen kódot kellene írnunk:
char[] sometext={'H','e','l','l','o',' ','W','o','r','l','d'};
De mivel Processingben van, ezét a következő formát használhatjuk:
String sometext = "How do I make String? Type some characters
between quotation marks!"; //a kódot egy sorba írd!
Különböző metódusokkal működik:
charAt()
Szimpla karater ad vissza, az index szám jelöli hogy a stringnek hanyadik elemét akarjuk kiolvasni. Arra vigyázz hogy az első elemet 0-val, a másodikat 1-gyel stb. lehet elérni!
String message = "some text here.";
char c = message.charAt(3);
println(c); // az eredmény: 'e'
length()
Nem összekeverendő a tömbb hossz paraméterével. A kerek zárójel is arra utal hogy ez nem egy paraméter hanem egy függvény.
String message = "This String is 34 characters long.";
println(message.length());
toUpperCase(), toLowerCase()
Átváltoztathatjuk a stiongünket nagybetűkre és kisbetkre ezekkel.
String uppercase = message.toUpperCase();
println(uppercase);
Mivel a string egy állandó, tehát értéke nem változik, ezért ha változtatni akarjuk akkor mindig létre kell hoznunk egy új stringet. Ebben a példában a a toUpperCase a sting negybetűs másolatát küldi vissza.
equals()
== operátorral tehetjük a stringet valamivelegyenlővé, a szimpla = deklarálásra szolgál!
String one = "hello";
String two = "hello";
println(one == two);
A harmadik sorban az objektumok memória címét hasonlítjuk össze (technikailag), mivel ugyanazta stringet tartalmazzaa kétérték megegyezik, egyébként a végeredmény hamis (false) lenne.
Az equal() függvény biztosítja hogy leellenőrizhessük hogy a két string ugyanazt a karakterláncot tartalmazza-e, figyelmen kívül hagyva hogy hol tároljuk az adatot.
String one = "hello";
String two = "hello";
println(one.equals(two));
Habár mindkét kód ugyanazt csinálja, biztonságosabb az equalt() használni, mivel attól függően hogy a kódban hol hozzuk létre string objektumot, az == nem mindigműködik.
Stingeket egymáshoz is fűzhetünk a + operátorral, számok esetében ez természetesen összeadást jelent.
String helloworld = "Hello" + "World";
Változókat is hozzá fűzhetünk stringekhez:
int x = 10;
String message = "The value of x is: " + x;
Szöveg megjelenítése
Ennek legegyszerűbb modja hakiprinteljük őket az üzenet ablakban. Ezt csináljuk amikor nyomon akarjuk követni az adatunkat, pl. ha a horizontális egérmozgást akarjuk tudni akkor ezt írjuk le:
println(mouseX);
De akár leíró szöveget is kiírhatunk a kódban általunk gondolt helyen:
println("Kiírjuk az egér pozícióját!");
Ebben az esetben a szövegünk még nem a megjelenítő ablakban van, hogyan tudnánk ezt is elérni? A következő pár lépéssel:
1. Deklaráljunk egy PFont típusú objektumot.
PFont f;
2. Hozzuk létre a betűket a nevére hivatkozva a createFont() függvénnyel. Ez ugyanúgy egyszer fut le minta setup(). Éppúgy mint a képeknél, memóriába töltjük az adatot, tehát nem célszerű draw() függvénbe tenni.
Az elérhető rendszer-betűtipusokat (mindenkinek van, nem kell telepíteniük) egy kóddal ki tudod printelni, ezután innen tudsz választani:
size(200, 200);
String[] fontList = PFont.list();
println(fontList);
Ezután a következő szintaxissal tudod alkalmazni a betű-nevedhez a paramétereket: típus, mérte, anti-alising legyen (true) vagy ne (false):
f = createFont("Arial",16,true);
// Arial, 16 pont, anti-aliasing be
3. Specifikáld a betűt a textFont() segítségével, két paramétere van, a betű-változód neve és a mérete (utóbbi opcionális és változtatható). Ez a sima text()-hez képest egy bitmap képet eredményez, így dinamikusan növelhető aszöveg mérete. P2D render használatával feljavíthatod a kép minőségét és teljesítményt is. A P3D render pixeleket eredményezhet.
textFont(f,36);
4. Szín megadása fill()-lel:
fill(255);
5. A szöveget a text() függvény meghívásával tudjuk megjeleníteni. Három paraméterrel rendelkezik, éppúgy mint a formák: a megjelenítendő szöveg, x és y koordinátaák.
text("Hello Strings!",10,100);
A teljes kód:
PFont f;
void setup() {
size(200,200);
f = createFont("Arial",16,true);
}
void draw() {
background(255);
textFont(f,16);
fill(0);
text("Hello Strings!",10,100);
}
Menüből is létrehozhatunk betűt: "Tools" --> "Create Font." Ez létrehoz egy VLW betű fájlt a data mappádban, amit PFont objektumba be tudsz tölteni loadFont() függvénnyel.
f = loadFont("ArialMT-16.vlw");
Szöveg animálása
Nézzünk meg néhány hasznos függvényt a fentiek mellé!
textAlign()
A sortördelést határozhatjuk meg vele: balra zárt (LEFT), középre zárt (CENTER) és jobbra zárt (RIGHT).
PFont f;
void setup() {
size(400,200);
f = createFont("Arial",16,true);
}
void draw() {
background(255);
stroke(175);
line(width/2,0,width/2,height);
textFont(f);
fill(0);
textAlign(CENTER);
text("This text is centered.",width/2,60);
textAlign(LEFT);
text("This text is left aligned.",width/2,100);
textAlign(RIGHT);
text("This text is right aligned.",width/2,140);
textWidth()
Kiszámolja és visszaküldi egy karakter vagy szöveg string szélességét.
Csináljuk egy balról jobbra mozgó feliratot! Ha tudjuk a kezdőpont x koordinátáját és a szöveg szélességét, valamint az ablakunk méretét, akkor ki tudjuk számolni az animáció végének x koordinátáját, ahol méglátszik a teljes szöveg.
Először setup()-ban inicializáljuk a szöveget, betűtipust és méretet, x és y koordinátát:
// Főcim animálása
String headline = "Akármi lehet a főcím";
PFont f; // globális változó: f
float x; // szöveg vzsintes pozíciója
void setup() {
f = createFont("Arial",16,true); // betű betöltése
x = width; // inicializáljuk a szöveg jobb szélét
}
A draw()-ban megjelenítjüka szöveget az adott helyen:
textFont(f,16);
textAlign(LEFT);
text(headline,x,180);
Változtatjuk az x pozició értékét hogy létrejöjjön az animáció, mivel balra kell csússzon az értéket csökkentjük:
x = x - 3;
Most egy kicsit bonyolultabb rész jön. Mivel a szövegünk balra van zárva, ezért nem elég ha x kisebb mint 0 egyenlettel akarjuk eltűntetni az ablakból (mint formáknál) mivel ilyenkormég egy része belóg a képe. Ehelyett az egyenletünk úgy néz ki hogy x kisebb mint a nullából kivont szöveg-szélesség (alább a kód):
float w = textWidth(headline);
if (x < -w) {
x = width;
}
A teljes kód:
// string tömbbe tesszük a szöveget:
String[] headlines = {
"Processing a köbön",
"Akármi lehet a főcím",
};
PFont f; // f globális betű változó
float x; // szöveg vizszintes helyzte
int index = 0;
void setup() {
size(400,200);
f = createFont("Arial",16,true);
// jobboldali szöveg eltűntetés inicializálása
x = width;
}
void draw() {
background(255);
fill(0);
// szöveg megjelenítése x poziciónál
textFont(f,16);
textAlign(LEFT);
text(headlines[index],x,180);
// animáció sebessége:
x = x - 3;
// ha x kisebb minta negatv szélesség
// tűnjön el a szöveg:
float w = textWidth(headlines[index]);
if (x < -w) {
x = width;
index = (index + 1) % headlines.length;
}
}
Ezeken kívül még a textLeading(), textMode(), textSize() függvények tartoznak a témához.
Szöveg forgatása
Transzformációt és forgatást is érvényesíthetünk szövegre. Tanslate() használatakor a koordinátarendszerünket helyezzük alrébb, így a fomra x,y értéke ugyanaz maradhat:
A pushMatrix() és popMatrix() függvényekkel jelezzük hogy a transzformációt melyik parancssorokra akarjuk értelmezni (amennyiben nem az egész kódra akarjuk). A példában a kirajzolt szürke négyszöget eltoljuk translate()-tel ráccsal együtt 60,80 koordinátához és kékre színezzük, amint látod ennek helye megegyezik a másodiknak kirajzolt piros négyzettel, amit az eredeti koordinátarendszerben rajzoltunk ki, csak a kezdőpontját helyeztük át, mivel minkét négyszög elfás,a színeik összekeverednek, így egy lila jön létre:
void setup()
{
size(200, 200);
background(255);
noStroke();
// eredeti szürke négyzet kirajzolása:
fill(192);
rect(20, 20, 40, 40);
// az átlátszó piros nyégyzet megváltoztatott koordinátával:
fill(255, 0, 0, 128);
rect(20 + 60, 20 + 80, 40, 40);
// az átlátszó kék négyzet a rács alrébb tolásával:
fill(0, 0, 255, 128);
pushMatrix();
translate(60, 80);
rect(20, 20, 40, 40);
popMatrix();
}
A forgatás ugyanígy működik, paraméternek megadjuk hogy milyen mértékegységben és mennyivel akarjuk forgatni:
pushMatrix();
rotate(radians(45));
fill(0);
rect(40, 40, 40, 40);
popMatrix();
Nagyítás vagy kicsinyítés:
pushMatrix();
scale(2.0);
rect(20, 20, 40, 40);
popMatrix();
Az előzőek alapján forgassuk körbe a középpont körül a középre igazított szövegünket:
PFont f;
String message = "ez a szöveg pörög";
float theta;
void setup() {
size(200, 200);
f = createFont("Arial",20,true);
}
void draw() {
background(255);
fill(0);
textFont(f); // szöveg beállítása
translate(width/2,height/2); // középre transzformálása
rotate(theta); // elforgatása theta-változó értékével
textAlign(CENTER);
text(message,0,0);
theta += 0.05; // forgatás növelése
}
Szöveg kirajzolása karakterenként
Ebben az esetben a karaktereket egyenként mozgathatod, színezheted, stb. Ehhez létre kell hoznod egy tömbböt amibe beolvasod a karaktereket egyenként charAt() függvénnyel, és innen fogod őket kirajzolni úgy hogy a pozíciójuk x tengelyen mindig 10-zel több. A fent említett módokon hozd létre a PFont objektumodat, töltsdbele a szöveget, határozd meg aszöveg tulajdonságait és draw()-ba írd a karakter számláló for ciklust!
PFont f;
String message = "Each character is not written individually.";
void setup() {
size(400, 200);
f = createFont("Arial",20,true);
}
void draw() {
background(255);
fill(0);
textFont(f);
// egy tömbként jelenik meg a szöveg
text(message,10,height/2);
}
Ebben az esetben egyben jelent meg a szöveged, mivel nincs kiolvasva karakterenként. Írjuk át:
PFont f;
String message = "Each character is written individually.";
void setup() {
size(400, 200);
f = createFont("Arial",20,true);
}
void draw() {
background(255);
fill(0);
textFont(f);
int x = 10;
for (int i = 0; i < message.length(); i++) {
// i++ ugyanaz mint i=i+1
// charAt() egyesével beolvassa a karaktereket:
text(message.charAt(i),x,height/2);
// 10 pixelközönként kiírja a karaktereket:
x += 10;
}
}
Ebben az esetbenmár karakterenkéntírtuk ki a szöveget,de nagyon szétesik, igazítsuk meg textWidth() fügvénnyel, ami kiolvassa az adott karakter (i változóval meghatározott) szélességét (pixelben) és hozzáadja az x-hez (ami10 pixel):
PFont f;
String message = "Each character is written individually.";
void setup() {
size(400, 150);
f = createFont("Arial",20,true);
}
void draw() {
background(255);
fill(0);
textFont(f);
int x = 10; //első karakter itt lesz
//kiolvassuk a karaktereket sorban egy for ciklussal:
//
for (int i = 0; i < message.length(); i++) {
textSize(random(12,36)); // 12-36 közötti random érték
text(message.charAt(i),x,height/2);
// textWidth() a betűköz helyes beállítására:
x += textWidth(message.charAt(i));
}
noLoop();
}
Most már tudjuk effektezni is a karaktereket egyenként! Akövetkező példában, ha nyomva tartod a bal egér gombot, akkor összerázódnak a betűk, azaz pozíciót változtatnak:
PFont f;
String message = "click mouse to shake it up";
// Letter objektum tömb, letters névvel:
//Az osztályt később meghatározzuk majd!
Letter[] letters;
void setup() {
size(260, 200);
// betű betöltése
f = createFont("Arial",20,true);
textFont(f);
// adott string hosszúságú tömbb létrehozása:
letters = new Letter[message.length()];
// Letters inicializálása x pozícióra
int x = 16;
for (int i = 0; i < message.length(); i++) {
letters[i] = new Letter(x,100,message.charAt(i));
x += textWidth(message.charAt(i));
}
}
void draw() {
background(255);
for (int i = 0; i < letters.length; i++) {
// betűk megjelenítése
letters[i].display();
// ha egérgomb nyomva, a betűk rázkódnak
// ha nincs,akkor eredetipozícióba kerülnek
if (mousePressed) {
letters[i].shake();
} else {
letters[i].home();
}
}
}
// Az osztály ami minden egyes betűre jellemző
class Letter {
char letter;
// jegyezze meg az eredeti pozícióját:
float homex,homey;
// és a pillanatnyit is:
float x,y;
Letter (float x_, float y_, char letter_) {
homex = x = x_;
homey = y = y_;
letter = letter_;
}
// betűk megjelentése
void display() {
fill(0);
textAlign(LEFT);
text(letter,x,y);
}
// mozgasd a betűket random
void shake() {
x += random(-2,2);
y += random(-2,2);
}
// kerüljenek vissza a betűk eredeti pozícióba
void home() {
x = homex;
y = homey;
}
}
A karakterről karakterre módszer lehetővé teszi hogy görbére illesszük a szöveget. Első lépésként fűzzünk fel négyzeteket egy körvonalra, ehhez trigonometriát kell alkalmaznunk.
Példa:
PFont f;
// A kör sugara:
float r = 100;
// a dobozok szélessége és magassága:
float w = 40;
float h = 40;
void setup() {
size(320, 320);
smooth();
}
void draw() {
background(255);
// Rajzoljunk egy kört az ablak közepére
translate(width / 2, height / 2); //eltoltuk a rácsot
noFill();
stroke(0);
// Az ablakunk közzépontj a köré is,
// innen rajzolunk r sugarú kört:
ellipse(0, 0, r*2, r*2);
// 10 dobozunk legyen:
int totalBoxes = 10;
// Visszakövetjük a pozíciójukat a görbe mentén:
float arclength = 0;
// for ciklus az összes dobozhoz:
for (int i = 0; i < totalBoxes; i++) {
// a dobozok felének szélességével toljuk el őket:
arclength += w/2;
// A fok radiánban megadva,
// a pozíció osztva a sugárral:
float theta = arclength / r;
pushMatrix();
// derékszögű koordináta átalakítása:
translate(r*cos(theta), r*sin(theta));
// doboz elforgatása:
rotate(theta);
// doboz megjelenítése:
fill(0,100);
rectMode(CENTER);
rect(0,0,w,h);
popMatrix();
// ismét elmozdítjuk a dobozt:
arclength += w/2;
}
}
Ezek után a dobozokon belülre helyezzünk egy-egy betűt. Mivel a betűk szélessége változó ismét a textWidth()-et hívjuk segítségül.
// A megjelenítendő szöveg:
String message = "text along a curve";
PFont f;
// a kör sugara:
float r = 100;
void setup() {
size(320, 320);
f = createFont("Georgia",40,true);
textFont(f);
// Középre zárjuk a szöveget:
textAlign(CENTER);
smooth();
}
void draw() {
background(255);
// középre toljuk a koordináta rendszert:
// kört rajzolunk:
translate(width / 2, height / 2);
noFill();
stroke(0);
ellipse(0, 0, r*2, r*2);
// Visszakövetjük a pozíciót a görbe mentén:
float arclength = 0;
// For ciklus az összes dobozhoz:
for (int i = 0; i < message.length(); i++)
{
// leellenőrizzük minden karakter szélességét:
char currentChar = message.charAt(i);
float w = textWidth(currentChar);
// alrébb tesszük a dobozok szélességével:
arclength += w/2;
// radiánsban megadott szög:
// dobozok szélessége osztva a kör sugarával:
// a kör bal szélén kezdjük, PI-től indul:
float theta = PI + arclength / r;
pushMatrix();
// derékszögű koordináta átalakítása:
translate(r*cos(theta), r*sin(theta));
// doboz elforgtása:
rotate(theta+PI/2); // 90 fokkal elforgatjuk
// karakter megjelenítése
fill(0);
text(currentChar,0,0);
popMatrix();
// eltolása a megfelelő pozícióhoz:
arclength += w/2;
}
}
A fokok PI-vel meghatározott értékei:
forrás: http://processing.org/learning/text/,
http://processing.org/learning/transform2d/
http://processing.org/reference/pushMatrix_.html