BGT de la Blastbay Studios, un scripting accesibil si facil

Diverse limbaje, programare, scripting, coduri, unelte specifice etc.
Scrie răspuns
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Multumesc pentru ajutor. Acum totul merge cum trebuie.
Ulterior ii facusem eu fereastra joculetului, dar in momentul cand am postat aici n-avea asa ceva, intr-adevar.
Stefan
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Salutare din nou.
Sunt tare curios de un lucru.
Sa zicem ca intr-un joc suntem nevoiti sa cumparam ceva.
Inainte de a cumpara acel lucru, se presupune ca in inventar nu era nimic,
(precizez ca inventarul il creez folosind dynamic meni-ul).deci sa zicem ca variabila rosii este 0. In momentul in care variabila rosii este sa zicem.... 1, este posibil ca in acel meniu sa apara un nou item? Precizez ca vreau ca acel item sa-si afaca aparitia acolo doar in momentul in care am facut rost de acel obiect.
Ceva in genul time adventures, chillingham.
Stefan
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Probabil ca vrei in felul urmator:
Sa fii pe meniu, te plimbi prin lista si facand ceva vrei sa mai apara un item.
Nu stiu daca acea clasa dynamic_menu facuta de Philip permite schimbarea numarului de itemi la run-time, banuiesc ca nu, daca nu scrie prin manual, daca nu este acolo vreo metoda.
Oricum, daca ai vrea asa ceva, ar trebui sa te bagi in sursa clasei sa modifici, trebuie sa bagi in while-ul care tine fereastra in loc, cel inc are sagetile sus jos te plimba printre optiuni ceva tasta cu care sa se adauge itemi.

Eu as face ceva propriu, de fapt nici nu am mai folosit clasa aceea pentru jocurile mai noi, mi-am creat propriul meniu, astfel incat sa fie asa cum imi place mie si sa adaug si sa scot usor ce vreau. La table am clasa aceea dar modificata foarte mult ca sa se comporte asa cum e acum.

Deci, ar trebui sa incerci tu ceva ca sa iti faci o lista proprie, cred ca am facut si eu un cod in acest sens prin topicul asta. Acea clasa sau functie va trebui sa aiba la un moment dat si un while unde sa ii pui navigarea cu sageata sus jos, practic plimbare prin valorile unui array cu string-uri.
Incepe tu ceva si o sa iti arat mai clar cum ar putea fi. Vezi daca nu gasesti lista facuta de mine prin acest topic. Pe ea am putea-o modifica astfel incat sa ii poti scoate itemi cu delete si adauga itemi cu alta tasta.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Salutare.
Eu inca mai am o mare, mare nelamurire.
Cum pot face ca tot feedback-ul sa fie redat de catre jaws?
Am facut un meniu, am setat speech_mode ca fiind Jaws pe acel meniu, dar problema e ca vreau ca atunci cand dau enter sau fac vreo alta alegere prin scriptulet, sa imi vorbeasca tot jaws, nu sapi.
Jaws imi spune doar optiunile din meniu, iar celelalte lucruri sunt redate de catre sapi.
PS: as vrea sa stiu daca exista o cale mai usoara fara a mai pune screen_reader_speak la fiecare chestie, ca altfel cred ca mai termin in o gramada de ani... :)
Nu stiu daca cei care fac jocurile jucabile cu jaws au vreo metoda prin care sa declare cumva screen reader-ul ca fiind utilizabil pentru toate actiunile si chestiile ce sunt executate in acel scriptulet
Stefan
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Nu se poate declara cumva global sa vorbeasca JAWS daca tu utilizezi tts_voice; aceasta este o clasa pentru vocile SApi.
Tu instantiezi undeva la inceput sa zicem obiectul / variabila my_voice. Apoi tot mergi cu my_voice.speak(), my_voice.speak_interrupt etc.
E clar ca si pentru a vorbi cu JAWS ar trebui sa scrii peste tot screen_reader_speak() sau screen_reader_speak_interrupt().
Ca sa nu ai astfel de probleme, cel mai bine e sa faci o functie numita say().
Aceasta functie say() sa primeasca la parametru stringul de verbalizat.
In functia say mai poti utiliza si o variabila globala pentru numarul screen-reader-ului cu care vrei sa vorbeasca, iar acea functie va primi un numar intre 1 si 4, acesta fiind detectat cumva la inceputul jocului sa la un interval stability in decursul jocului; astfel e posibil sa te muti de pe JAWS pe NVDA la runtime.
Tot in functia say ai putea sa detectezi ca nu e pornit nici un screen reader si atunci sa folosesti acel my_voice care era o instant a lui tts_voice.

