Processing i micro:bit – igra Pong
Pomeranje grafičkih objekata, koje iscrtavamo u nekoj aplikaciji u Processing-u možemo vezati za događaje miša i tastature. Npr. Pomeranje možemo ostvariti pritiskom na tastere sa strelicama, ili na neki drugi taster koji mi odredimo. Umesto toga, možemo upotrebiti i mikrokontroler, npr. Micro:bit, tako što pomoću njega merimo npr. ubrzanje, ili proizvedemo neki događaj, a onda prenesemo tu informaciju preko serijskog porta na računar. Tu informaciju dalje, koristi aplikacija u Processing-u, koja je čita takođe sa serijskog porta. Upoznajmo se u nastavku o Mikro:bit-u i pogledajmo primere u Processing-u koji koriste jedan ili više mikro:bit-ova.
Microbit uređaj
Mikrobit je ručni programabalni mikro računar. Sastoji se od poločice, procesora, senzora, dioda, ulazno-izlaznog serijskog porta, tastera. Može se povezati sa Processingom koji je pogodan za kreiranje vizuelnih aplikacija. Pogodan je za učenje dece programiranju.
Povezivanjem mikrobita i processinga mogu se kreirati zanimljive aplikacije, jer se već bogata biblioteka pogodna za kreiranje animacija i simulacija iz fizike, može obogatiti merenjem temperature, ubrzanja, jačine svetlosti, udaljenosti do predmeta itd. korišćenjem mikrobita.
Može se programirati pomoću programskih jezika scratch, javascript-a ili python-a. Evo nekih preporuka :
- Za programiranje u scratch-u ili javascript-u koristiti Majkrosoftov MakeCode: https://makecode.microbit.org/
- Za programiranje u pajtonu instalirati radno okruženje Mju: https://codewith.mu/en/download
- Na sledećim slikama se može videti prednja i zadnja strana mikrobit-a


Delovi mikrobita
Delovi mikrobita:
- Prednja ploča
- Zadnja ploča
- Ekran sa 25 LED dioda
- Tasteri, se nalaze sa leve i desne strane ekrana A i B. pritisak na taster se registruje od strane microbita. Postoji i taster za reset, tj. za restartovanje programa, odnosno njegovo ponovno učitavanje
- Kompas, određuje položaj (stranu sveta) i može da meri jačinu magnetnog polja
- Akcelerometar. Detektuje pokrete mikrobita
- Senzor za temperaturu. Ovaj senzor meri temperaturu mikrobit-ovog procesora.
- Pinovi. Na ivici mikrobita nalazi se 25 izvoda, 5 velikih i 20 malih. Preko ovih pinova se mogu povezivati razni dodatni uređaji kao i senzori.
Oznake za 5 velikih pinova: 0,1,2, 3V, GND. Prva tri su opšte namene, na 3V dolazi napajanje od 3,3 V, a GND je uzemljenje.
- Bluetooth. Ova antena kojom je opremljen mikrobit služi za bežično povezivanje sa drugim uređajima. ovo povezivanje se može ostvariti sa drugim bluetooth uređajima, sa računarom, mobilnim telefonom ili nekim drugim uređajem.
Na sledećoj slici možete videti delove sa prednje strane mikrobit-a

Na sledećoj slici se može videti detaljan izgled Mikrobit-a sa zadnje strane.

Mikrobit radionice
Mikrobit radionice su sastavni deo kursa kreativnog programiranja koji organizuje Regionalni Centar za Talente "Mihajlo Pupin" u Pančevu:
Kreativno programiranje
Pogledajte u sledećem videu nekoliko osnovnih radionica sa upotrebom mikrobit-a
Igrica pong
Stara igrica pong koja ostvaruje kretanje pravougaonika u horizontalnoj ravni levo-desno i loptice koja se kreće verikalno i odbija o pravougaonik i zidove može se napraviti u processingu i povezati sa mikrobitom. Sledeći video pokazuje kako to može da se uradi:
Prvo đemo pokazati kako da se poveže mikrobit sa processingovom aplikacijom. Mikrobit proizvodi 3 događaja: TitlLeft, TitleRight i shake, koji redom treba da: promene pravac kretanja pravougaonika, na levo, na desno i da izvrše resetovanje u igrici. U delu programa koji treba da bude na mikrobitu definisaćemo ove događaje i koristeći naredbu selekcije, a u zavisnosti od izazvanog događaja, poslati odgovarajuću poruku na serijski port: "l" za titlLeft, "d" za titlRight i "r" za shake događaj. Pregled svih događaja na mikrobitu možemo videti na sledećoj slici:

