Curs BGT - Desfasurare

Diverse limbaje, programare, scripting, coduri, unelte specifice etc.
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Acum e un cronometru in regula, asa se evolueaza, construind treptat.

Pentru a mai clarifica cate ceva din ce am invatat cursurile trecute, mentionez ca puteam sari peste variabilele intermediare de tip string care preluau valorile scrise in input_box().
Am spus ca o functie poate primi ca parametru o alta functie.
Asadar, putem pune functia input_box() ca parametru de tip string al functiei string_to_number(), astfel returnandu-se per ansamblu un integer.
Pentru valoarea lui max, numarul limita de secunde, in loc de doua randuri, reformulam intr-un singur rand:
int max=string_to_number(input_box("Limita", "Scrie numarul de secunde:"));

Dupa cum spuneam, functiile se executa din adancime spre suprafata, de la dreapta la stanga. Deci, inainte se intampla functia input_box(), apoi ea returneaza string-ul scris in edit, acest string este parametrul functiei string_to_number() care returneaza unei variabile de tip int valoarea int rezultata in urma convertirii.
Ne auzim maine la un nou curs, despre array-uri.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

BGT Curs 8, Arrays - partea 1

Mesaj de Manu »

Marti, 15 mai 2012 ne-am intalnit pentru a opta oara in cadrul cursului de BGT si am vorbit despre Array-urile cu o singura dimensiune.

Un array poate fi considerat un set de variabile de acelasi tip si cu acelasi nume, referirea la una dintre ele facandu-se printr-un index, un numar de ordine.

Avem de foarte multe ori nevoie de mai multe variabile care sa aiba valori diferite, dar de acelasi tip. Sa zicem ca vrem 5 variabile care sa contina 5 prenume diferite.
Desigur ca am putea sa cream separat cele 5 variabile in felul urmator:
string prenume1="Ion", prenume2="Gheorghe", prenume3="Cristian", prenume4="Vasile", prenume5="Nicolae";
Vom vedea ca declarand separat variabilele duce la ineficienta cand lucram apoi in cod cu ele.

Pentru a declara un array, trebuie sa punem dupa tip, lipit de acesta, paranteza dreapta deschisa si paranteza dreapta inchisa:
string[], int[], float[], double[] sau bool[].

Pentru exemplul de mai sus, cel cu prenumele, unde stim exact ce valori sunt continute, putem imediat dupa ce scriem numele array-ului, dupa un egal, sa scriem intre acolade, cu virgula intre ele, cele 5 valori intre ghilimele (acestea fiind string-uri).

Asadar, cream un array cu 5 variabile, un array de tip string numit prenume:

string[] prenume={"Ion", "Gheorghe", "Cristian", "Vasile", "Nicolae"};

Din acest moment avem array-ul prenume cu o marime de 5.
Pentru a ne referi la una dintre variabilele acestui array, punem intre paranteze drepte, lipit de nume, numarul de ordine.
Numarul de ordine, indexul array-ului este 0 based, asadar "Ion" este la indexul 0, iar "Nicolae" este la indexul 4.

De exemplu, pentru a afisa intr-un alert "Ion" la titlul ferestrei si "Vasile" in corpul acesteia, scriem:

alert(prenume[0], prenume[3]);

Sa presupunem ca acum am avea nevoie ca JAWS sa ne spuna cele 5 prenume.

Daca nu am avea array-uri si am fi creat 5 variabile diferite: prenume1, prenume2, prenume3, prenume4, prenume5, ar trebui sa scriem 5 randuri diferite in care am repeta aceeasi functie: screen_reader_speak_interrupt():

screen_reader_speak_interrupt(1, prenume1);
wait(2000);
screen_reader_speak_interrupt(1, prenume2);
wait(2000);
screen_reader_speak_interrupt(1, prenume3);
wait(2000);
screen_reader_speak_interrupt(1, prenume4);
wait(2000);
screen_reader_speak_interrupt(1, prenume5);
wait(2000);

Trebuie sa punem si un wait(2000), o asteptare de doua secunde, altfel nu am auzi decat "Nicolae", celelalte anunturi fiind intrerupte, astfel pana la urma am ajuns la 10 randuri.

Cine stie sa utilizeze bucla for, poate foarte usor sa faca intr-un cod scurt ca cele 5 prenume sa fie spuse de JAWS din array:

for(int x=0, x<5, x++)
{
screen_reader_speak_interrupt(1, prenume[x]);
wait(2000);
}

Blocul de cod se repeta de 5 ori, x crescand cu cate 1, fapt care ne face posibila referirea pe rand la toate variabilele array-ului prenume.

In primul mod de verbalizare a celor 5 nume avem nevoie de 10 randuri pentru vorbirea propriu-zisa a tuturor prenumelor, in cel de-al doilea mod avem doar doua randuri, plus for-ul.
Daca am vrea sa auzim si un beep inaintea fiecarui nume, automat ar trebui la primul mod sa punem de 5 ori aceeasi functie, pe cand cu for-ul si array punem in plus doar un rand ca prima instructiune in blocul de cod al for-ului.


Mai putem defini array-uri fara sa le incarcam direct cu valori, doar specificand tipul, numele si intre paranteze rotunde numarul de variabile care sa fie continute, urmand ca la runtime sa fie modificate dupa caz valorile acestora.

De exemplu pentru a crea un array numit numere cu 10 variabile de tip int, scriem:

int[] numere(10);

Din acest moment, putem sa ne referim la oricare dintre cele 10 variabile scriind:

numere[0] - pentru prima,
numere[1] - pentru a doua,
...
numere[9] - pentru a zecea etc.

Daca am vrea sa facem ca la indexul 0 al array-ului numere sa fie valoarea 17, atribuim valoarea precum la o simpla variabila, scriind:
numere[0]=17;