Poate nu am fost prea clar, eu am aceste functii gata facute, doar trebuie sa le pui in joc si apoi sa chemi functia say ca in exemplul:
say("Salut!");
astfel sa se auda "salut" cu un screen reader daca exista vreunul pornit, daca nu sa vorbeasca cu SApi5.
Daca nu te descurci, o sa pot pune aici functiile mele pe care le-am utilizat in cateva jocuri, cum ar fi Pontes Escape.
Desigur ca le gasesti si in sursa jocului facut de noi la acel curs de BGT. Acolo sunt chiar in limba romana, cu cod comentat.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Am mai incercat sa fac o mica chestiuta cu bgt-ul. Un spatiu de 15 pe 15, prin care sa te plimbi cu sagetile.
Am vrut ca pe unul dintre pereti sa pun si o usa, iar in momentul cand ajung fix pe coordonata respectiva sapi sa imi zica "large door".
Problema e ca nu stiu cum, dar sapi rateaza cumva sa anunte usa in momentul in care trebuie, si o mai anunta total aiurea, de exemplu cand dau o sageata in sus de la locul in care trebuia de fapt s-o anunte.
Pun codul mai jos, mentionez c-am realizat aceasta... camaruta cum m-am priceput, si daca exista alternative mai simple sau sugestii ce pot simplifica munca, sunt bine venite.

[code]
tts_voice V;

void main()
{
show_game_window("Scroller");
install_keyhook();
V.speak_wait("Loading...");
scroller();
}

void scroller()
{
int x=0;
int y=0;
sound step;
step.load("Concrete1.wav");
step.volume=-5;
while(true)
{
wait(5);
if(key_pressed(KEY_UP))
{
x++;
step.play();
}
if(key_pressed(KEY_DOWN))
{
x--;
step.play();
}
if(key_pressed(KEY_LEFT))
{
y--;
step.play();
}
if(key_pressed(KEY_RIGHT))
{
y++;
step.play();
}
if(x<0)
{
x=0;
step.stop();
V.speak_interrupt("Wall");
}
if(x>15)
{
step.stop();
x=15;
V.speak_interrupt("Wall");
}
if(y<0)
{
step.stop();
y=0;
V.speak_interrupt("Wall");
}
if(y>15)
{
step.stop();
y=15;
V.speak_interrupt("Wall");
}
if(y==5&&x==0)
{
V.speak_interrupt("Large door");
}
if(key_pressed(KEY_Q))
{
V.speak_wait("Exiting...");
exit();
}
}
}
[/code]
Stefan
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Am reusit sa mai slepuiesc putin scriptuletul, dar tot am o mare problema.
Cand jaws-ul gaseste usa in micul spatiu pe care l-am creat, datorita while-ului repsta "Usa, usa" foarte repede si cam.... la nesfarsit.
Ce ar trebui sa fac ca Jaws sa imi zica doar "Usa", o singura data atunci cand se indeplineste conditia data?
Pun mai jos codul pentru orice eventualitate.

#include "Verbalizare Jaws.bgt"
tts_voice V;
int x;
int y;

void main()
{
show_game_window("Scroller");
install_keyhook();
screen_reader_speak_interrupt(1,"Incarcare.......");
wait(1000);
scroller();
}

