View Full Version : [CICLO 6] Storia 2
Storia 2: Ogni gemma creata dovrà avere un’animazione a ciclo continuo che simuli un riflesso, e che si ripeta ogni 3.5 secondi, valore comunque modificabile in GameConfig. Le animazioni di tutte le gemme su schermo dovranno essere sincronizzate tra loro, ossia iniziare tutte nello stesso momento.
Nella finestra "next" verrà visualizzata una coppia di gemme dei due colori immediatamente successivi nella coda a quella attualmente in caduta. Di queste due gemme, quella in basso sarà la prossima a cadere, e la coppia verrà aggiornata ogni volta che una nuova gemma viene creata.
Punti cardine da tenere a mente durante i lavori:
Mai fare a gara a chi finisce il task per primo, meglio procedere con calma, altrimenti perderemo molto più tempo in seguito
Evitiamo di complicarci la vita, esiste di certo una soluzione più semplice di quella che abbiamo pensato di implementare
MAI aggiungere elementi non richiesti esplicitamente dai task: se mai serviranno, se ne parlerà nelle prossime storie
Comunichiamo il più possibile, se qualcosa non è chiaro discutiamone tutti i dettagli fino ad eliminare ogni dubbio, anche il più insignificante
Postare sempre la test list PRIMA di mettere mano al codice
Ecco i task per questa storia.
Task:
6.2.1: 71104: 2 giorni
Mostrare nel riquadro "next" dell'area di gioco le prossime due gemme che saranno rilasciate. La prima gemma ad essere rilasciata dovra essere quella piu in basso.
6.2.2: thebol: completato
Aggiungere a sprite la capacita di caricare Texture che contengono i vari frame delle animazioni.
6.2.3: cdimauro: 2 giorni
Implementare le animazioni in sprite cambiando frame ogni decimo di secondo. Al termine del'animazione si deve mostrare il frame di base per 3500 millisecondi prima di ripartire.
6.2.4: Ufo13: 2 giorni
Sincronizzare le animazioni delle gemme all'interno della griglia tra di loro. Se una gemma viene creata quando le altre sono a meta animazione deve quindi mostrarsi anche lei a meta animazione.
ciao ;)
Approfitto dello spazio sotto i task per un piccolo chiarimento sulle animazioni.
Le texture che useremo avranno questo formato:
http://lnx.rc6.it/diamonds/varie/topaz.png
Le due "colonne" contengono rispettivamente la gemma normale e quella illuminata. Il frame più in alto è quello di base, e dovrà rimanere fisso per 3.5 secondi (variabili da GameConfig). Scaduto questo tempo, dovranno essere visualizzati, ognuno per 0.1 secondi, gli altri cinque frame nella colonna, dall'alto in basso. Al termine di questo ciclo di animazione, si dovrà tornare al fotogramma fisso.
Per qualsiasi dubbio, chiedete pure ;)
6.2.4:
Sincronizzare le animazioni delle gemme all'interno della griglia tra di loro. Se una gemma viene creata quando le altre sono a meta animazione deve quindi mostrarsi anche lei a meta animazione.
Ma in questo modo le gemme non brillano tutte insieme ?
Ma in questo modo le gemme non brillano tutte insieme ?
Esatto ;)
Altra cosa...mi sa che va aggiunto un task di questo tipo:
aggiungere a Config la psosibilità di leggere/gestire valori floating point...
Esatto ;)
Sinceramente a me piacerebbe che brillassero ad intervalli non regolari ed abbastanza diversi l'una dall'altra... Che so 3 secondi + rand(300)/100...
Sinceramente a me piacerebbe che brillassero ad intervalli non regolari ed abbastanza diversi l'una dall'altra... Che so 3 secondi + rand(300)/100...
Brillando in maniera differente potrebbero essere un elemento di distrazione. Essendo la cosa uniforme, invece, dovremmo poter limitare questo svantaggio.
Per questo stesso motivo abbiamo anche scelto un timeout fisso, e non variabile.
In ogni caso, dato che per sincronizzare l'animazione bisogna prima implementarla, potremo vedere anche l'effetto di più animazioni fuori sincrono e, in caso, anche cambiare idea ;)
cdimauro
07-12-2005, 17:05
Vorrei prenotarmi per il task 6.2.3. Prevedo di impiegarci 2 giorni dalla fine del task 6.2.2.
Altra cosa...mi sa che va aggiunto un task di questo tipo:
aggiungere a Config la psosibilità di leggere/gestire valori floating point...
Parlando con Jocchan abbiamo deciso che non serve. Almeno per ora. Ho cambiato quel "3,5 secondi" in 3500 milisecondi in modo da poter usare un intero e renderlo consistente all'unita di misura che gia usiamo.
ciao ;)
Vorrei prenotarmi per il task 6.2.3. Prevedo di impiegarci 2 giorni dalla fine del task 6.2.2.
Assegnato.
ciao ;)
Sinceramente a me piacerebbe che brillassero ad intervalli non regolari ed abbastanza diversi l'una dall'altra... Che so 3 secondi + rand(300)/100... non sono d'accordo :)
secondo me se il riflesso appare a tutte nello stesso momento è molto più bello (nonché più realistico ;))
allora, premesso che io e daniele ci scusiamo per il ritardo del nostro task causato dall'incompatibilità di orari, mi vorrei prenotare (^^') per il 6.2.1, 2 giorni per sicurezza.
non sono d'accordo :)
secondo me se il riflesso appare a tutte nello stesso momento è molto più bello (nonché più realistico ;))
allora, premesso che io e daniele ci scusiamo per il ritardo del nostro task causato dall'incompatibilità di orari, mi vorrei prenotare (^^') per il 6.2.1, 2 giorni per sicurezza.
Assegnato.
Per quanto riguarda il task della storia precedente non ti preoccupare. Sapevo che sarebbe andata a finire cosi visti gli orari di Daniele ma vi ho abbinati lo stesso.
ciao ;)
non capisco le richeste per il il 6.2.2.
A usare la png postata su sto thread come esempio, i test vengono superati, pero se la si prova a usare non viene visualizzata per bene.
E questo che è da implementare?
Altra cosa che ho notato, e che i nomi delle gemme sono usati in piu punti di codice, e se si vuole cambiarne uno bisogna modificarlo in piu parti di codice.
Non sarebbe meglio esternalizzare in una classe statica o sistema simile?
non capisco le richeste per il il 6.2.2.
A usare la png postata su sto thread come esempio, i test vengono superati, pero se la si prova a usare non viene visualizzata per bene.
E questo che è da implementare?
ci ho pensato un po e immagino sia proprio questo da fare...
cmq mi ci prenoterei io per questo task.
Tempo stimato 1 giorno.
Ho committato le gemme con i frame.
Thebol, bisogna appunto consentire al codice di gestire texture in questo formato ;)
P.S.: i nomi delle gemme sono costanti che non cambieremo, ma effettivamente resta sbagliato avere questi valori troppo diffusi all'interno del codice.
Ho committato le gemme con i frame.
Thebol, bisogna appunto consentire al codice di gestire texture in questo formato ;)
P.S.: i nomi delle gemme sono costanti che non cambieremo, ma effettivamente resta sbagliato avere questi valori troppo diffusi all'interno del codice.
fatto :)
Il problema e quando settavi la brightnes(sia a true che false) si usavano come valori solo quelli della texture senza tenere conto del size dello sprite.
Per cui ho tolto i test
gemTextureRect = new Rectangle(0, 0, gem.getTexture().getWidth() / 2 - 1,
gem.getTexture().getHeight() - 1);
gem.draw(engine);
assertTrue("gem must be drawn with unbrightened texture", engine
.getTextureRect().equals(gemTextureRect));
gem.setBrightenedStatus(true);
gemTextureRect = new Rectangle(gem.getTexture().getWidth() / 2, 0, gem
.getTexture().getWidth() - 1, gem.getTexture().getHeight() - 1);
gem.draw(engine);
assertTrue("gem must be drawn with brightened texture", engine
.getTextureRect().equals(gemTextureRect));
e gli ho sostituiti con
gem.setBrightenedStatus(false);
gem.draw(engine);
assertEquals("gem must be drawn with unbrightened texture(bad left)", engine
.getTextureRect().left(), 0);
assertEquals("gem must be drawn with unbrightened texture(bad right)", engine
.getTextureRect().right(), 31);
gem.setBrightenedStatus(true);
gem.draw(engine);
assertEquals("gem must be drawn with brightened texture(bad left)", engine
.getTextureRect().left(), 32);
assertEquals("gem must be drawn with brightened texture(bad right)", engine
.getTextureRect().right(), 63);
che misura se si sta disegnano un frame della prima colonna o della seconda
poi ho inserito un test sulla dimensione della texture area disegnata, in modo che sia uguale a quella di sprite
public void testGemViewSize()
{
MockEngine engine = new MockEngine();
Gem gem = Gem.createForTesting();
gem.draw(engine);
assertEquals("Height of the texture engine differente of height of gem(init)",engine.getTextureRect().getHeight(), (int)gem.getHeight());
assertEquals("Width of the texture engine differente of width of gem(init)",engine.getTextureRect().getWidth(), (int)gem.getWidth());
gem.setBrightenedStatus(false);
gem.draw(engine);
assertEquals("Height of the texture engine differente of height of gem(bright false)",engine.getTextureRect().getHeight(), (int)gem.getHeight());
assertEquals("Width of the texture engine differente of width of gem(bright false)",engine.getTextureRect().getWidth(), (int)gem.getWidth());
gem.setBrightenedStatus(true);
gem.draw(engine);
assertEquals("Height of the texture engine differente of height of gem(bright true)",engine.getTextureRect().getHeight(), (int)gem.getHeight());
assertEquals("Width of the texture engine differente of width of gem(bright true)",engine.getTextureRect().getWidth(), (int)gem.getWidth());
}
poi ho modificato il codice di setBrightenedStatus in
{
if(!brightened)
{
setViewArea(
new Rectangle(
0,
0,
((int) getWidth()) -1,
((int) getHeight()) -1
)
);
}
else
{
setViewArea(
new Rectangle(
getTexture().getWidth() / 2,
0,
((int) getWidth()) -1 + (getTexture().getWidth() / 2),
((int) getHeight()) -1
)
);
}
this.brightened = brightened;
}
che soddisfa i test di build
Ho provato anche a farlo girare e ora si vede bene.
Un appunto sui colori dei diamanti:
il diamante(normale) è molto simile all sapphire illuminato(una volta sovrapensiero mi sono proprio sbagliato), forse si potrebbero differenziare un po di piu.
Se il tutto va bene, fatemi sapere come fare il commit :)
Un appunto sui colori dei diamanti:
il diamante(normale) è molto simile all sapphire illuminato(una volta sovrapensiero mi sono proprio sbagliato), forse si potrebbero differenziare un po di piu.
Grazie per la segnalazione, appena mi libero un pò provvederemo :D
Se il tutto va bene, fatemi sapere come fare il commit :)
Non hai accesso al repository su Subversion? Ti consiglio di dare una sbirciata qui: http://www.hwupgrade.it/forum/showthread.php?t=1016614
ci ho pensato un po e immagino sia proprio questo da fare...
cmq mi ci prenoterei io per questo task.
Tempo stimato 1 giorno.
Assegnato.
ciao ;)
Altra cosa che ho notato, e che i nomi delle gemme sono usati in piu punti di codice, e se si vuole cambiarne uno bisogna modificarlo in piu parti di codice.
Non sarebbe meglio esternalizzare in una classe statica o sistema simile?
E' una buona idea per un futuro refactoring. Tutte quelle costanti letterali in giro non piacciono nemmeno a me. Se ho tempo rimedio personalmente piu tardi.
ciao ;)
E' una buona idea per un futuro refactoring. Tutte quelle costanti letterali in giro non piacciono nemmeno a me. Se ho tempo rimedio personalmente piu tardi. più che una classe statica è meglio usare Config: l'abbiamo fatta apposta allo scopo ;)
mi manca il login e pwd
Ti ho mandato il login con un messaggio privato. Controlla.
ciao ;)
Ti ho mandato il login con un messaggio privato. Controlla.
ciao ;)
commitato le 2 classi ;)
cdimauro
08-12-2005, 07:52
Vado di fretta, perché mia moglie ha preso l'ascia di guerra.
Per quanto riguarda il mio task, ci sono due soluzioni: integrare un timer in ogni sprite oppure avere un solo timer (quello dell'intero gioco), e richiamare un metodo di aggiornamento per ogni sprite.
Il primo porta ad eventuali asincronie nel sistema (n timer diversi sono difficili da gestire), il secondo l'uso di una collezione di sprite.
Io propendo per la seconda. Che ne dite?
In tal caso, vorrei sapere la frequenza a cui verranno richiamati gli sprite.
Grazie e scusate per la fretta. :D
C'è già il timer... Ed è quello che in Game fa l'update di grid... Basta chiamare l'update di tutte gemme in grid ogni volta che viene fatto l'update di grid...
Iltimer è fissato a 10ms...ma si può modificare vambiando l'UpdateRate in GameConfig.xml... In ogni caso anche ti va bene comunque lasciarlo a quella cifra..
Ho fatto un po di refactoring in spirte.
Ho introdotto un nuovo metodo
public void setViewArea(int left, int top)
{
setViewArea(
new Rectangle(
left,
top,
left + ((int) getWidth()) -1 ,
top + ((int) getHeight()) -1
)
);
}
che crea la viewArea definendo il left e il top, e generando gli altri 2 valori usando la dimensione dello sprite.
in questa maniera setBrightenedStatus diventa:
public void setBrightenedStatus(boolean brightened)
{
if(!brightened)
{
setViewArea(0, 0);
}
else
{
setViewArea(getTexture().getWidth() / 2, 0);
}
this.brightened = brightened;
}
Questo metodo risulterà anche utile per l'animazione, e inoltre rende Gem non soggetta ai cambiamenti di rectangle(per ora).
Un altro refactoring carino sarebbe nella nuova setViewArea non creare un nuovo oggetto ma cambiare le propieta dell'oggetto(cosa non prevista da rectangle), ma penso che arriverebbe fek con You Aren't Gonna Need It. :asd:
per il mio task propongo di aggiungere due metodi drawFirst(x, y) e drawSecond(x, y) all'interfaccia GemGenerator e alla classe GemQueue; questi sono i test:
public void testDrawFirst()
{
MockEngine engine = new MockEngine();
gemQueue.drawFirst(0, 0);
assertEquals(1, engine.getNumberOfQuadsDrawn());
}
public void testDrawSecond()
{
MockEngine engine = new MockEngine();
gemQueue.drawSecond(0, 0);
assertEquals(1, engine.getNumberOfQuadsDrawn());
}
non c'è molto da testare a dir la verità, giusto verificare che quei due sprites vengano disegnati.
edit1: scusate, sono ancora addormentato :D
devo anche testare che Grid chiami questi due metodi; un momento che scrivo il test...
edit2: eccolo:
public void testDrawNextTwoGems()
{
MockEngine engine = new MockEngine();
grid.draw(engine);
assertEquals(3, engine.getNumberOfQuadsDrawn());
}
però mi sa che andranno modificati anche un altro paio di test sempre di Grid.draw perché grid a questo punto ogni volta disegna due sprites in più.
ma penso che arriverebbe fek con You Aren't Gonna Need It. :asd: guarda che si deve scrivere "You Ain't Gonna Need It" :Prrr:
slang per slang facciamo le cose fatte bene, no? :D
guarda che si deve scrivere "You Ain't Gonna Need It" :Prrr:
slang per slang facciamo le cose fatte bene, no? :D
prenditela con fek, ho copiaincollato da un suo post :asd:
per il mio task propongo di aggiungere due metodi drawFirst(x, y) e drawSecond(x, y) all'interfaccia GemGenerator e alla classe GemQueue; questi sono i test:
public void testDrawFirst()
{
MockEngine engine = new MockEngine();
gemQueue.drawFirst(0, 0);
assertEquals(1, engine.getNumberOfQuadsDrawn());
}
public void testDrawSecond()
{
MockEngine engine = new MockEngine();
gemQueue.drawSecond(0, 0);
assertEquals(1, engine.getNumberOfQuadsDrawn());
}
non c'è molto da testare a dir la verità, giusto verificare che quei due sprites vengano disegnati.
edit1: scusate, sono ancora addormentato :D
devo anche testare che Grid chiami questi due metodi; un momento che scrivo il test...
edit2: eccolo:
public void testDrawNextTwoGems()
{
MockEngine engine = new MockEngine();
grid.draw(engine);
assertEquals(3, engine.getNumberOfQuadsDrawn());
}
però mi sa che andranno modificati anche un altro paio di test sempre di Grid.draw perché grid a questo punto ogni volta disegna due sprites in più.
L'idea di inserire il codice per quel riquadro dentro a Grid non mi piace molto ma non ho alternative per il momento quindi per ora puoi continuare con la tua soluzione.
ciao ;)
Voglio prenotarmi per il task 4, prevedo di impiegare 2 giorni.
Voglio prenotarmi per il task 4, prevedo di impiegare 2 giorni.
Cavolo quanta energia :D
Tutto tuo. procedi pure.
ciao ;)
L'idea di inserire il codice per quel riquadro dentro a Grid non mi piace molto ma non ho alternative per il momento quindi per ora puoi continuare con la tua soluzione.
ciao ;)
Scusate, ma non si tratta soltanto di disegnare delle gemme ad una data coordinata ?!?!?
La classe GemQueue contiene una funzione getGemAt che permette di ottenereuna gemma in una data posizione della coda...
Non basterebbe fare una classe derivata da Drawable che nel metodo draw disegna le due gemme ?
Dopo basta metterla nel LayerManager...
Scusate, ma non si tratta soltanto di disegnare delle gemme ad una data coordinata ?!?!?
La classe GemQueue contiene una funzione getGemAt che permette di ottenereuna gemma in una data posizione della coda...
Non basterebbe fare una classe derivata da Drawable che nel metodo draw disegna le due gemme ?
Dopo basta metterla nel LayerManager...
Credo tu abbia ragione, dopotutto non abbiamo bisogno di avere delle gemme reali e funzionanti al 100%... ci bastano due png coerenti col tipo di gemme presenti in coda nelle prime due posizioni ;)
Scusate, ma non si tratta soltanto di disegnare delle gemme ad una data coordinata ?!?!?
La classe GemQueue contiene una funzione getGemAt che permette di ottenereuna gemma in una data posizione della coda...
Non basterebbe fare una classe derivata da Drawable che nel metodo draw disegna le due gemme ?
Dopo basta metterla nel LayerManager...
Ecco questa soluzione mi piace molto di piu :D
ciao ;)
Scusate, ma non si tratta soltanto di disegnare delle gemme ad una data coordinata ?!?!?
La classe GemQueue contiene una funzione getGemAt che permette di ottenereuna gemma in una data posizione della coda...
Non basterebbe fare una classe derivata da Drawable che nel metodo draw disegna le due gemme ?
Dopo basta metterla nel LayerManager... ieri ho avuto una visione di fek che cantava come al bano:
SEEEMPLICITA'AAAAA!!!!!!
:rotfl:
comunque ho committato :p
Ecco questa soluzione mi piace molto di piu :D
ciao ;) doh... lo devo rifare...? -.-
doh... lo devo rifare...? -.-
Refactoring ? :stordita:
ciao ;)
Refactoring ? :stordita: ma non capisco perché dovrei farlo, non farei altro che aumentare le righe di codice... se faccio una classe apposta suppongo che questa classe (oltre a dover fare paro paro quello che già fa Grid chiamando drawFirst e drawSecond) dovrà essere istanziata in Grid; perché mai isolare all'interno di un oggetto dentro Grid del codice che funziona già tranquillamente in Grid stessa?? secondo te col sistema della classe elimino le due funzioni drawFirst e drawSecond? e invece no :D perché Grid non usa GemQueue, Grid usa GemGenerator che non ha (giustamente) getGemAt :Prrr:
ma non capisco perché dovrei farlo, non farei altro che aumentare le righe di codice... se faccio una classe apposta suppongo che questa classe (oltre a dover fare paro paro quello che già fa Grid chiamando drawFirst e drawSecond) dovrà essere istanziata in Grid; perché mai isolare all'interno di un oggetto dentro Grid del codice che funziona già tranquillamente in Grid stessa?? secondo te col sistema della classe elimino le due funzioni drawFirst e drawSecond? e invece no :D perché Grid non usa GemQueue, Grid usa GemGenerator che non ha (giustamente) getGemAt :Prrr:
Ecco lo sapevo non mi sonospiegato bene :muro:
Quello che mi preoccupa è che Grid sta lentamente diventando una classe World. Lo scopo di Grid è gestire la griglia dell'area di gioco e le gemme al suo interno, quindi quando viene chiamato il suo draw() deve disegnare le gemme della griglia e basta. Allo stesso modo lo scopo di GemGenerator è quello di "generare" le gemme e basta, non dovrebbe preoccparsi minimamente di disegnare qualcosa sullo schermo.
Quello che secondo me dovrestio fare è:
Creare una classe tipo TinyWinnyDisplay che accetta una GemQueue come argomento piu le coordinate a cui disegnare le due gemme. Questa classe dovrebbe implementare Drawable.
Mettere il codice che hai scritto per drawFirst e drawSecond è semplicissimo e va bene anche in una singola funzione.
A questo punto la va istanziata all'interno di Game e non Gem altrimenti ricadiamo nello stesso errore di prima. mentre la istanzi la aggiungi ad un layer come ha suggerito cionci ed il gioco è fatto.
ps: Trova un nome piu carino per la classe :p
ciao ;)
ma il task4 lo hai dato a me o a thebol? :p
ma il task4 lo hai dato a me o a thebol? :p
Ah cavolo. Non avevo modificato il primo post la prima volta :muro:
Contatta thebol e fatelo in pair-programming qui sul forum :D
ciao ;)
A me va benissimo ma ho riletto un attimino il thread e mi pare che lui non abbia manco fatto richiesta per fare il quarto task :p
A me va benissimo ma ho riletto un attimino il thread e mi pare che lui non abbia manco fatto richiesta per fare il quarto task :p
:doh: Oggi devo aver lavorato troppo.
Ho sistemato tutto. Spero per l'ultima volta :D
caio ;)
A me va benissimo ma ho riletto un attimino il thread e mi pare che lui non abbia manco fatto richiesta per fare il quarto task :p
si, io mi ero prenotato per il secondo(gia completato e committato) :)
carina la storia del pp, ma sono via fino a domenica ;)
beh tanto io non posso iniziare finchè non finisce il 6.2.3 :p
si, io mi ero prenotato per il secondo(gia completato e committato) :)
carina la storia del pp, ma sono via fino a domenica ;)
Non hai postato la task list prima di iniziare il task. Questa non e' una gara di velocita' a chi finisce prima i propri task e il revert e' sempre in agguato.
Aggiungo alle nostre regolette il "Postare sempre la test list PRIMA di mettere mano al codice".
Non hai postato la task list prima di iniziare il task. Questa non e' una gara di velocita' a chi finisce prima i propri task e il revert e' sempre in agguato.
Ha postato il codice e i test in un messaggio a pagina 1 prima di fare il commit.
ciao ;)
Ecco lo sapevo non mi sonospiegato bene :muro:
Quello che mi preoccupa è che Grid sta lentamente diventando una classe World. Lo scopo di Grid è gestire la griglia dell'area di gioco e le gemme al suo interno, quindi quando viene chiamato il suo draw() deve disegnare le gemme della griglia e basta. Allo stesso modo lo scopo di GemGenerator è quello di "generare" le gemme e basta, non dovrebbe preoccparsi minimamente di disegnare qualcosa sullo schermo.
Quello che secondo me dovrestio fare è:
Creare una classe tipo TinyWinnyDisplay che accetta una GemQueue come argomento piu le coordinate a cui disegnare le due gemme. Questa classe dovrebbe implementare Drawable.
Mettere il codice che hai scritto per drawFirst e drawSecond è semplicissimo e va bene anche in una singola funzione.
A questo punto la va istanziata all'interno di Game e non Gem altrimenti ricadiamo nello stesso errore di prima. mentre la istanzi la aggiungi ad un layer come ha suggerito cionci ed il gioco è fatto.
ps: Trova un nome piu carino per la classe :p
ciao ;)
mumble :mbe:
mumble :mbe:
:O ma se...!! mumble :mbe:
ok :D
(per fortuna che avevo detto 2 giorni anziché 1 :D sesto senso?? :p)
cdimauro
09-12-2005, 16:26
A mio avviso il mio task dovrebbe fare delle cose diverse, per lo meno rileggendo anche quanto ha scritto Jocchan. Dovrebbe essere diviso in due parti:
1) modificare Sprite in modo che permetta l'impostazione del frame number e dello "status" (che Gem utilizzerebbe poi per la brillantezza).
2) modificare Gem in modo da implementare l'animazione ogni decimo di secondo e lasciando il primo frame per 3,5 secondi quando finisce l'animazione.
In questo modo i test da fare sarebbero i seguenti.
Per Sprite:
1) testare che l'impostazione di un numero di frame o di stato fuori dai rispettivi intervalli generi un'eccezione;
2) testare che l'impostazione di un preciso numero di frame o di stato sia corretta.
Per Gem:
1) testare che, partendo dallo stato iniziale, gli aggiornamenti dell'animazione producano la seguente sequenza per quanto riguarda il numero del frame corrente (considerando l'aggiornamento ogni decimo di secondo):
0 1 2 ... n 0 (350 volte) 1 2 ...
oppure (ma questo me lo deve dire Jocchan)
0 (350 volte) 1 2 ... n 0 (350 volte) 1 2 ...
dove n è il numero di frame associati a una gemma.
Se tutto va bene, compresi i test, mi metto all'opera per completare il mio task.
ho committato il nuovo task 6.2.1: adesso ho creato una nuova classe NextGemIndicator che implementa Drawable e vuole un oggetto GemQueue nel costruttore; c'è un solo test che verifica col MockEngine che questa classe disegni due sprites, ma un aspetto del codice è rimasto non testato: come hai detto VICIUS, Game istanzia un oggetto NextGemIndicator e lo mette nel LayerManager, ed è proprio questo l'aspetto che non so testare :p
ho committato il nuovo task 6.2.1: adesso ho creato una nuova classe NextGemIndicator che implementa Drawable e vuole un oggetto GemQueue nel costruttore; c'è un solo test che verifica col MockEngine che questa classe disegni due sprites, ma un aspetto del codice è rimasto non testato: come hai detto VICIUS, Game istanzia un oggetto NextGemIndicator e lo mette nel LayerManager, ed è proprio questo l'aspetto che non so testare :p
Ottimo.
Per testare l'ultimo aspetto puoi creare un Mock di LayerManager e usare quello per verificare che l'inserimento sia corretto.
Per testare l'ultimo aspetto puoi creare un Mock di LayerManager e usare quello per verificare che l'inserimento sia corretto.
Mmmmhh...questo dovrebbe essere già stato testato... Nel senso che se inserisco una classe che implementa drawable dovrebbe essere già garantito che draw venga chiamata dal layer manager... Infatti questa cosa dovrebbe essere già stata testata...
Poi l'inserimento nel layer manager avviene solamente in Game.java che se non sbaglio non dobbiamo testare...
cdimauro
10-12-2005, 09:48
Ho eseguito il commit, ma ho notato un problema: tutte le gemme hanno il frame base + 5 altri frame + uno spazio (che sembra pari ad altri 2 frame) vuoto/trasparente, per cui dopo il sesto frame si nota che la gemma "scompare".
Questo perché ho esteso Sprite e Gem in modo da caricare immagini aventi un numero qualunque di frame (e "stati": attualmente usati per indicare una gemma "normale" o "illuminata").
Quindi se per caso si dovesse decidere di aumentare il numero di frame per le animazioni, il tutto verrebbe gestito in maniera trasparente.
E' possibile avere le gemme disegnate in modo che non esistano spazi vuoti alla fine? Oppure devo rimettere mano al codice in modo da specificare sempre e comunque 1 frame base + 5 di successivi per le animazioni?
Poi volevo segnalare alcune cose.
1) Lasciando cadere le gemme sulla stessa colonna, appena si arriva in cima viene generata un'eccezione.
2) Dalle specifiche del task dovevo leggere l'ammontare di tempo (3,5 secondi) dal file di configurazione; l'ho fatto, ma per "scrivere il codice minimale che permetta di completare il task", nel costruttore di Gem creo un'istanza di Config, carico il file, e prelevo i parametri che mi servono; quindi ciò si verifica OGNI VOLTA che viene creata una gemma; non è una bella soluzione e secondo me dovremmo trovare il modo di poter accedere all'unica istanza di Config presente nel gioco.
3) Nel codice, in generale, c'è una quantità immane di cast dovuti al fatto che, anche per le stesse cose, si usano float o int indifferentemente; questo, a mio avviso, è una perdita di tempo non solo per la CPU (di questo possiamo anche fregarcene, per il momento), ma soprattutto per il programmatore che deve perdere tempo a scrivere i cast; oppure scrive del codice, non si accorge della differenza, e poi deve tornarci perché il compilatore s'incazza; non potremmo utilizzare soltanto gli int quando servono degli interi e soltanto dei float quando servono dei float?
Ehm...non ho capito come mai ci sono quei frame vuoti...
3) Nel codice, in generale, c'è una quantità immane di cast dovuti al fatto che, anche per le stesse cose, si usano float o int indifferentemente; questo, a mio avviso, è una perdita di tempo non solo per la CPU (di questo possiamo anche fregarcene, per il momento), ma soprattutto per il programmatore che deve perdere tempo a scrivere i cast; oppure scrive del codice, non si accorge della differenza, e poi deve tornarci perché il compilatore s'incazza; non potremmo utilizzare soltanto gli int quando servono degli interi e soltanto dei float quando servono dei float?
Diciamo che la conversione era da terminare... Passando la Rectangle a int la dimensioni devono passare a int...
1) è normale... Comunque il gioc dovrebbe terminare perchè è una situazione non gestita...
2) devi passare una istanza di Config a Gem (e a GemQueue) nel costruttore...
Puoi fare anche in modo che il valore sia uno static int all'interno di Gem e venga preso solo una volta dal config...
Puoi fare anche in modo che il valore sia static e venga preso solo una volta
No, ci deve essere una sola istanza di Config che viene propagata in tutto il gioco...
Ah ma questo non ti vieterebbe di propagarla comunque :)
I due frame vuoti ci sono per la necessità di avere una texture con dimensioni in potenza di due (servono infatti per arrivare a quelle dimensioni).
Non è possibile modificare il codice in modo che, per questa particolare animazione, ci si fermi prima del frame vuoto?
Questo perchè in futuro potremmo avere delle animazioni in cui, per arrivare appunto a quelle dimensioni, serva dello spazio vuoto, che però potrebbe:
a) non avere le dimensioni esatte di un frame, ma essere troppo piccolo
b) essere troppo grande (ricordiamo che le dimensioni aumentano esponenzialmente... se ci servono 514px dovremo usare una texture di altezza 1024!), quindi aggiungere dei frame "base" per riempire lo spazio farebbe perdere parecchio tempo tra un'animazione e l'altra
Ah ma questo non ti vieterebbe di propagarla comunque :)
Cioè ?
Io avevo proposto di usare un design pattern Singleton, ma a Francesco non paice :D Giustamente... Però a questo punto anche se sporco, potrebbe essere comunque una soluzione :)
Non basterebbe tenere conto del numero di frame realmente utilizzati?
Io avrei usato un altro metodo... Avrei fatto un metodo addFrame in Sprite che prende in ingresso la posizione...e poi avrei collezionato le posizioni in un arrayList... In questo modo non si lascia a Grid l'incombenza di calcolare la posizione...
I due frame vuoti ci sono per la necessità di avere una texture con dimensioni in potenza di due (servono infatti per arrivare a quelle dimensioni).
Giusto :)
Ottima idea! Basta trovare il modo di distinguere i frame "illuminati" da quelli "normali" :)
Penso sarebbe ottimo tenerselo come refactoring ed ora andare per la via più semplice :)
Ottima idea! Basta trovare il modo di distinguere i frame "illuminati" da quelli "normali" :)
Basta usare la setState che ha implementato Cesare... Magari modificandola leggermente... In pratica a seconda dello "stato" ci si sposta orizzontalmente sulla texture...
cdimauro
10-12-2005, 10:55
Diciamo che la conversione era da terminare... Passando la Rectangle a int la dimensioni devono passare a int...
OK, quindi è un problema che è destinato a essere risolto. Ottimo. :)
A me era venuta la tentazione di cambiare alcuni float in int in Sprite e Gem, ma poi mi sono detto: non so serveno realmente come float, per cui evito altrimenti rischio di far danni.
2) devi passare una istanza di Config a Gem (e a GemQueue) nel costruttore...
Va bene. Io per adesso non procedo perché il task funziona, ma avviso è meglio decidere se tenere un'istanza globale accessibile da tutti oppure passare Config a tutte le classi che lo richiedono.
Personalmente non sono contro le variabili globali.
Ora sto facendo un refactoring di Sprite per elimanre diverse duplicazioni (fra hight, width e frameArea)...
cdimauro
10-12-2005, 11:04
I due frame vuoti ci sono per la necessità di avere una texture con dimensioni in potenza di due (servono infatti per arrivare a quelle dimensioni).
E' la seconda volta che capita un problema a causa delle dimensioni che devono essere necessariamente potenze di due.
Non è possibile modificare il codice in modo che, per questa particolare animazione, ci si fermi prima del frame vuoto?
Certo che si può fare. Le pezze al codice si possono mettere sempre.
Anche se a me generalmente non piace farvi ricorso.
Questo comporterà che ogni volta dobbiamo sapere esattamente di quanti frame è composta l'animazione di una gemma, o in generale di uno sprite: sono valori che vanno messi "a mano", quando invece col codice che ho attualmente scritto viene gestito tutto automaticamente.
Questo perchè in futuro potremmo avere delle animazioni in cui, per arrivare appunto a quelle dimensioni, serva dello spazio vuoto, che però potrebbe:
a) non avere le dimensioni esatte di un frame, ma essere troppo piccolo
b) essere troppo grande (ricordiamo che le dimensioni aumentano esponenzialmente... se ci servono 514px dovremo usare una texture di altezza 1024!), quindi aggiungere dei frame "base" per riempire lo spazio farebbe perdere parecchio tempo tra un'animazione e l'altra
Chiarissimo. Io vorrei però che riflettessimo sul fatto che continuano a sorgere problemi e soprattutto continuiamo a perdere tempo a causa di un dettaglio che non era un requisito di progetto.
Penso che ai grafici non dispiacerebbe non mettersi a controllare ogni volta se la dimensione orizzontale e verticale sono delle potenze di due, ai programmatori neppure di trovarsi davanti a un problema causato dallo stesso motivo.
Ci stiamo complicando la vita.
cdimauro
10-12-2005, 11:06
Io avrei usato un altro metodo... Avrei fatto un metodo addFrame in Sprite che prende in ingresso la posizione...e poi avrei collezionato le posizioni in un arrayList... In questo modo non si lascia a Grid l'incombenza di calcolare la posizione...
Soluzioni se ne possono trovare quante ne vogliamo. Ma questo implica il dover scrivere del codice che, sulla carta, non sarebbe servito.
Ci stiamo complicando la vita, appunto.
In realtà, Cesare, credo sia una cosa di OpenGL...
Ma questo implica il dover scrivere del codice che, sulla carta, non sarebbe servito.
Ci stiamo complicando la vita, appunto.
Secondo me è il contrario...il codice che non dovevamo implementare è proprio quello che gestiva un'animazione generica... La texture con le varie gemme faceva parte del task e di conseguenza il task si doveva basare su quella...
cdimauro
10-12-2005, 11:11
x Ufo13. Sì, lo so. Infatti il problema era già nato, ed era stato risolto limitatamente al caricamento delle immagini nelle texture, ma adesso ne è sorto un altro a causa di questa soluzione.
Comunque una semplice soluzione sarebbe quella che, alla creazione della gemma, venisse indicato anche di quanti frame è composta l'animazione.
Al momento possiamo metterlo "hard coded" nel costruttore della gemma, per non toccare nessun'altra parte del codice che utilizza la classe Gem.
x Ufo13. Sì, lo so. Infatti il problema era già nato, ed era stato risolto limitatamente al caricamento delle immagini nelle texture, ma adesso ne è sorto un altro a causa di questa soluzione.
Comunque una semplice soluzione sarebbe quella che, alla creazione della gemma, venisse indicato anche di quanti frame è composta l'animazione.
Al momento possiamo metterlo "hard coded" nel costruttore della gemma, per non toccare nessun'altra parte del codice che utilizza la classe Gem.
Una volta decisa la dimensione di un frame, credo basti una specie di setFramesNumber(int frames)
cdimauro
10-12-2005, 11:14
Secondo me è il contrario...il codice che non dovevamo implementare è proprio quello che gestiva un'animazione generica... La texture con le varie gemme faceva parte del task e di conseguenza il task si doveva basare su quella...
L'errore che ho commesso è stato quello di non aver controllato preventivamente una qualunque gemma, anche col Paint.
Mi sono basato sul messaggio di Jocchan che mostrava una gemma con le varie animazioni, ma non ho fatto caso allo spazio vuoto che c'era sotto: essendo la PNG trasparente, non mi sono accorto che poteva esserci dello spazio in più.
cdimauro
10-12-2005, 11:17
Una volta decisa la dimensione di un frame, credo basti una specie di setFramesNumber(int frames)
Per adesso basterebbe modificare setSize di Sprite, in modo che numFrames venga settato a 6 anziché calcolato basandosi sulla dimensione verticale della texture e della gemma.
Così risolviamo subito il problema. C'è qualcuno che può farlo? Io in questo momento non posso usare il portatile dove tengo Eclipse.
Secondo me è il contrario...il codice che non dovevamo implementare è proprio quello che gestiva un'animazione generica... La texture con le varie gemme faceva parte del task e di conseguenza il task si doveva basare su quella...
Sono d'accordo... Sarebbe meglio agire solo a livello di Gem per quanto possibile (come avevo fatto per l'effetto illuminazione)... Implementare animazioni nelle sprite, come richiesto dal task, potrebbe essere un "guardare avanti" :)
Implementare animazioni nelle sprite, come richiesto dal task, potrebbe essere un "guardare avanti" :)
Non intendevo questo... Implementare le animazioni nella Sprite va più che bene, ma secondo me deve essere Gem in toto a gestire l'animazione e non Grid...
Ed in Gem va gestita non in maniera generica...
Il fatto delle potenze di due è sicuramente una limitazione, anche io mi stavo scordando di aggiungere lo spazio vuoto in basso. Purtroppo però ci serve per avere compatibilità con le OpenGL 1.1, quindi dobbiamo - a malincuore - farci il callo :(
x Cesare: secondo me per ora si potrebbe togliere questo codice
numFrames = (int)(texture.getHeight() / this.height);
numStates = (int)(texture.getWidth() / this.width);
e creare due metodi appositi setStatesNumber e setFramesNumber. Sarà poi Gem a settarseli come richiesto :)
è la soluzione più semplice che mi viene in mente ora... Poi il resto si può fare come refactoring quando si ha tempo... Mi ci metto anche subito :)
cdimauro
10-12-2005, 11:31
Per adesso metti
numFrames = 6;
Poi si deciderà come affrontare il problema più in generale, e decideremo cosa fare. Niente overengineering. ;)
questo non è un overEngineering è un Refactoring :)
comunque metto 6 così posso iniziare a lavorare al mio task e poi decidi tu il da farsi :)
cdimauro
10-12-2005, 11:35
Non intendevo questo... Implementare le animazioni nella Sprite va più che bene, ma secondo me deve essere Gem in toto a gestire l'animazione e non Grid...
Ed in Gem va gestita non in maniera generica...
Se è per questo il task diceva di implementare le animazioni in Sprite.
Quindi, se avessi dovuto seguire letteralmente il task, puoi immaginare i casini che ne sarebbero derivati. :p
E' vero che nel task non era scritto di implementare le animazioni in maniera generica, ma non era nemmeno scritto di pensare soltanto a Gem (e Grid eventualmente). ;)
Aspetta Ufo13...sto facendo un refactoring per elimnare alcune ripetizioni...
Cesare: mi ptoresti spiegare perchè la grandezza dello sprite può essere diversa dalla frameArea ?
Questo perché ho esteso Sprite e Gem in modo da caricare immagini aventi un numero qualunque di frame (e "stati": attualmente usati per indicare una gemma "normale" o "illuminata").
Quindi se per caso si dovesse decidere di aumentare il numero di frame per le animazioni, il tutto verrebbe gestito in maniera trasparente.
YAGNI. Non fare il commit di questo. Risolvi solo e nient'altro del problema richiesto per favore. E la test list prima.
3) Nel codice, in generale, c'è una quantità immane di cast dovuti al fatto che, anche per le stesse cose, si usano float o int indifferentemente; questo, a mio avviso, è una perdita di tempo non solo per la CPU (di questo possiamo anche fregarcene, per il momento), ma soprattutto per il programmatore che deve perdere tempo a scrivere i cast; oppure scrive del codice, non si accorge della differenza, e poi deve tornarci perché il compilatore s'incazza; non potremmo utilizzare soltanto gli int quando servono degli interi e soltanto dei float quando servono dei float?
Io e cionci stiamo pian piano risolvendo questi problemi con i float.
allora fai tu, che è una cosa velocissima da fare, così inizio a lavorare al mio task :)
cdimauro
10-12-2005, 11:39
Il fatto delle potenze di due è sicuramente una limitazione, anche io mi stavo scordando di aggiungere lo spazio vuoto in basso. Purtroppo però ci serve per avere compatibilità con le OpenGL 1.1, quindi dobbiamo - a malincuore - farci il callo :(
Non è questo il discorso, IMHO: che ci sia questa limitazione è evidente e purtroppo dobbiamo prenderne atto, ma cerchiamo di fare in modo che NON influenzi la scrittura del resto del codice.
Questo vuol dire, in soldoni, mantenere questo dettaglio implementativo limitato esclusivamente all'interno della classe Texture (ed eventualmente di Sprite, ma soltanto a livello di implementazione, appunto), e fare in modo che (all'apparenza) si abbia a che fare con sprite di dimensione qualsiasi.
Ah ma questo non ti vieterebbe di propagarla comunque :)
Ma questo rendererebbe fek molto nervoso, perche' non gli piacciono i singleton :)
Preferisco che l'istanza di Config sia passata dove necessario.
cdimauro
10-12-2005, 11:41
questo non è un overEngineering è un Refactoring :)
Ma se introduci il metodo setNumFrames devi aggiungere anche il relativo test. ;)
comunque metto 6 così posso iniziare a lavorare al mio task e poi decidi tu il da farsi :)
Lavora al tuo task, e non ti preoccupare: finisci il tuo compito. Per il resto, decideranno coach e/o customer sul da farsi. :D
Io avrei usato un altro metodo... Avrei fatto un metodo addFrame in Sprite che prende in ingresso la posizione...e poi avrei collezionato le posizioni in un arrayList... In questo modo non si lascia a Grid l'incombenza di calcolare la posizione...
Questa e' la soluzione piu' comune usata in queste situazioni e risolve bene anche il nostro problema a mio avviso.
cdimauro
10-12-2005, 11:42
Vado a mangiare un boccone. Ne parliamo dopo.
[QUOTE=cdimauro]Ma se introduci il metodo setNumFrames devi aggiungere anche il relativo test. ;)
infatti appena me ne sono reso conto ci ho ripensato :D
Non intendevo questo... Implementare le animazioni nella Sprite va più che bene, ma secondo me deve essere Gem in toto a gestire l'animazione e non Grid...
Ed in Gem va gestita non in maniera generica...
Ragazi, state usando Grid come classe spazzatura, quando non sapete dove mettere qualcosa la buttate in Grid. E questo non mi piace affatto.
Non voglio dover imporre la regola di non scrivere piu' nulla in Grid se non espressamente richiesto da un task pena il revert. Cercate di autoregolarvi su questo e di pensare sempre due volte a dove potete mettere il codice e non in Grid.
Ma questo rendererebbe fek molto nervoso, perche' non gli piacciono i singleton :)
Fek nervoso... :ops:
:D
Non è questo il discorso, IMHO: che ci sia questa limitazione è evidente e purtroppo dobbiamo prenderne atto, ma cerchiamo di fare in modo che NON influenzi la scrittura del resto del codice.
Questo vuol dire, in soldoni, mantenere questo dettaglio implementativo limitato esclusivamente all'interno della classe Texture (ed eventualmente di Sprite, ma soltanto a livello di implementazione, appunto), e fare in modo che (all'apparenza) si abbia a che fare con sprite di dimensione qualsiasi.
In che modo? Il numero di frame di un'animazione non ha nulla a che fare con la dimensione della texture che contiene tutti i frame.
Se per avere un pg immobile ci vogliono 4 frame, per fargli tirare un pugno 7, e la texture può contenerne 10, non possiamo riempirla con 6 frame inutili (ripetendo più volte il ciclo) per farlo stare fermo, dato che tra l'altro - oltre a perdere in reattività - avremmo un numero non coerente con un ciclo completo, e nemmeno usare 10 frame più "brevi" per l'animazione che ne richiederebbe 4, dato che - oltre alla mole di lavoro per disegnare i frame intermedi - sarebbe molto più fluida delle altre (e la cosa si noterebbe).
Insomma, dobbiamo riuscire a gestire le animazioni in modo che possa esserci dello spazio vuoto, e che questo non venga visualizzato.
Per le gemme si può anche dare un valore costante, dato che poi tutte avranno sempre questo valore e basta, ma per gli sprite complessi (i personaggi) dovremo inventarci qualcosa.
Ok, ho letto dei vari problemi con SetNumFrames e SetNumStates e con i frame di animazione, dove calcolari e dove non calcolari.
La soluzione e' semplice: revert e si riparte daccapo con il task.
Ed in pair programming sul forum. Chi si prenota?
Fek nervoso... :ops:
:D
Ricordi che i DF impararono a loro spese a non farmi innervosire in Roger Wilco :D
io se si riesce a partire subito perchè per le 17 vado a snowboardare e torno stanotte :p
Ricordi che i DF impararono a loro spese a non farmi innervosire in Roger Wilco :D
hahah me ne hanno parlato quando ho giocato insieme a loro :D
cdimauro
10-12-2005, 12:15
Cesare: mi ptoresti spiegare perchè la grandezza dello sprite può essere diversa dalla frameArea ?
Non ho capito cosa intendi: potresti essere più chiaro, per favore?
cdimauro
10-12-2005, 12:20
YAGNI. Non fare il commit di questo. Risolvi solo e nient'altro del problema richiesto per favore.
Allora basta soltanto impostare
numFrames = 3;
numStates = 2;
In setSize. ;)
E la test list prima.
Parli di codice Java o semplicemente una descrizione dei test da effettuare? Nel secondo caso, l'avevo scritta prima (a pagina 3, mi pare) e il codice Java dei test ricalca esattamente quella descrizione.
Se serve scrivere il codice di test in Java, la prossima volta farò così.
Cesare se hai tempo fino alle 5 possiamo farlo in pair :p
cdimauro
10-12-2005, 12:21
Ma questo rendererebbe fek molto nervoso, perche' non gli piacciono i singleton :)
Una curiosità: come mai?
Preferisco che l'istanza di Config sia passata dove necessario.
La prossima volta ne terrò conto. :D
cdimauro
10-12-2005, 12:26
Ragazi, state usando Grid come classe spazzatura, quando non sapete dove mettere qualcosa la buttate in Grid. E questo non mi piace affatto.
Non voglio dover imporre la regola di non scrivere piu' nulla in Grid se non espressamente richiesto da un task pena il revert. Cercate di autoregolarvi su questo e di pensare sempre due volte a dove potete mettere il codice e non in Grid.
OK. Io in Grid ho soltanto messo il codice (in update()) che serve a richiamare updateAnimation() a ogni istanza di Gem appartenente alla griglia. E' poi Gem a effettuare i calcoli relativi all'animazione, visto che è una cosa che le compete strettamente.
Quest'approccio va bene o va cambiato?
cdimauro
10-12-2005, 12:27
Cesare se hai tempo fino alle 5 possiamo farlo in pair :p
Alle 5 mi trovi ancora al Planet, a Catania, a guardare Harry Potter. :D
Mi spiace, ma avevo già preso quest'impegno con mia moglie.
Tral'altro fek non ha fatto il revert ancora :) beh se non si offre nessuno (cionci?) io passo ed aspetto domani per iniziare il mio task :)
cdimauro
10-12-2005, 12:35
In che modo? Il numero di frame di un'animazione non ha nulla a che fare con la dimensione della texture che contiene tutti i frame.
Se per avere un pg immobile ci vogliono 4 frame, per fargli tirare un pugno 7, e la texture può contenerne 10, non possiamo riempirla con 6 frame inutili (ripetendo più volte il ciclo) per farlo stare fermo, dato che tra l'altro - oltre a perdere in reattività - avremmo un numero non coerente con un ciclo completo, e nemmeno usare 10 frame più "brevi" per l'animazione che ne richiederebbe 4, dato che - oltre alla mole di lavoro per disegnare i frame intermedi - sarebbe molto più fluida delle altre (e la cosa si noterebbe).
Insomma, dobbiamo riuscire a gestire le animazioni in modo che possa esserci dello spazio vuoto, e che questo non venga visualizzato.
Per le gemme si può anche dare un valore costante, dato che poi tutte avranno sempre questo valore e basta, ma per gli sprite complessi (i personaggi) dovremo inventarci qualcosa.
Se vuoi implementare delle animazioni "generiche" dei personaggi (e da quello che scrivi sembra sarà necessario), il codice di sprite relativo alle animazioni va ripensato in toto.
A ogni personaggio sarà associata un'immagine (o più) che conterrà tutti i frame dell'animazione. Eventualmente servirà anche un altro file contenente l'elenco di tutti i rettangoli che rappresentano i fotogrammi.
Quando lavoravo a un piacchiaduro, avevamo una sola immagine contenente tutti i pezzi in cui erano stati suddivise le animazioni; avevamo anche un programmino che serviva a prendere ogni pezzo per comporre il frame del personaggio, e quindi generava un file di dati con tutte le informazioni necessarie a "ricomporre" ogni frame.
Ma non è questo il momento di pensarci: provvederemo quando se ne presenterà l'occasione.
cdimauro
10-12-2005, 12:38
Ok, ho letto dei vari problemi con SetNumFrames e SetNumStates e con i frame di animazione, dove calcolari e dove non calcolari.
La soluzione e' semplice: revert e si riparte daccapo con il task.
Ed in pair programming sul forum. Chi si prenota?
Francesco, per adesso con quelle modifiche minimali il task è risolto e Ufo13 può lavorare per completare il suo: non potremmo finire il ciclo e poi discuterne?
Francesco, per adesso con quelle modifiche minimali il task è risolto e Ufo13 può lavorare per completare il suo: non potremmo finire il ciclo e poi discuterne?
Allora perfetto. Quando ci servira' una soluzione piu' generica la implementeremo.
Scusa Cesare ma:
else
{
animationDelay = 10;
}
Non andrebbe settato a 5? L'animazione va in millisecondi e la distanza tra i frame dell'animazione dovrebbe essere 100ms. Visto che l'update viene fatto ogni 20ms andrebbe settato a 5 :)
Comunque non metterei numeri così hard coded altrimenti non si capisce + bene...
Francesco, per adesso con quelle modifiche minimali il task è risolto e Ufo13 può lavorare per completare il suo: non potremmo finire il ciclo e poi discuterne?
Ho guardato il codice, non mi piace proprio. setState non ha alcuna giustificazione di esistere per un solo stato, e' solo un'inutile complicazione. setFrame e' sovraingegnerizzata. E poi serve una soluzione tampone, tutto fuorche' semplice.
Puoi fare il revert per favore e ripartiamo daccapo con il task? Ti assicuro che e' la scelta migliore.
cdimauro
10-12-2005, 13:30
C'ho pensato anch'io provando a riposare (è inutile: se ho dei pensieri in testa non ci riesco proprio) qualche minuto sul divano, e sono d'accordo. Il codice si può buttare tutto.
Tra l'altro Sprite può anche non essere toccato di una virgola se al posto di Sprite nel testo del task mettiamo Gem (che poi penso che sia l'obiettivo da raggiungere, alla luce del testo del messaggio di Jocchan).
Io adesso sto andando al cinema con mia moglie: potrebbe fare qualcun'altro il revert?
Eventualmente sarei disponibile stasera, penso verso le 7, per lavorare in pair programming, se c'è qualcuno. Ma potrei anche lavorarci da solo: è un task che avevo preso io, e mi piacerebbe portare a termine un impegno.
Decidi tu.
A dopo
Ok, sto provando io a fare il revert.
Eventualmente sarei disponibile stasera, penso verso le 7, per lavorare in pair programming, se c'è qualcuno. Ma potrei anche lavorarci da solo: è un task che avevo preso io, e mi piacerebbe portare a termine un impegno.
Ufo e Cesare fate voi il task in pair programming allora?
E visto che tendete verso l'overengineering ultimamente, vi tengo d'occhio io pronto a spezzarvi i ditini alla prima riga di codice non necessaria :D
Ok, ho fatto un commit in cui ho modificato alcuni float in int. Poi ho fatto il merge con i cambiamenti di Cesare. Visto che c'era il mio merge di mezzo, il revert non puo' essere fatto automaticamente quindi mi servirebbe un volontario (:D) che si occupi di resuscitare setBrightnessStatus() ed eliminare setStatus() dalla faccia della terra.
Prima di qualunque modifica al codice fate l'update perche' ho toccato una carrellata di file in questo commit.
Faccio un attimino un refactoring per elimnare una ripetizione (le dimensioni dello sprite sono espresse sia in rectangle che esplicitate in Srpite)...poi vi lascio al strada libera...
Mi spiegate a cosa serve questo test ?
public void testSizeIsDifferentFromTextureArea()
{
sprite.setSize(14, 14);
MockEngine engine = new MockEngine();
sprite.draw(engine);
assertEquals(11, engine.getTextureRectRight());
assertEquals(11, engine.getTextureRectBottom());
}
Ho aggiunto due metodi (testati) a rectangle che credo possano essere utili e rendono sprite molto più leggibile:
public void resize(int width, int height)
{
bottom = top + height - 1;
right = left + width - 1;
}
public void translate(int left, int top)
{
bottom = top + getHeight() - 1;
right = left + getWidth() - 1;
this.top = top;
this.left = left;
}
Ho fatto il refactoring...quel test chiaramente fallisce, ma non riesco a capire perchè... Serve a deformare le texture ?
No ancora no...aspettavo di sapere qualcosa su quel test, che ovviamente non passa...
sto guardando il codice... magari dai un'occhiata alla storia relativa per vedere se ci sono informazioni sul test :)
modifica:
credo che volessero che texture e sprite fossero 2 entità differenti con 2 size differenti e che il setsize della sprite non cambiasse le dimensioni del rectangle disegnato (perchè?)
ovviamente il fatto che tu voglia far diventare le cose identiche fa fallire il test...
credo che volessero che texture e sprite fossero 2 entità differenti con 2 size differenti e che il setsize della sprite non cambiasse le dimensioni del rectangle disegnato (perchè?)
ovviamente il fatto che tu voglia far diventare le cose identiche fa fallire il test...
Sì, è questo...immagino che modificando width e height con setSize si faccia uno stretch della texture con le nuove dimensioni...
Grandezza di texture e sprite sono comunque indipendenti perchè le dimensioni di sprite si riferiscono all'area di texture visualizzata...
Sì, è questo...immagino che modificando width e height con setSize si faccia uno stretch della texture con le nuove dimensioni...
Credo di ricordare che servisse per far pulsare le gemme, ma visto che le gemme non pulsano piu' e al momento non c'e' alcuna richiesta di scaling degli sprite, uccidi pure il test e prosegui col refactoring.
Sì...era sicuramente per quel motivo...
fek: hai modificato qualcosa in checkstyle ?
Mi dice che queste righe sono duplicate, eppure non le ho toccate !!!
public void testInvalidHorizontalArgument()
{
try
{
@SuppressWarnings("unused")
Rectangle rectangle = new Rectangle(20, 10, 10, 25);
}
catch(IllegalArgumentException e)
{
return;
}
fail("Invalid argument exception not thrown");
}
public void testInvalidVerticalArgument()
{
try
{
@SuppressWarnings("unused")
Rectangle rectangle = new Rectangle(10, 20, 20, 15);
}
catch(IllegalArgumentException e)
{
return;
}
fail("Invalid argument exception not thrown");
}
Ho fatto apssare il checksyle modificando leggermente il testo delle fail :D Ma no capisco perchè prima passavo, forse perchè ho aggiunto due righe vuote sotto ?
Il problema era quello... Credo che checkstyle possa essere impostato per ignorare le linee vuote...
Comunque refactoring committato...date un'occhiate per vedere se vi piace...
Il problema era quello... Credo che checkstyle possa essere impostato per ignorare le linee vuote...
Comunque refactoring committato...date un'occhiate per vedere se vi piace...
Il controllo delle duplicazioni di checkstyle sta iniziando a diventarmi noiosetto ora.
cdimauro
10-12-2005, 17:25
Ufo e Cesare fate voi il task in pair programming allora?
Io sono appena rientrato e sono disponibile, se non ci sono altri refactoring.
Domani non sono disponibile, perché torno al mio paesino. Vediamo cosa dice Goldrake, io intanto accendo Trillian.
E visto che tendete verso l'overengineering ultimamente, vi tengo d'occhio io pronto a spezzarvi i ditini alla prima riga di codice non necessaria :D
Visto che mi servono, farò il bravo. :angel:
Posso fare io questo task allora? :)
Se qualcuno si vuole unire, chiamatemi in MSN.
Io io !!! :D
Abbiamo un volontario.
Ok...task 6.2.3 terminato...ed implicitamente abbiamo svolto anche il 6.2.4... Mi dispice, ma è venuto da solo...
La storia è chiusa?
Da bravo customer posso testare la nuova build?
fek sta facendo un po' di refactoring comunque credo che sia terminata... Se vuoi ti posso fare anche una build con le gemme che brillano a intervalli non regolari, giusto per vedere l'effetto...
fek sta facendo un po' di refactoring comunque credo che sia terminata... Se vuoi ti posso fare anche una build con le gemme che brillano a intervalli non regolari, giusto per vedere l'effetto...
La build machine crea automaticamente una build pronta dopo ogni commit.
La build machine crea automaticamente una build pronta dopo ogni commit.
Senza dubbio...ma io gli facevo uno spike...
fek sta facendo un po' di refactoring comunque credo che sia terminata... Se vuoi ti posso fare anche una build con le gemme che brillano a intervalli non regolari, giusto per vedere l'effetto...
Se puoi farlo ti ringrazio, intanto scarico l'ultima build disponibile ;)
fek: che ne dici di rendere costante (o quasi) il ciclo di update ? Man mano che il gioco va avanti il numeri di cicli all'interno del while di Gem.update aumentano linearmente... Certo niente di preuccupante, ma non vorrei che dopo TOT ore diventassero troppi...
fek: che ne dici di rendere costante (o quasi) il ciclo di update ? Man mano che il gioco va avanti il numeri di cicli all'interno del while di Gem.update aumentano linearmente... Certo niente di preuccupante, ma non vorrei che dopo TOT ore diventassero troppi...
Ma il numero di cicli nel while non dipende solo dal numero di frame di animazione?
while (timer.getTime() >= frameDuration)
Se sono passati 2 cicli di animazione (6 frame ciascuno), verranno fatte 12 iterazioni del while...
while (timer.getTime() >= frameDuration)
Se sono passati 2 cicli di animazione (6 frame ciascuno), verranno fatte 12 iterazioni del while...
Ma perche' questo non e' il codice che avevamo scritto che non aveva questo problema e dipendeva solo dal numero di frame :)
Cambialo pure, quest'implementazione e' sbagliata.
Ma perche' questo non e' il codice che avevamo scritto che non aveva questo problema e dipendeva solo dal numero di frame :)
Cambialo pure, quest'implementazione e' sbagliata.
Credovo che l'avessi fatto te il refactoring... Il refactoring l'ha fatto Ufo13...
Ti paice ?
public void update(AbstractTimer timer)
{
currentFrame = 0;
int frameDuration = getCurrentAnimationFrame().getDuration();
long timeStamp = timer.getTime();
while (timeStamp - lastCycleStart >= frameDuration)
{
advanceAnimation(timeStamp);
frameDuration += getCurrentAnimationFrame().getDuration();
}
int offset = 0;
if(this.bright)
{
offset = GEM_SIZE;
}
setTextureArea(
getCurrentAnimationFrame().getX() + offset,
getCurrentAnimationFrame().getY());
}
private void advanceAnimation(long timeStamp)
{
currentFrame++;
if (currentFrame == animationFrames.size())
{
currentFrame = 0;
lastCycleStart = timeStamp;
}
}
Sono ripartito dal suo codice... Altrimenti si fa un revert...
In questo modo non torna... Le gemme non brillano insieme...
A questo punto faccio il revert al tuo codice...
Credovo che l'avessi fatto te il refactoring... Il refactoring l'ha fatto Ufo13...
Era così anche prima io ho solo eliminato duplicazione :)
cionci: secondo me si può sistemare partendo dalla build aggiornata
Ho la connessione che mi va su e giù.... Mi si è già piantato Eclipse due volte...
cionci: secondo me si può sistemare partendo dalla build aggiornata
Fai pure...comunque il codice di fek e quello tuo non fanno la stessa cosa...
Guarda ad esempio le condizioni del while...
long deltaTime = 0;
deltaTime = timer.getTime() - lastTime;
currentTime += deltaTime;
int frame = 0;
int frameTime = frames.get(frame).getLength();
while (currentTime >= frameTime)
Comunqui fai pure...
scusami cionci ma se
currentTime = (ultimo update + differenza tra ultimo update ed ora)
vuol dire che currentTime = ora
quindi currentTime è giusto sostituirlo con timer.getTime() imho cmq sistemo ora :)
scusami cionci ma se
currentTime = (ultimo update + differenza tra ultimo update ed ora)
vuol dire che currentTime = ora
quindi currentTime è giusto sostituirlo con timer.getTime() imho cmq sistemo ora :)
No perche' currentTime e' locale ad ogni gemma e viene aggiornato dal delta di tempo che passa dall'ultimo aggiornamento.
Ora dovrebbe essere come prima...
riscrivo meglio :p
Per terminare il task 4 non dovremmo implementare i test comunque?
Tipo test su X gemme inserite in grid in tempi differenti e che abbiano sempre lo stesso frame anche dopo non so (3600*n)+100 secondi
No perche' currentTime e' locale ad ogni gemma e viene aggiornato dal delta di tempo che passa dall'ultimo aggiornamento.
Fek (aggiungo per favore :p) mi spieghi meglio? Io continuo a non capire la differenza... Tra le altre cose ho provato inserendo un contatore ed in entrambe le implementazioni fa solo 6 cicli al massimo...
Ogni oggetto Gem possiede questi due campi:
private long lastTime;
private long currentTime;
ad ogni update abbiamo questo codice:
long deltaTime = timer.getTime() - lastTime;
currentTime += deltaTime;
// alcune operazioni
lastTime = timer.getTime();
Io l'unica differenza che vedo è che non viene tenuto conto del tempo delle operazioni svolte al posto dei commenti (e secondo me non è corretto trascurarlo per quanto piccolo)...
secondo me dentro il while si può mettere tranquillamente timer.getTime() (ho provato con un contatore e funziona in maniera identica nella mia implementazione come nella precedente)...
Se per voi non è corretto vi prego di spiegarmi bene la cosa perchè sto andando in dissonanza cognitiva :D
Ok, salvo qualche insignificante ritocco la storia è chiusa in tempo, quindi ci aggiorniamo con uno speciale ciclo natalizio (per l'occasione lo chiameremo 6/bis).
Questo perchè siamo buoni, e per Natale non possiamo non farvi lavorare ;)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.