Daca vrem ca a zecea variabila a array-ului sa aiba valoarea 1001, scriem:
numere[9]=1001;

Daca vrem ca toate cele 10 variabile sa aiba valoarea 5, nu scriem 10 randuri in care sa spunem:
numere[0]=5;
numere[1]=5,
...
numere[9]=5;
ar fi enervant si ineficient.

Folosim for-ul:
for(int x=0; x<10; x++)
{
numere[x]=5;
}


Exista tot felul de metode pentru a redimensiona un array, pentru a-i adauga variabile, pentru a sorta valorile etc, dar ramane sa detaliem cand vom trece de cursul in care invatam clasele cu proprietatile si metodele lor.


Tot in cadrul acestei intalniri, a opta, am facut o mica aplicatie practica.
Am creat array-ul numere cu o dimensiune de 10, iar printre valorile acestui array plimbandu-ne ca pe un drum cu sagetile stanga - dreapta, auzim JAWS spunand "Mergi"sau "Sari".
Ne putem imagina deplasarea cu sagetile pe un drum care e neted unde valoarea variabilei este 0, si prag intr-un singur loc unde valoarea este 1.

Pentru aceasta am facut intai ca toate valorile sa fie 0, iar apoi am ales una dintre ele random sa fie 1.

Mai jos e tot codul comentat:

Cod: Selectaţi tot

void main()
{
// Cream o fereastra cu un titlu pentru asa-zisul joculet:
show_game_window("Drum de 10 pasi cu un singur prag");

// Punem o functie din BGT care face ca cu JAWS pornit sa fie utilizabile sagetile:
install_keyhook();

// Declaram array-ul numere de tip int cu o marime de 10:
int[] numere(10);

// Nivelam terenul facand ca toate cele 10 valori sa fie 0:
for(int x=0; x<10; x++)
{
numere[x]=0;
}

// Atribuim unei variabile int y o valoare random intre 0 si 9:
int y=random(0, 9);

// La index-ul y, deci la locul aleatoriu determinat mai sus, punem valoarea 1 pentru prag:
numere[y]=1;

// Cream o variabila int z care sa se schimbe la sageti, astfel incat sa ne plimbam pe drumulet:
int z=0;

// Cream while-ul principal care sa fie activ atata vreme cat nu apasam q:
while(!key_pressed(KEY_Q))
 {
// daca se apasa sageata dreapta:
if(key_pressed(KEY_RIGHT))
{
// daca nu e mai mare de 9, z sa creasca cu cate 1:
if(z<9) z++;

// acum in functie de valoarea aflata la indexul z al array-ului, JAWS spune "Mergi" sau "Sari":
if(numere[z]==00) screen_reader_speak_interrupt(1, "Mergi");
else screen_reader_speak_interrupt(1, "Sari");
}

// Daca se apasa sageata stanga, deplasarea in sens invers:
if(key_pressed(KEY_LEFT))
{
// Daca z e mai mare decat 0 sa scada cu cate 1:
if(z>0) z--;

// Acum sa spuna din nou "Mergi" sau "Sari" in functie de ceea ce se gaseste pe locatie:
if(numere[z]==0) screen_reader_speak_interrupt(1, "Mergi");
else screen_reader_speak_interrupt(1, "Sari");
}

// Daca se apasa tasta F4 sa auzim locul pe care ne aflam:
if(key_pressed(KEY_F4))
{
	screen_reader_speak_interrupt(1, ""+z);
}

wait(5); // asteptare de 5 milisecunde pentru procesor.
}
exit();
}
De observat ca am fost atenti ca valoarea lui z sa nu iasa din marimea array-ului, fapt care ar face sa apara o eroare "Runtime error, out of bounds", iar programul s-ar inchide fortat.
Un alt lucru de observat este ca daca la un if avem doar o singura instructiune, aceasta poate sta si fara acoladele care ar delimita blocul de cod aferent. Aceeasi regula e valabila si pentru while si for.


Avand in vedere ca am scris rezumatul destul de tarziu si pana marti, 22 mai, cand ne intalnim pentru a noua oara este putin timp, nu mai dau nici o tema.
Data viitoare continuam tot cu array-urile si vom vorbi despre cele bidimensionale si despre string-uri ca array.


Imprimarea intalnirii de marti 15 mai 2012, Array-uri (partea 1), este la link-ul urmator:
Download Fisier MP3 08._Curs_BGT_-_Arrays-Partea1.mp3 (55,9 MB)
Ultima oară modificat 02 Iul 2012, 16:26 de către Manu, modificat 1 dată în total.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Curs 9, Arrays partea 2

Mesaj de Manu »

Marti, 22 mai 2012, ne-am intalnit pentru a noua lectie de programare in BGT.

Am continuat cu array-urile. Am vorbit despre stringurile ca array si despre array-urile cu doua dimensiuni.


Orice string poate fi considerat un array de caractere, astfel incat ne putem referi la unul dintre caracterele ce il compun printr-un index scris intre paranteze drepte.

Avand de exemplu variabila numita text care contine stringul "calculator", scriind urmatorul rand putem afisa litera "l" intr-un alert():

Cod: Selectaţi tot

alert("Salut!", text[2]);
Exista functia string_len(), al carei parametru de tip string este masurat ca lungime, returnand un int cu valoarea acesteia.
Astfel cu for se poate crea un mic script care sa spuna pe litere un text:

Cod: Selectaţi tot

void main()
{
// Cream o variabila de tip string cu numele textul, careia ii atribuim o valoare dintr-un input_box:
string textul=input_box("Salut!", "Scrie ceva:");
// Cream un for in care sa creasca valoarea variabilei x de la 0 la lungimea textului minus 1:
for(int x=0; x<string_len(textul); x++)
{
// Anuntam caracterul la care s-a ajuns, referindu-ne la el prin indexul x:
screen_reader_speak(1, textul[x]);
}
exit();
}