void scroller()
{
x=0;
y=0;
sound step;
step.load("Sounds/Concrete1.wav");
step.volume=-5;
while(true)
{
wait(5);
if(key_pressed(KEY_UP))
{
step.stop();
x++;
step.play();
}
if(key_pressed(KEY_DOWN))
{
step.stop();
x--;
step.play();
}
if(key_pressed(KEY_LEFT))
{
step.stop();
y--;
step.play();
}
if(key_pressed(KEY_RIGHT))
{
step.stop();
y++;
step.play();
}
if(x<0)
{
x=0;
step.stop();
anuntare_perete();
}
if(x>15)
{
step.stop();
x=15;
anuntare_perete();
}
if(y<0)
{
step.stop();
y=0;
anuntare_perete();
}
if(y>15)
{
step.stop();
y=15;
anuntare_perete();
}
if(key_pressed(KEY_C))
{
anuntare_coordonate();
}
if(key_pressed(KEY_Q))
{
screen_reader_speak_interrupt(1, "Iesire din program......");
wait(1000);
exit();
}
if(x==0&&y==5)
{
anuntare_usa();
}
}
}
Stefan
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Ar fi mai multe solutii, doar ca fara sa modificam codul tau ar trebui una cam de compromis.

Mai intai as mentiona cum am facut noi la Pontes Escape. Ca o conditie sa nu fie permanent adevarata pana nu se apasa iar sageata, asta pentru ca se afla intr-un loop, am facut of unctie de genul:
actiuni_dupa_pas()
In aceasta functie am verificat daca este usa de exemplu, iar aceasta functie este chemata o singura data in momentul apasarii uneia dintre sageti.
Asadar, faci functie actiuni_dupa_pas(), in ea verifici if(x==0&&y==5).
Chemi functia in fiecare dintre if-urile care verifica key_pressed().

La cum e acum codul, ai mai putea sa faci si altfel, dar mi se pare ca e o solutie prea de compromis:
ai putea crea o variabila globala
bool a_fost_usa_anuntata=false.
La acel if care verifica daca x==0 si y==5, ii mai spui si ca daca usa nu a fost anuntata, deci:
if(x==0 && y==5 && !a_fost_usa_anuntata)
Asadar se va intampla nu doar daca coordonata corespunde, ci si daca nu a fost usa anuntata.
In If, unde se ajunge doar daca se indepinesc cele trei criterii, faci ca _a_fost_usa_anuntata sa fie adevarat:
a_fost_usa_anuntata=true;
Automat este marcat faptul ca a fost anuntul si nu se mai indeplineste iar conditia.
Compromisul vine acum, pentru ca va trebui sa faci ca daca nu este x==0 si y==5 ca variabila a_fost_usa_anuntata sa se faca falsa.
Deci, un if:
if(x!=0 && y!=5)
{
a_fost_usa_anuntata=false;
}
In acest moment, cand nu ne aflam pe usa, se tot seteaza faptul ca nu a fost anuntata, deci cand se ajunge pe usa va fi anunt din nou.
Problema e ca continuu, la fiecare 5 milisecunde se va seta acea variabila la false, deci se intampla repetitiv o actiune fara sens.
Oricum asta nu e asa grav pentru ca e doar atat, nu implica si altceva, cum ar fi o anuntare de alt tip doar pentru ca e loop si ca nu e usa.

Oricum, prima solutie e mai buna si mai usor de indeplinit.
E bine sa creezi functii care sa aiba loc in fiecare ipostaza, cum spuneam de cea care sa se intample atunci cand se paseste. In viitor in ea poti verifica tot felul de lucruri care sa se intample doar o data la apasarea unei sageti.
Nu e bine sa stea multe lucruri in loop daca e clar ca nu e cazul sa se intample decat uneori, cum ar fi in cazul de fata doar cand pasim.

Daca nu ai inteles, scrii tu aici si incerc sa modific codul tau.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Pentru a evita confuziile, credeti ca imi puteti exemplifica putin calea aceea mai simpla de care ati zis, cu functia aceea "Actiuni dupa pas" si tot tacamul. Sa-mi fac cat de cat o idee si sa nu mai fac nefacute din nou.
Stefan
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Creezi functia:

void actiuni_dupa_pas() {
// Aici verificarea daca e usa, si eventual altele.
}

Chemi functia actiuni_dupa_pas() in fiecare if(key_pressed()), dupa incrementarile si decrementarile variabilelor x si y si verificarile daca e perete etc.