Prvo ćemo kreirati kod u mikrobitu koristeći makecode projekat i kopirati ga na mikrobit. Kompletan postupak možete videti u izloženom videu. U okviru događaja onStart ubacićemo blok while petlje sa uslovom true, a unutar petlje blok selekcije, tj. if-else if... naredbu, što se može videti na slici 6:

Ili javascript kod:

Kod u Processingu započinjemo kreiranjem setup i draw metode i dodavanjem promenljivih: port(Serial), k(int), dogadjaj(String)
Prvi deo zadatka je da prihvatimo tekst sa serijskog porta i da u zavisnosti da li je "l", "d" ili "r", prepišemo tekst na prozor aplikacije u processingu: Kod koji radi ovo možete videti u nastavku:
Kod sa slike 7: Igrica Pong- Kod u processingu-početak
import processing.serial.*;
Serial port;
float k = 0;
String dogadjaj = "Nema događaja";
void setup() {
size(600, 600);
port = new Serial(this, Serial.list()[0], 115200);
port.bufferUntil(10);
}
void draw() {
background(100);
if (0 < port.available()) { // ako ima podataka za čitanje
serialEvent(port);
} else {
println("Nije dostupan port");
}
stroke(0);
textSize(20);
text("Dogadjaj: " + dogadjaj, width / 2, 150);
}
void serialEvent(Serial port) {
String inData = port.readString();
if (inData != null && inData.charAt(0) == 'l') {
k = -2;
dogadjaj = "titleLeft";
} else if (inData != null && inData.charAt(0) == 'd') {
k = +2;
dogadjaj = "titleRight";
} else if (inData != null && inData.charAt(0) == 'r') {
reset();
dogadjaj = "shake";
}
}
void reset() {
}

Da bi kreirali port, potrebna nam je klasa Serial, koja se nalazi u istoimenoj biblioteci, a koju treba importovati da bi mogli da je koristimo.
Promenljiva k inicijalizovana na nulu će u stvari biti promena položaja po svakom pozivu draw metode(20 puta u sekundi), dakle brzina pomeranja pravougaonika.
Promenljiva događaj je tekst događaja koji ćemo ispisati na prozoru u zavisnosti od događaja koji je proizveo mikrobit.
Unutar setup metode se kreira veličina prozora na 600*600px a zatim se kreira port, kao objekat.
Serial.list je lista dostupnih portova, pa vidimo da je kreiran port na osnovu prvog elementa u listi.
Funkcija bufferUntil(10) daje naznaku da će se čitati samo jedna linija teksta, tj. dok se ne naiđe na karakter sa kodom "10", a to je karakter za kraj reda.
Unutar draw metode posle postavljanja pozadine proverava se da li je neki port dostupan i ako jeste poziva se funkcija serialEvent(Serial port).
U ovoj funkciji se koristi selekcija koja ispituje prvi karakter u pročitanom stringu sa porta i ako je to "l"(titleLeft) onda se vrednost brzine k postavlja na negativnu vrednost u ovom primeru k=-2. Ako je to "d"(titleRight) onda je k=2.
Tekst na ekranu se ispisuje sa processing-ovom funkcijom text(), koja kao prvi parametar prihvata tekst koji se ispisuje,a druga dva se odnose na položaj u xOy koordinatnom sistemu. Nastavak koda možete videti na sledećim slikama:
Kod sa slike 9: Igrica Pong- Kod u processingu 1 deo
import processing.serial.*;
Serial port;
float vx = 0; // brzina pravougaonika (reketa)
String dogadjaj = "Nema događaja";
float x = 50; // položaj pravougaonika
float y = 450;
float xL; // položaj loptice
float yL = 0;
float rL = 25;
float vL = 0; // brzina loptice
boolean dole = true;
boolean udar = false;
void setup() {
size(600, 600);
port = new Serial(this, Serial.list()[0], 115200);
port.bufferUntil(10);
kreirajLopticu();
}