In a doua parte a intalnirii ne-am ocupat de array-urile bidimensionale.
Un array poate contine alte array-uri in loc de simple variabile.
Daca avem de exemplu un array cu lungime de 8:

Cod: Selectaţi tot

string[] agenda(8);
Acesta ar putea contine, sa zicem cate un array de cate 3 itemi la fiecare index. Presupunem ca avem nevoie ca la fiecare index al array-ului in prima dimensiune sa fie cate un array de 3 in care sa fie la [0] numele, la [1] adresa, iar la [2] numarul de telefon.

Pentru a declara un array bidimensional, trebuie sa scriem de doua ori paranteza dreapta deschisa si paranteza dreapta inchisa.\

Cod: Selectaţi tot

string[][] agenda;
In acest moment nu este cunoscuta marimea nici unei dimensiuni.

Trebuie mai intai sa redimensionam array-ul la prima lui dimensiune. Folosim pentru aceasta metoda resize(). Inca nu am lucrat cu metode, dar vedem cum se aplica o metoda cu semnul "." (punct). Vom invata pe larg lucrul cu metode ale claselor in cursul viitor.

Cod: Selectaţi tot

string[][] agenda;
agenda.resize(8);
Randul de mai sus a facut ca prima dimensiune sa fie cu o marime de 8, deci de la index [0] la index [7].

Trebuie acum sa redimensionam fiecare item din array la un array cu marime de 3.

Pentru a nu scrie pe rand:

Cod: Selectaţi tot

agenda[0].resize(3);
agenda[1].resize(3);
// ...
agenda[7].resize(3);
ne folosim de un for:

Cod: Selectaţi tot

for(int x=0; x<8; x++)
{
agenda[x].resize(3);
}
Avand astfel un array numit agenda de 8 pe 3, putem scrie primul nume:

Cod: Selectaţi tot

agenda[0][0]="Vasile";
// Pentru numarul de telefon al lui Vasile:
agenda[0][2]="074020xxxx";
Asadar, numarul dintre primele paranteze drepte este index-ul primei dimensiuni a array-ului, iar numarul dintre parantezele drepte ce urmeaza reprezinta indexul celei de-a doua dimensiuni.


Ca aplicatie practica, am "desenat" si o tabla simpla de sah.
Am creat un array bidimensional de 9 pe 9, in care de la 1 la 8 in ambele dimensiuni sa fie patratelele. La index [0] nu se gaseste nimic. Am ales aceasta cale pentru a ne fi apoi mai usor cand ne referim la patratica din colt stanga jos din perspectiva albului, unde in situatie initiala exista o tura alba, sa scriem [1][1], pentru regina alba - [4][1].

Mai jos este codul creat insotit de cateva comentarii precedate de doua slash-uri:

Cod: Selectaţi tot

// Declaram un array bidimensional cu numele tabla:
string[][] tabla;

void main()
{
// O fereastra:
show_game_window("Tabla de sah");

// Facem sa mearga sagetile cu JAWS pornit:
install_keyhook();

// Redimensionam array-ul la primul nivel, cel care va fi determinat de coordonata x, de la stanga la dreapta:
tabla.resize(9);

// Redimensionam al doilea nivel la 9, cel la care ne vom referi prin y, coordonatele sus - jos:
for(int x=0; x<9; x++)
{
tabla[x].resize(9);
}

// Acum punem stringul "Gol" pe fiecare patratica, practic o lustruim:
for(int x=0; x<9; x++)
{
for(int y=0; y<9; y++)
{
tabla[x][y]="Gol";
}
}

// O functie pentru aranjarea tablei, definita de noi dupa void main():
umplere();

// Cream doua variabile, x si y pentru a ne putea referi in orice moment la un punct pe tabla:
int x=1, y=1;

// While principal, activ pana la apasarea tastei q:
while(!key_pressed(KEY_Q))
{
// Apasarea sagetii dreapta, x este incrementat cu 1:
if(key_pressed(KEY_RIGHT))
{
if(x<8)
{
  x++;
	screen_reader_speak_interrupt(1, tabla[x][y]);
} 
else	screen_reader_speak_interrupt(1, "Margine dreapta");        
}

// Sageata stanga, x este decrementat cu 1:
if(key_pressed(KEY_LEFT))
{
if(x>1)
{
  x--;
	screen_reader_speak_interrupt(1, tabla[x][y]);
}
else	screen_reader_speak_interrupt(1, "Margine stanga");
}

// Sageata in sus, y este incrementat cu 1:
if(key_pressed(KEY_UP))
{
if(y<8)
{
  y++;
	screen_reader_speak_interrupt(1, tabla[x][y]);
}
else	screen_reader_speak_interrupt(1,"margine sus");                
}

// Sageata in jos, y este decrementat cu 1:
if(key_pressed(KEY_DOWN))
{
if(y>1)
{
  y--;
	screen_reader_speak_interrupt(1, tabla[x][y]);
}
else	screen_reader_speak_interrupt(1, "Margine jos");
}

wait(5); // asteptarea de rigoare pentru procesor.
}

exit();
}

// Functie pentru aranjarea tablei:
void umplere()
{
// Aranjam pionii cu un for, acestia fiind in sir la y==2 si y==7:
for(int x=1; x<9; x++)
{
tabla[x][2]="Pion alb";
tabla[x][7]="Pion negru";
}

// Acum scriem cate un rand pentru fiecare piesa din cele 16 nearanjate:
tabla[1][1]="Turn alb";
tabla[2][1]="Cal alb";
tabla[3][1]="Nebun alb";
// ... de completat patratelele lipsa!
tabla[8][1]="Turn negru";
// ... de completat patratelele lipsa!
tabla[1][8]="Turn negru";
tabla[2][8]="Cal negru";
// ... de completat patratelele lipsa!
tabla[8][8]="Turn negru";
}