Daca nu iese, as putea sa il modific candva catre sfarsitul saptamanii.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Bun. Pe asta am inteles-o, si am si rezovalt-o.
Acuma mi se intampla ceva foarte ciudat cu sunetele.
Am incarcat o ambianta cu stream, doar ca problema e urmatoarea: cand un sunet este repetat rapid, de exemplu lovirea de perete sau folosirea sabiei, la un moment ambianta pur si simplu se blocheaza sau se intrerupe si nu imi pot explica care ar fi cauza.
Stefan
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

Greu de spus, eventual pune codul sa vedem daca nu e ceva gresit, desi nu prea vad cum s-ar putea gresi la asta, mai ales ca initial merge...
Poate ai un calculator mai slab si nu prea reuseste sa faca un management bun in lucru cu Direct X... Nu imi pot da seama...
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
BosGrigore
Plutonier
Mesaje: 145
Membru din: 22 Iul 2012, 21:48
Localitate: Cluj-Napoca

Mesaj de BosGrigore »

Incarca ambianta cu load() pentru a fi redata din memorie, stream() reda ambianta direct de pe hard disc si de aceea apare intreruperea.
Grigore
Stefan_Ilioaica
Capitan
Mesaje: 503
Membru din: 12 Sep 2009, 21:00
Localitate: Bucuresti

Mesaj de Stefan_Ilioaica »

Vin si eu aici cu o intrebare ce poate parea cam pentru cei care abia au vazut bgt-ul, dar totusi...
Care-i diferenta dintre const si int? Si la joculetul acela "Falling", si la altele am observat ca le folosim pe ambele.
Stefan
Avatar utilizator
Manu
General de divizie
Mesaje: 4120
Membru din: 02 Feb 2007, 01:15
Localitate: Cluj-Napoca
Contact:

Mesaj de Manu »

"const" inseamna ca este definita o constanta. O constanta este ca o variabila, doar ca nu este variabila. :)
Scriind
const int my_number = 5;
vom avea my_number o constanta care nu va mai putea fi modificata, se va putea scrie undeva sa zicem:
int my_new_number = my_number;
dar nu vom mai putea scrie:
my_number = 10;
Asadar, in bgt si in multe alte limbaje, exista variabile si constante. In cazul variabilelor se poate modifica oricand continutul, in cazul constantelor nu se mai poate face acest lucru, vor ramane de-a lungul existentei cu primele valori atribuite.

In BGT si in alte limbaje cu tipuri statice, atat variabilele, cat si constantele trebuie sa aiba un tip specificat la creare, adica trebuie sa fie string, int, float, double, bool etc.
E adevarat ca poti folosi oricand o variabila, chiar daca nu ai nevoie sa ii schimbi valoarea, dar pentru claritate a fost creata si posibilitatea declararii de constante in BGT.

Eu am folosit la unele jocuri numele intr-o constanta, am scris la inceput:
const string game_name = "Pontes Escape";
E clar ca nu e nevoie sa ii mai schimb numele pe parcursul rularii, peste tot unde se mentioneaza numele jocului apare acel game_name, de exemplu la mesajul de intampinare:
say("Welcome to "+game_name+"!");
Totusi, la fel ar fi fost si daca scriam sus:
string game_name = "Pontes Escape";
deci am putea sterge cuvantul "const" si nu s-ar intampla nimic, cel putin in acest caz.
In Java si alt elimbaje o constanta poate avea mai multe implicatii, de multe ori fiind necesar sa declari parametri unei functii ca final (constante), asta pentru a fi permisa utilizarea lor in niste listeneri etc, dar acestea sunt lucruri mai avansate.
Pe scurt, in BGT nu prea au rost constantele, ajuta doar la organizarea codului, de multe ori fiind convenabil sa ai clar anumite valori care sa stii ca nu se vor schimba: ar mai putea intra aici de exemplu numarul versiunii care ar putea fi o constanta de tip float sau int, utila pentru a o compara cu o valoare adusa de pe un server, astfel stiind ca exista sau nu o noua versiune disponibila pentru update.
Errare humanum est, sed perseverare diabolicum...
In forum linguae Latinae venite! (via est: www.limbalatina.ro)
Scrie răspuns