Ovde vidimo da su dodate promenljive:
vx- brzina pravougaonika(umesto k),
x,y - položaj gornjeg levog ugla pravougaonika,
xL,yL -položaj kvadrata u koji je upisana lopta(položaj lopte)
rL- poluprečnik lopte
vL- brzina lopte u y pravcu
udar, dole - logičke promenljive koje govore da li lopta ide na dole(true) ili ne, i druga da li se odbila o pravougaonik ili ne.
Unutar setup metode je dodat poziv metode kreirajLopticu() koja treba da u gornjem delu kreira novu lopticu ispočetka.
Kod sa slike 10: Igrica Pong- Kod u processingu 2 deo
void kreirajLopticu() {
xL = 100 + random(400);
yL = 50;
vL = 2;
dole = true;
udar = false;
}
void draw() {
background(100);
if (0 < port.available()) { // ako ima podataka za čitanje
serialEvent(port);
} else {
println("Nije dostupan port");
}
stroke(0);
textSize(20);
text("Dogadjaj: " + dogadjaj, width / 2, 150);

Ovde dalje nema novih izmena, tj. ovaj deo koda je ranije već objašnjen.
Kod sa slike 11: Igrica Pong- Kod u processingu 3 deo
/* Pravougaonik */
fill(color(0, 0, 200));
rect(x, y, 100, 25);
/* Loptica */
fill(color(150, 0, 0));
ellipse(xL, yL, rL, rL);
/* Kad pravougaonik dođe do desne ili leve ivice */
if (x > width - 100) {
vx = vx * (-1);
} else if (x < 0) {
vx = vx * (-1);
}
/* Pomeranje pravougaonika */
x = x + vx;
/* Kretanje loptice */
yL += vL;

U draw metodi, posle ispisivanja teksta, crta se prvo pravougaonik plave boje, a zatim i loptica u crvenoj boji, na svojim trenutnim x i y koordinatama.
Posle toga se proveravaju granični položaji za pravougaonik, tj. da li je otišao izvan vidnog polja prozora aplikacije. U slučaju da jeste, menja se pravac brzine pravougaonika.
Dalje se može videti kod koji povećava položaje pravougaonika u x i lopte u y pravcu za vrednost odgovarajućih brzina vx, odnosno vL.
Kod sa slike 12: Igrica Pong- Kod u processingu 4 deo
/* Dostignut nivo pravougaonika */
if (yL > y - rL / 2) {
if (xL >= x && xL <= x + 100) {
vL *= -1; // menja smer
udar = true;
dole = false;
}
}
/* Kad izađe van opsega pri dnu */
if (dole && yL > height) {
udar = false;
kreirajLopticu();
}
/* Kad izađe van opsega pri vrhu */
if (!dole && yL < -2) {
kreirajLopticu();
}
}

U nastavku koda se može videti kako se proverava da li se loptica odbila o gornju površinu pravougaonika, tako što se prvo proverava uslov da je y koordinata lopte dostigla nivo gornje površine pravougaonika. Ako jeste, treba dalje razlikovati 2 slučaja.
Prvi, da je x koordinata okvira lopte između leve i desne površine pravougaonika i ako jeste, došlo je do udara i lopta se odbija, tj. menja smer brzine na više.
Drugi, ako uslov za x koordinate nije zadovoljen, došlo je do promašaja i lopta nastavlja da se kreće sve dok ne dođe do donje ivice okvira, kada nestaje i kreira se nova loptica.
Kod sa slike 13: Igrica Pong- Kod u processingu 5 deo
void serialEvent(Serial port) {
String inData = port.readString();
if (inData != null && inData.charAt(0) == 'l') {
vx = -2;
dogadjaj = "titleLeft";
} else if (inData != null && inData.charAt(0) == 'd') {
vx = +2;
dogadjaj = "titleRight";
} else if (inData != null && inData.charAt(0) == 'r') {
reset();
dogadjaj = "shake";
}
}
void reset() {
}
Ceo program u jednom komadu (5 slike spojene)
import processing.serial.*;
Serial port;
float vx = 0; // brzina pravougaonika (reketa)
String dogadjaj = "Nema događaja";
float x = 50; // položaj pravougaonika
float y = 450;
float xL; // položaj loptice
float yL = 0;
float rL = 25;
float vL = 0; // brzina loptice
boolean dole = true;
boolean udar = false;
void setup() {
size(600, 600);
port = new Serial(this, Serial.list()[0], 115200);
port.bufferUntil(10);
kreirajLopticu();
}
void kreirajLopticu() {
xL = 100 + random(400);
yL = 50;
vL = 2;
dole = true;
udar = false;
}
void draw() {
background(100);
if (0 < port.available()) { // ako ima podataka za čitanje
serialEvent(port);
} else {
println("Nije dostupan port");
}
stroke(0);
textSize(20);
text("Dogadjaj: " + dogadjaj, width / 2, 150);
/* Pravougaonik */
fill(color(0, 0, 200));
rect(x, y, 100, 25);
/* Loptica */
fill(color(150, 0, 0));
ellipse(xL, yL, rL, rL);
/* Kad pravougaonik dođe do desne ili leve ivice */
if (x > width - 100) {
vx = vx * (-1);
} else if (x < 0) {
vx = vx * (-1);
}
/* Pomeranje pravougaonika */
x = x + vx;
/* Kretanje loptice */
yL += vL;
/* Dostignut nivo pravougaonika */
if (yL > y - rL / 2) {
if (xL >= x && xL <= x + 100) {
vL *= -1; // menja smer
udar = true;
dole = false;
}
}
/* Kad izađe van opsega pri dnu */
if (dole && yL > height) {
udar = false;
kreirajLopticu();
}
/* Kad izađe van opsega pri vrhu */
if (!dole && yL < -2) {
kreirajLopticu();
}
}
void serialEvent(Serial port) {
String inData = port.readString();
if (inData != null && inData.charAt(0) == 'l') {
vx = -2;
dogadjaj = "titleLeft";
} else if (inData != null && inData.charAt(0) == 'd') {
vx = +2;
dogadjaj = "titleRight";
} else if (inData != null && inData.charAt(0) == 'r') {
reset();
dogadjaj = "shake";
}
}
void reset() {
}