A se retine ca nu putem avea in acelasi array doua tipuri de valori. Un array, fie el cu o dimensiune sau mai multe, trebuie sa fie declarat cu un tip si poate contine apoi doar acel tip.


Daca cineva mai are timp si nervi pentru o tema, sa incerce sa adauge la tabla de sah creata la curs:
1. Daca se apasa tasta delete (KEY_DELETE), piesa pe care ne aflam sa fie scoasa de pe tabla, iar in acel loc sa apara "Gol".
2. Daca se apasa tasta F5 (KEY_F5), tabla sa fie rearanjata la pozitia initiala. Pentru aceasta cerinta este necesar ca functia umplere() creata de noi sa stie sa aranjeze intreaga tabla, asadar ca cerinta 0 ar fi finalizarea functiei umplere().

Daca pune cineva o rezolvare pe forum, cred ca ar fi bine sa mentioneze doar codul adaugat spunand locul in care a fost scris in codul de la curs.


Imprimarea intalnirii de marti 22 mai 2012, Array-uri (partea 2), este la link-ul urmator:
Download Fisier MP3 09._Curs_BGT_-_Arrays-Partea2.mp3 (91,0 MB)
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Eddy
Caporal
Mesaje: 11
Membru din: 06 Apr 2010, 06:09
Localitate: Bucuresti

curs 9 tema

Mesaj de Eddy »

1
if pentru scoaterea piesei de pe tabla
codul este scris in while-ul principal

Cod: Selectaţi tot

if(key_pressed(KEY_DELETE))
{
tabla[x][y]="gol";
screen_reader_speak_interrupt(1, tabla[x][y]);
}
// sfarsit cod
2
if pentru aranjarea tablei la pozitia initiala
codul va fi scris in while-ul principal

Cod: Selectaţi tot

if(key_pressed(KEY_F5))
{
umplere();
screen_reader_speak_interrupt(1, "Tabla la pozitie initiala");
}
// sfarsit cod
3
aranjarea pieselor pe tabla
codul va fi scris in functia de tip void umplere() dupa acolada for-ului

Cod: Selectaţi tot

// piese albe
tabla[1][1]="tura alba";
tabla[2][1]="cal alb";
tabla[]3[1]="nebun alb";
tabla[4][1]="regina alba";
tabla[5][1]"rege alb";
tabla[6][1]=nebun alb";
tabla[7][1]="cal alb";
tabla[8][1]="tura alba";

//piese negre
tabla[1][8]="tura neagra";
tabla[2][8]="cal negru";
tabla[3][8]="nebun negru";
tabla[4][8]="regina neagra";
tabla[5][8]="rege negru";
tabla[6][8]="nebun negru";
tabla[7][8]="cal negru";
tabla[8][8]="tura neagra";
// sfarsit cod
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Rezolvarile sunt corecte.
E bine ca ai scris si randurile pentru piesele grele, asa le poate lua si altcineva sa nu mai scrie manual.
Am putea umple tabla si mai sintetic, dar... deocamdata ne oprim la metoda scrierii rand cu rand a celor 16 piese grele pentru a se clarifica bine orientarea prin array-ul bidimensional.
Dupa ce este clar lucrul cu for-urile si array-urile, devine usor sa gasim diversi algoritmi pentru a umple o tabla de sah mai eficient, astfel incat un nume de piesa sa poata fi usor schimbat, bunaoara cuvantul "Cal" sa fie repede inlocuit cu "Fugar". Sintetizarea modului de umplere a tablei ar fi util si in momentul in care se doreste traducerea jocului in mai multe limbi.
Desigur ca din start o tabla reprezentata printr-un array de tip string nu prea este eficienta, eventual considerand-o doar pentru afisarea audio, fapt pe care l-am si facut in esenta (am "desenat"), pentru lucrul propriu-zis cu mutarile si toate celelalte ar trebui sa avem si una de tip int, poate tridimensionala pentru a surpinde si culoarea, dar nu e cazul sa intram in amanunte.

Pentru maine, ar fi bine sa avem toti aceasta tabla de sah, poate ii vom adauga si ceva sunete pentru lovirea de margine sau pentru golirea unui camp.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Anunt si aici ca intalnirea de ieri s-a amanat pentru martia viitoare.
Va fi timp astfel pentru consolidarea cunostintelor, a se insista mai ales pe for si array-uri, acestea fiind necunoscute anterior de catre niciun participant.
Data viitoare continuam cu utilizarea claselor, urmand ca in ultima intalnire in care invatam sintaxa sa le cream chiar noi.
Urmeaza apoi cateva intalniri pentru aplicatii practice.

Daca mai sunt nelamuriri, am mai putea discuta aici.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Curs 10, Clase Built-In

Mesaj de Manu »

Marti, 5 iunie 2012 ne-am intalnit pentru a zecea lectie in cadrul cursului de programare in BGT.

Am invatat cum se pot utiliza in BGT clasele deja create.

O clasa, un obiect este ca o variabila care contine la randul ei alte variabile si functii.

Avem de exemplu clasa sound, care contine variabile, denumite de acum inainte proprietati, precum: volume, pitch, pan; tot in legatura cu sound avem functii, numite de acum metode, precum: stream(), load(), play(), play_looped(), stop(), close() etc.

Asadar, un obiect poate avea proprietati si metode, primele fiind de fapt variabile, cele din urma fiind functii.

Instantiem un obiect la fel ca pe oricare variabila de un anume tip.
Avand clasa sound, putem instantia un obiect de tip sound scriind:
sound muzica;
Din momentul instantierii, ne putem referi la proprietati si metode scriind numele obiectului instantiat si proprietatea sau metoda cu punct intre, precum in exemplul:
muzica.volume=-100;
randul de mai sus inseamna ca a fost dat la minim volumul obiectului numit muzica, deci a fost modificata proprietatea volume.

muzica.pan=100;
randul de mai sus ar face ca sunetul atribuit obiectului de tip sound numit muzica sa se auda doar in difuzorul din dreapta, asadar am schimbat proprietatea pan.

int volum_actual=muzica.volume;
randul de mai sus atribuie valoarea volumului actual unei variabile de tip int.

Exemple pentru metode:
muzica.stream("C:\\windows\\media\\fundal.ogg");
randul de cod anterior ar face ca obiectului de tip sound numit muzica sa i se atribuie un fisier de sunet numit "fundal.ogg" aflat pe partitia C, in folderul Media din folderul Windows. Metoda stream face ca sunetul sa fie preluat de pe hard treptat, nu il incarca pe tot in rami.

muzica.load("C:\\windows\\media\\fundal.ogg");
aplicand metoda load(), intregul fisier de sunet este incarcat in rami.

muzica.play_looped()
randul anterior face ca sunetul atribuit obiectului muzica prin stream() sau load() sa fie redat repetitiv pana la aplicarea metodei stop():
muzica.stopp();


Am vazut cum functioneaza si obiectul timer.
Instantiem un obiect de tip timer numit t:
timer t;
Din momentul instantierii acesta ruleaza, avand ca proprietate principala elapsed:
int timp_scurs=t.elapsed;
am atribuit variabilei timp_scurs numarul de milisecunde trecut de la instantiere sau de la ultimul restart().
O metoda importanta a clasei timer este restart():
t.restart();
face ca proprietatea elapsed sa fie adusa la valoarea 0, moment in care incepe din nou sa creasca.


Mai jos este un cod pe care l-am creat impreuna la curs.
Este o fereastra in care se aude un sunet de fundal.
La apasarea tastelor 1, 2, 3 sunetul de fundal se muta la stanga, centru, respectiv dreapta.
La apasarea tastei D de la dice, se aude o aruncare de zaruri, pozitionarea sunetului intre boxa stanga si dreapta fiind aleatorie.
Dupa 20 de secunde fereastra se inchide, putem spune ca e un demo de 20000 milisecunde.

Cod: Selectaţi tot

void main()
{
show_game_window("fundal cu muzica");

// Cream amianta, obiect de tip sound:
sound ambianta;
// Ii atribuim fisierul de tip sunet "fundal.ogg", fisier aflat in acelasi folder cu scriptul .bgt:
ambianta.stream("fundal.ogg");
// Reglam volumul la minus 18, pentru a nu se auzi foarte tare, pentru a fi doar ca fundal:
ambianta.volume=-18;
// Ii dam drumul sa cante la nesfarsit:
ambianta.play_looped();

// Instantiem obiectul zar de tip sound:
sound zar;
// Incarcam in rami pentru zar un sunet numit "dice.ogg", fisier aflat in acelasi folder cu fisierul .bgt:
zar.load("dice.ogg");

// Instantiem un timer:
timer t;
// Ii dam un restart, desi nu are sens aici:
t.restart();

// Deschidem while-ul principal care va rula pana la apasarea tastei Q:
while(!key_pressed(KEY_Q))
{
wait(5); // asteptarea de rigoare pentru procesor.

// Daca se apasa 1, fundalul se va auzi in stanga doar:
if(key_pressed(KEY_1))
ambianta.pan=-100;

// Daca se apasa 2, fundalul se va auzi la centru:
if(key_pressed(KEY_2))
ambianta.pan=0;

// Daca se apasa 3, fundalul se va auzi in dreapta doar:
if(key_pressed(KEY_3))
ambianta.pan=100;

// Daca se apasa D de la englezescul "dice":
if(key_pressed(KEY_D))
{
zar.stop(); // ii dam un stop la sunet, asta pentru a putea apasa la o frecventa marita tasta D.
zar.pan=random(-100, 100); // facem sa se auda undeva la intamplare sunetul.
zar.play(); // i se da drumul.
}

// Se verifica daca au trecut 20 de secunde pentru a se inchide automat fereastra:
if(t.elapsed>=20000)
{
// Trei randuri pentru a face sa se auda un sunet de avertizare:
sound finish;
finish.load("final.ogg");
finish.play_wait();
break; // se sparge while-ul.
}
} // se termina blocul de cod al while-ului.
exit();
}

Avand in vedere ca rezumatul a fost pus tarziu, intre timp avand loc si ultima intalnire in legatura cu sintaxa, nu mai dau nici o tema.
Daca cineva are idee cum sa programeze ca la apasarea tastei V sa se opreasca sunetul de fundal cu fade out, treptat, este bun.
In orice caz, ar fi bine sa se gaseasca cel putin o solutie teoretica, urmand apoi sa clarificam aici pe forum printr-un cod cat mai bun.


Imprimarea intalnirii de marti 5 iunie 2012, Clase Built-in, este la link-ul urmator:
Download Fisier MP3 10._Curs_BGT_-_Clase-Built-in.mp3 (72,4 MB)
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Curs BGT 11 - Crearea claselor

Mesaj de Manu »

Marti, 12 iunie 2012, ne-am intalnit pentru a unsprezecea oara in cadrul Cursului de programare in BGT.
Este ultima intalnire in care am invatat sintaxa.

Am discutat despre crearea claselor.

Pentru a crea o clasa, trebuie sa scriem urmatorul sablon:

Cod: Selectaţi tot

class nume_clasa
{
// aici proprietati si metode, respectiv variabile si functii.
}
Intai de toate, in blocul de cod al clasei definim proprietatile ca pe niste variabile oarecare, ele fiind disponibile apoi pentru modificare in cadrul metodelor / functiilor.