Ovde vidimo još dva uslova: Kada lopta izađe iz vidljivog dela prozora po vertikalnom pravcu, u donjem i u gornjem delu. U oba slučaja se kreira nova loptica.
Na kraju vidimo metodu serialEvent() koja je ranije već objašnjena. Posle pokretanja videćemo:

Igrica je dovršena u drugom delu tj u videu broj 3. Pogledajte u nastavku:
Proveri znanje
Otvori kviz
Kviz: Processing i micro:bit
1. Kako micro:bit šalje podatke programu u Processing-u?
2. Šta micro:bit može da meri da bi upravljao igrom?
3. Šta se u igri Pong pomera na osnovu podataka sa micro:bit-a?
4. Umesto micro:bit-a, kretanje se može vezati i za:
| Prethodno |< Osnove processinga sa Javom |
Sledeće Vektori u Processing-u >| |
MIKROBIT I NJEGOVA UPOTREBA U PROCESSING APLIKACIJAMA
Pomeranje grafičkih objekata, koje iscrtavamo u nekoj aplikaciji u Processing-u možemo vezati za događaje miša i tastature. Npr. Pomeranje možemo ostvariti pritiskom na tastere sa strelicama, ili na neki drugi taster koji mi odredimo. Umesto toga, možemo upotrebiti i mikrokontroler, npr. Micro:bit, tako što pomoću njega merimo npr. ubrzanje, ili proizvedemo neki događaj, a onda prenesemo tu informaciju preko serijskog porta na računar. Tu informaciju dalje, koristi aplikacija u Processing-u, koja je čita takođe sa serijskog porta. Upoznajmo se u nastavku o Mikro:bit-u i pogledajmo primere u Processing-u koji koriste jedan ili više mikro:bit-ova.Microbit uređaj
Mikrobit je ručni programabalni mikro računar. Sastoji se od poločice, procesora, senzora, dioda, ulazno-izlaznog serijskog porta, tastera. Može se povezati sa Processingom koji je pogodan za kreiranje vizuelnih aplikacija. Pogodan je za učenje dece programiranju.Povezivanjem mikrobita i processinga mogu se kreirati zanimljive aplikacije, jer se već bogata biblioteka pogodna za kreiranje animacija i simulacija iz fizike, može obogatiti merenjem temperature, ubrzanja, jačine svetlosti, udaljenosti do predmeta itd. korišćenjem mikrobita.
Može se programirati pomoću programskih jezika scratch, javascript-a ili python-a. Evo nekih preporuka :
- Za programiranje u scratch-u ili javascript-u koristiti Majkrosoftov MakeCode: https://makecode.microbit.org/
- Za programiranje u pajtonu instalirati radno okruženje Mju: https://codewith.mu/en/download
- Na sledećim slikama se može videti prednja i zadnja strana mikrobit-a
Delovi mikrobita
Delovi mikrobita:- Prednja ploča
- Zadnja ploča
- Ekran sa 25 LED dioda
- Tasteri, se nalaze sa leve i desne strane ekrana A i B. pritisak na taster se registruje od strane microbita. Postoji i taster za reset, tj. za restartovanje programa, odnosno njegovo ponovno učitavanje
- Kompas, određuje položaj (stranu sveta) i može da meri jačinu magnetnog polja
- Akcelerometar. Detektuje pokrete mikrobita
- Senzor za temperaturu. Ovaj senzor meri temperaturu mikrobit-ovog procesora.
- Pinovi. Na ivici mikrobita nalazi se 25 izvoda, 5 velikih i 20 malih. Preko ovih pinova se mogu povezivati razni dodatni uređaji kao i senzori.
- Bluetooth. Ova antena kojom je opremljen mikrobit služi za bežično povezivanje sa drugim uređajima. ovo povezivanje se može ostvariti sa drugim bluetooth uređajima, sa računarom, mobilnim telefonom ili nekim drugim uređajem.
Mikrobit radionice
Mikrobit radionice su sastavni deo kursa kreativnog programiranja koji organizuje Regionalni Centar za Talente "Mihajlo Pupin" u Pančevu:
Kreativno programiranje
Igrica pong
Stara igrica pong koja ostvaruje kretanje pravougaonika u horizontalnoj ravni levo-desno i loptice koja se kreće verikalno i odbija o pravougaonik i zidove može se napraviti u processingu i povezati sa mikrobitom. Sledeći video pokazuje kako to može da se uradi:
Prvi deo zadatka je da prihvatimo tekst sa serijskog porta i da u zavisnosti da li je "l", "d" ili "r", prepišemo tekst na prozor aplikacije u processingu: Kod koji radi ovo možete videti u nastavku:
Promenljiva k inicijalizovana na nulu će u stvari biti promena položaja po svakom pozivu draw metode(20 puta u sekundi), dakle brzina pomeranja pravougaonika.
Promenljiva događaj je tekst događaja koji ćemo ispisati na prozoru u zavisnosti od događaja koji je proizveo mikrobit.
Unutar setup metode se kreira veličina prozora na 600*600px a zatim se kreira port, kao objekat.
Serial.list je lista dostupnih portova, pa vidimo da je kreiran port na osnovu prvog elementa u listi.
Funkcija bufferUntil(10) daje naznaku da će se čitati samo jedna linija teksta, tj. dok se ne naiđe na karakter sa kodom "10", a to je karakter za kraj reda.
Unutar draw metode posle postavljanja pozadine proverava se da li je neki port dostupan i ako jeste poziva se funkcija serialEvent(Serial port).
U ovoj funkciji se koristi selekcija koja ispituje prvi karakter u pročitanom stringu sa porta i ako je to "l"(titleLeft) onda se vrednost brzine k postavlja na negativnu vrednost u ovom primeru k=-2. Ako je to "d"(titleRight) onda je k=2.
Tekst na ekranu se ispisuje sa processing-ovom funkcijom text(), koja kao prvi parametar prihvata tekst koji se ispisuje,a druga dva se odnose na položaj u xOy koordinatnom sistemu. Nastavak koda možete videti na sledećim slikama:
vx- brzina pravougaonika(umesto k),
x,y - položaj gornjeg levog ugla pravougaonika,
xL,yL -položaj kvadrata u koji je upisana lopta(položaj lopte)
rL- poluprečnik lopte
vL- brzina lopte u y pravcu
udar, dole - logičke promenljive koje govore da li lopta ide na dole(true) ili ne, i druga da li se odbila o pravougaonik ili ne.
Unutar setup metode je dodat poziv metode kreirajLopticu() koja treba da u gornjem delu kreira novu lopticu ispočetka.
Posle toga se proveravaju granični položaji za pravougaonik, tj. da li je otišao izvan vidnog polja prozora aplikacije. U slučaju da jeste, menja se pravac brzine pravougaonika.
Dalje se može videti kod koji povećava položaje pravougaonika u x i lopte u y pravcu za vrednost odgovarajućih brzina vx, odnosno vL.
Prvi, da je x koordinata okvira lopte između leve i desne površine pravougaonika i ako jeste, došlo je do udara i lopta se odbija, tj. menja smer brzine na više.
Drugi, ako uslov za x koordinate nije zadovoljen, došlo je do promašaja i lopta nastavlja da se kreće sve dok ne dođe do donje ivice okvira, kada nestaje i kreira se nova loptica.
Na kraju vidimo metodu serialEvent() koja je ranije već objašnjena. Posle pokretanja videćemo:
| Prethodno |< Osnove processinga sa Javom |
Sledeće Vektori u Processing-u >| |