Am creat clasa dice, in romana insemnand zaruri:

Cod: Selectaţi tot

class dice
{
// Doua proprietati>
int zar1;
int zar2;
}
Nu putem atribui o o valoare variabilelor la definirea lor.

Pentru a seta primele valori ale proprietatilor, trebuie sa scriem constructorul clasei, acesta aratand ca o functie oarecare fara un tip in fata, avand numele clasei:

Cod: Selectaţi tot

class dice
{
// Doua proprietati>
int zar1;
int zar2;

// In constructor facem ca valoarea initiala a celor doua proprietati sa fie 0:
dice()
{
zar1=0;
zar2=0;
}
}
In continuare, dupa constructor definim metodele clasei ca pe oricare functie.

Cream doua metode, arunca() si spune():

Cod: Selectaţi tot

class dice
{
// Doua proprietati:
int zar1;
int zar2;

// In constructor facem ca valoarea initiala a celor doua proprietati sa fie 0:
dice()
{
zar1=0;
zar2=0;
}

// Definim cele doua metode:
void arunca()
{
zar1=random(1, 6);
zar2=random(1, 6);
}

void spune()
{
// Se va vorbi prin JAWS for Windows:
screen_reader_speak_interrupt(1, ""+zar1+", "+zar2+".");
}
}
De acum avem clasa dice care poate fi instantiata de exemplu in doua exemplare, cate o mana de zaruri pentru fiecare jucator:

Cod: Selectaţi tot

dice jucator1;
dice jucator2;
Din acest moment, daca spunem:

Cod: Selectaţi tot

jucator1.arunca();
jucator1.spune();
Vor fi aruncate zarurile pentru primul jucator, apoi va fi anuntat prin JAWS valorile acestora.

Putem oricand sa ne referim la valoarea unui zar al jucatorului 2 astfel:

Cod: Selectaţi tot

alert("Primul jucator!", "Al doilea zar al primului jucator este: "+jucator1.zar2+".");
In randul de mai sus am accesat practic proprietatea zar2 a instantei jucator1 a clasei dice.

La definirea unei clase putem specifica si un destructor, acesta fiind accesat in momentul distrugerii clasei, de exemplu cand este apelata functia exit().

Pentru a defini destructorul, scriem:

Cod: Selectaţi tot

class dice

// Aici proprietati, constructor si metode.

// Destructorul:
~dice()
{
alert("Destructor", "Obiect dice distrus.");
}
}
Asadar, pentru destructor scriem numele clasei precedat de semnul tilda, urmat de paranteza rotunda deschisa si inchisa, plus un bloc de cod in care scriem instructiunile pe care le dorim.

Daca am instantat dice ca jucator1 si jucator2, deci de doua ori, la apelarea functiei exit() va aparea de doua ori mesajul din functia alert().


Imprimarea intalnirii de marti, 12 iunie 2012, Crearea claselor, este la link-ul urmator:
Download Fisier MP3 11._Curs_BGT_-_Crearea_claselor.mp3 (54,3 MB)
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

De martia viitoare incepem sa facema plicatii practice, ar fi bine sa ne hotaram si pe aici cam pe ce linie mergem.

In urma unor discutii am ramas ca facem o sala prin care sa ne plimbam, iar pe ici pe colo sa existe diferite obiecte plasate, semnalate sonor si verbalizate de JAWS.
Ar urma sa vedem ce facem cu obiectele, eventual sa le putem muta, distruge sau ascunde.

Pentru aceasta vom folosi un array bidimensional ca in cazul tablei de sah, vom avea cateva sunete pentru obiectele pe care le vom plasa aleatoriu prin sala. La apasarea anumitor taste se va putea interactiona intr-un mod sau altul cu obiectele gasite.

Daca sunt idei pentru finisarea ideii, scrieti si pe aici, astfel incat sa stim cat mai clar ce avem de facut la... se le spunem seminarii.

Pe marti incerc sa am pregatit un ZIP cu sunete.
Ultima oară modificat 16 Iul 2012, 14:48 de către Manu, modificat 1 dată în total.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

BGT - Aplicatii practice - Partea 1

Mesaj de Manu »

Marti, 10 iulie 2012, ne-am intalnit pentru a douasprezecea oara in cadrul cursului de programare in BGT, fiind prima sedinta in care n-am mai invatat lucruri noi, ci am trecut la aplicatii practice.

Am inceput impreuna crearea unui joc.
Este vorba de o sala construita printr-un array bidimensional.
Utilizatorul va privi sala de pe mijlocul unei lungimi, iar cu sageata in sus va deplasa jucatorul virtual inainte, schimband directia cu cate 90 de grade prin apasarea sagetilor stanga / dreapta.
Prin sala vor fi diferite obiecte cu care se va interactiona in diverse moduri.

Am apucat in aceasta prima intalnire dintr-o serie de minim 4 sa cream sala redimensionand un array bidimensional de tip int.
Am definit 4 constante pentru lungime minima si lungime maxima, respectiv latime minima si latime maxima, urmand ca in viitor lungimea si latimea reale sa fie definite random intre aceste valori.
Pentru inceput nu am mers pe ideea de random, ci am setat lungimea la valoarea maxima posibila, iar latimea la valoarea minima posibila, 40, respectiv 20).
Sala fiind reprezentata printr-un array de tip int, am setat ca toate cele 800 de puncte sa fie initial cu valoarea 0, ceea ce in viitor va insemna loc gol, fara nici un obiect.
Am mai creat si o functie numita spune(), care stie sa trimita stringul din parametru la JAWS. Aceasta functie va fi dezvoltata sa vorbeasca la nevoie prin SApi5 si prin alte screen readere.

Asadar, in prezent, daca este rulat codul nostru, nu se va intampla decat:
Se aude un mesaj de bun venit, se anunta construirea salii, dupa care fereastra ramane activa, fiind posibila inchiderea programului cu Alt+F4, moment in care se aude un mesaj de bun ramas.

In intalnirile viitoare continuam cu deplasarea prin sala, adaugarea de sunete, initial pasii fiind important sa se auda corespunzator cu pozitia: daca suntem in coltul din stanga pe lungimea de pe care privim sa auzim pasul la volum mare in boxa stanga, daca se paseste in coltul nord-est sa se auda incet in boxa dreapta.


Mai jos este codul pe care l-am facut impreuna, dupa care este si link pentru descarcarea fisierului MP3:

Cod: Selectaţi tot

// Constante globale:
const int maxlung=40;
const int minlung=30;
const int maxlat=30;
const int minlat=20;

// Variabile globale:
int lungime=0, latime=0;
int x=0, y=0;
int[][] sala;


void main()
{
show_game_window("Explorare spatiu");
install_keyhook();

// Functia spune este definita de noi:
spune("Bine ai venit! Explorare placuta!");

// Functia lucruri_initiale() apeleaza construirea si golirea salii:
lucruri_initiale();

start_joc();

exit(); // deocamdata nu se ajunge la el niciodata, loop-ul principal este intrerupt printr-un alt exit.
}

void lucruri_initiale()
{
creare_sala();
}

void creare_sala()
{
spune("Asteapta, se construieste sala!", false);

// Deocamdata setam marimi fixe pentru lungimea si latimea salii:
lungime=maxlung;
latime=minlat;

// Redimensionam array-ul bidimensional la valorile lungimii si latimii:
sala.resize(lungime);
for(int i=0; i<lungime; i++)
{
sala[i].resize(latime);
}
golire_sala(); // Functie care atribuie valoarea 0 tuturor celor 800 de pozitii.
}

void golire_sala()
{
for(int i=0; i<lungime; i++)
{
for(int k=0; k<latime; k++)
{
sala[i][k]=0;
}
}
}

void start_joc()
{
jocul();
}

void jocul()
{
while(true)
{
if(key_down(KEY_LMENU)&&key_pressed(KEY_F4))
{
inchidere_joc();
}

wait(5);
}
}

void inchidere_joc()
{
spune("La revedere, te mai asteptam!");
exit();
}

// Functia spune stie sa vorbeasca deocamdata prin JAWS, cu intrerupere sau fara:
void spune(string mesaj, bool intrerupt=true)
{
if(intrerupt)
{
screen_reader_speak_interrupt(1, mesaj);
}
else
{
screen_reader_speak(1, mesaj);
}
}

Imprimarea intalnirii de marti, 10 iulie 2012, Aplicatii practice - Partea 1, este la link-ul urmator:
Download Fisier MP3 12._BGT_-_Aplicatii_practice_-_Partea1.mp3 (58,9 MB)
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Aplicatii practice in BGT, partea 2

Mesaj de Manu »

Marti, 17 iulie 2012, ne-am intalnit pentru a treisprezecea oara, intr-o a doua intalnire de aplicatii practice.

Am continuat cu realizarea joculetului nostru si am reusit sa facem deplasarea prin sala.

La apasarea sagetilor stanga / dreapta, personajul din joc se intoarce cu cate 90 de grade in directia corespunzatoare.
Cu sageata in sus personajul se deplaseaza in directia de la un moment dat.
Cu tasta d se poate afla la orice moment directia de deplasare - Nord, Est, Sud sau Vest.
Cu tasta c se pot afla in orice moment coordonatele X Y pe care se afla personajul.
Deplasarea este insotita de sunet corespunzator cu pozitia, auzit din perspectiva unuia care priveste de pe mijlocul laturii sudice.
Se aude si lovirea de perete corespunzator cu pozitia personajului.

Am facut ca sala sa fie creata la dimensiuni random intre anumite limite, codul fiind in asa fel creat incat indiferent de lungime si latime, deplasarea insotita de sunete sa fie in regula.
Daca se specifica lungimea la 1 si latimea la 50, va fi senzatia deplasarii printr-un tub, incercarea de a o lua la stanga sau dreapta fiind stopata de peretii care nu lasa decat locul de pasire inainte sau inapoi pe axa Nord-Sud.

Mai jos este un ZIP care contine tot ce trebuie pentru ca joculetul in faza lui actuala sa poata fi incercat de oricine, in folderul rezultat in urma extragerii fiind si o varianta compilata (.EXE).

Daca sunt completari sau imbunatatiri de cod aduse de catre cursanti intre doua intalniri, ar fi bine sa fie postate tot pe aici, urmand ca eu sa le includ in varianta oficiala pe care vom lucra in continuare.

Un .ZIP care contine intr-un folder tot proiectul in cea de-a doua faza a lui, fisiere de sunet, fisierul .BGT si un .EXE este la link-ul urmator:
Download Fisier ZIP cu intreg proiectul in faza 2, functional cu JAWS

Deschidere doar sursa intr-un fisier .TXT la link-ul urmator:
Sursa fisier TXT cu intreg codul in faza 2

Imprimarea intalnirii de marti, 17 iulie 2012, Aplicatii practice - Partea 2, este la link-ul urmator:
Download Fisier MP3 13._BGT_-_Aplicatii_practice_-_Partea2.mp3 (91,5 MB)
Ultima oară modificat 28 Iul 2012, 14:44 de către Manu, modificat de 3 ori în total.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Cornel
Locotenent
Mesaje: 376
Membru din: 02 Iun 2008, 23:17
Localitate: Targu Frumos

variatii

Mesaj de Cornel »

Jucandu-ma prin cod, m-am gandit sa adaug o comanda pentru revenirea la pozitia initiala, adica, directie nord, x=1, y=1; pentru aceasta am creat o noua functie care poate fi adaugata de catre cei curiosi chiar la sfarsitul codului:

Cod: Selectaţi tot

void pozitie_initiala()
{
directie=1;
x=0;
y=0;
}
acum incadram aceasta functie in while-ul din functia joc(), chiar dupa ultimul if:

Cod: Selectaţi tot

if(key_pressed(KEY_R))
{
pozitie_initiala();
}
Cornel
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Ca sa vada utilizatorul mai clar schimbarea, cheama tot in functia aia si redare_pas(); atunci chiar se aude cum brusc paseste / sare personajul in cel mai sud-vestic punct.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Cornel
Locotenent
Mesaje: 376
Membru din: 02 Iun 2008, 23:17
Localitate: Targu Frumos

mici adaugiri

Mesaj de Cornel »

Pentru calcularea variabilei int p, adica pan stanga-dreapta, o formula mai sintetica este p=x-lungime/2; asadar, inlocuim in functia void calculare_pv() linia p=... cu formula indicata mai sus; in alta ordine de idei, m-am gandit sa adaug si o comanda care sa ne spuna dimensiunile salii - lungime per latime; adaugam asadar in while-ul din functia joc (singurul de altfel) urmatorul cod:

Cod: Selectaţi tot

if(key_pressed(KEY_S))
{
spune("Dimensiunile salii sunt: " + lungime + "lungime si " + latime + "latime.", true);
}
Nu ar strica sa fie si un fundal in joc, ca atare, copiem in folderul sunete fisierul fundal.ogg, fisier pe care Manu l-a inclus in arhiva de la lectia obiectelor. Acum, pe langa cele doua obiecte indicate la inceput, mai adaugam si sound fundal, astfel vom avea -
sound fundal, pas, perete;
Acum, mergem in functia void incarcare_sunete()
si adaugam acolo linia:

Cod: Selectaţi tot

 fundal.stream("sunete\\fundal.ogg");
Pasul urmator consta in a crea o functie in care sa includem parametrii fundalului; deci, la sfarsitul fisierului sursa scriem:

Cod: Selectaţi tot

void redare_fundal()
{
fundal.volume=-25;
//e nevoie desigur de o reducere a volumului, Manu ne va explica desigur, cum sa-l reducem dupa preferinte, ulterior
fundal.play_looped();
//aceasta pentru ca fundalul sa curga continuu
Nu mai ramane decat sa includem in joc acest fundal, mai exact, in functia void lucruri_initiale() scriem, deasupra functiei creare_sala(); redare_fundal(); avand deci:

Cod: Selectaţi tot

void lucruri_initiale()
{
redare_fundal();
creare_sala();
}
In fine, sa presupunem ca, dupa adaugarea unor obiecte prin sala si cresterea gradului de dificultate, avem nevoie si de o pauza; la capatul fisierului sursa cream functia pauza:

Cod: Selectaţi tot

void pauza()
{
while(true)
{
fundal.volume=0;
if(key_pressed(KEY_P))
{
redare_fundal();
break;
}
}
}
Acum invocam in functia joc aceasta functie; dupa cum observam, vom avea un while care intrerupe while-ul principal al jocului si, la randul lui prin tasta p se sparge, reintrand pe while-ul jocului:

Cod: Selectaţi tot

void jocul()
{
while(true)
{
if(key_pressed(KEY_P))
{
spune("stop:", true")
pauza();
}
//si apoi continuarea cu celelalte if-uri, desigur, fiecare poate decide ordinea acestor conditii, in functie de logica proprie
Poate mai vin si altii cu idei, fie legate de cum sa arate sala, ce obiecte sa fie pe acolo, care sa fie sarcinile plimbaretului etc.
Cornel
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Totul e foarte bine si vom include ce ai programat in codul oficial pentru faza 3 a jocului.

Ma bucur ca ai gasit cea mai sintetica formula pentru calcularea pan-ului, noi la curs am mers pe formule diferite pentru pan stanga si pan dreapta. Va fi inlocuit acel if din calculare_pv(), practic va fi ceva sintetizat.

Ai grija cu while-ul din functia pauza(), acolo nu ai pus un wait(5) si cand e pe pauza, procesorul iti merge la 100%.
Regula e: niciodata un while care poate dura mult fara wait(), altfel te vor injura utilizatorii.

La volumul fundalului vom merge pe tastele KEY_PRIOR si KEY_NEXT (page-up si page-down), verificate prin key_down(), acolo nu trebuie decat sa chemam doua functii: crestere_volum_fundal(), respectiv scadere_volum_fundal();

Functia crestere_volum_fundal() ar putea arata astfel daca nu se salveaza setarea, ci tot timpul va fi reglat la -25 la lansarea jocului:

Cod: Selectaţi tot

void crestere_volum_fundal()
{
// Doar daca fundalul nu ajunge la 0, unde va fi piedica:
if(fundal.volume<0))
{
fundal.volume=fundal.volume+1;
// Punem si o asteptare de 30 ms pentru a nu creste instant:
wait(30);
}
}
Practic acel wait(30) face ca volumul sa creasca mai treptat, altfel la o scurta mentinere apasata a tastei page-up ar ajunge volumul la 0, nu ar avea nevoie decat de 25 ori 5 ms, deci 125 ms, aproape imperceptibil. Am zis ori 5 pentru ca acel wait de 5 este in while-ul principal la fiecare ciclu. Cu acest wait(30), volumul are nevoie de 25 ori 35 ms, deci de 875 ms, aproape o secunda, pentru a ajunge de la -25 cat e initial, pana la 0.

Se cheama ca acum ai inteles tot ce am facut, incepi sa devii independent, ma bucura treaba asta, abia astept sa scoatem jocul asta final cu tot ce trebuie: miza, nivel de dificultate etc..
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Scrie răspuns