View Full Version : [CICLO 4] Storia 2
Storia: Introduzione del rilevamento del tasto giù, alla cui pressione la gemma deve accelerare il proprio movimento verso il basso causato dalla gravità.
Quando il tasto viene rilasciato, la velocità della gemma tornerà ad essere quella usuale di caduta. Il tutto va implementato senza dimenticare la possibilità di premere contemporaneamente a giù anche i tasti sinistra e destra, considerando tutte le possibili combinazioni (sinistra+destra+giù, sinistra+giù, destra+giù).
E' fondamentale che il gioco risponda prontamente ai comandi, distinguendo più pressioni immediatamente successive (anche in caso di situazioni concitate), ed evitando al contempo che ciò comporti spostamenti indesiderati della gemma, come spostamenti di più caselle in caso di una pressione leggermente più lunga del solito.
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
Stasera scriviamo i task. Scusate per il ritardo. Lavoriamo per voi :D
Ecco i task:
TASK:
4.2.1: Cionci: completato
Guando il tasto "Giù" è mantenuto premuto il valore della gravità usato da Grid deve essere moltiplicato per un fattore definito nel file di configurazione del gioco. Quando il tasto viene rilasciato deve ritornare ad essere quello originale.
4.2.2: 71104 + cdimauro: completato
Registrare in una coda all'interno di Input gli eventi "pressione" e "rilascio" dei vari tasti. Ad ogni evento deve essere associato il timestamp in cui l'evento è stato scatenato.
4.2.3: 71104
Modificare reactToInput di Grid per usare la coda creata nel task 4.2.2 in Input. Il comportamento attuale deve essere mantenuto inalterato.
4.2.4:
Una volta reagito ad un comando, reactToInput deve ricordare uno e un solo ulteriore comando richiesto durante il tempo di 'inattivita' e dovra' eseguirlo allo scadere del tempo stesso.
ciao ;)
Prima di iniziare il vostro task, chiedete chiarimenti su tutto cio' che non vi e' perfettamente chiaro.
Poi dateci la vostra test list, e possibilmente l'acceptance test.
Per il task 4.2.2, consiglierei di svolgerlo in Pair Programming sul forum, quindi prenotatevi in due.
Io saro' via Giovedi' e Venerdi', se qualcuno (cionci?) vuole svolgere un task con me possiamo farlo domani sera.
Buon lavoro :)
Azz...domani sera è probabile che io non sia a casa :muro:
Magari se sono a casa domani sera potremmo fare insieme il task 4.2.2 in pair programming...sempre che nessuno si sia prenotato per allora...
Per fare il 4.2.1 il mi sa che deve essere finito anche il task 4.2.2 o sbaglio ?
4.2.2 e' indipendente da 4.2.1, mentre 4.2.3 e 4.2.4 dipendono da da 4.2.2.
vorrei fare il 4.2.1, che è l'unico che mi è chiaro... ^^' stima 1 giorno.
ot: come mai stiamo implementando questa coda in Input? a me sembra che il sistema di input attuale vada bene: regolando un po' meglio qualche parametro (tipo quello del delay) io ho una buona sensazione, mi sembra che il gioco sia ben giocabile.
Allora mi prenoto per il task 4.2.1:
- il test dovrà verificare che impostando una data gravità e poi simulando la pressione del tasto giù, dopo una chiamata a reactToInput e una ad update, la gemma si sia spostata di X volte la gravità impostata...
Test di massima:
public void testReactionToDownKey
{
grid.insertGem(0, 4, gem);
grid.setGemUnderControl(gem);
grid.setGravity(10);
float oldYPosition = gem.getY();
config.addIntProperty("DownKeyGravityMultiplier", 4)
input.generateKey(KeyCode.vk_Down);
grid.reactToInput(input, timer);
grid.update();
assertEquals("gem doesn't move down as expected", gem.getY(), oldPosition + 40);
}
Modifiche da effettuare a Grid:
- aggiunta di un parametro Config al cotruttore
- modifica di reactToInput per gestire il tasto giù e la modifica della gravità
Azz...mi hai anticipato perchè mi sono messo a scrivere il test :cry:
Azz...mi hai anticipato perchè mi sono messo a scrivere il test :cry:
Visto che hai scritto il test lo assegno a te :p
Il test mi sembra buono apparte due cose. Il nome della proprieta è troppo lungo. GravityMultiplier va piu che bene. E quel 40 messo li cosi non mi piace. Io farei in questo modo cosi mettiamo anche il valore della gravita standard nel config e Jocchan ci puo giocare quanto gli pare.
assertEquals("gem doesn't move down as expected", gem.getY(), oldPosition +
(config.getIntProperty("Gravity") * config.getIntProperty("GravityMultiplier")));
ciao ;)
Io farei in questo modo cosi mettiamo anche il valore della gravita standard nel config e Jocchan ci puo giocare quanto gli pare.
)
Perfetto, così al termine del ciclo inizio a giocherellare con i valori fino a trovare quelli ottimali.
EDIT: Grazie Cionci per i dati di login!!!!!!
Ok...allora tempo stimato 1 giorno...
Jocchan: se li trovo nei PVT te li passo
Jocchan: la texture non è una potenza di due... La build si arresta...
Jocchan ha rotto la build :D
Qualcuno puo' fare il revert del background per favore?
Comunque la texture è una potenza di due...e nonostante tutto l'eccezione viene lanciata...
assertEquals("gem doesn't move down as expected", gem.getY(), oldPosition +
(config.getIntProperty("Gravity") * config.getIntProperty("GravityMultiplier")));
Una piccola nota su assertEquals, questa e' la forma corretta:
assertEquals(messaggio, valore_atteso, valore_testato);
Poi, preferirei che il valore da testare sia calcolato fuori dall'assert, perche' e' piu' leggibile, quindi:
float newPosition = oldPosition +
(config.getIntProperty("Gravity") * config.getIntProperty("GravityMultiplier"));
assertEquals("gem doesn't move down as expected", gem.getY(), newPosition);
Comunque la texture è una potenza di due...e nonostante tutto l'eccezione viene lanciata...
Allora il test e' errato, puoi aggiustarlo?
Edit: Mi correggo, il background e' 800x600, Jocchan ha proprio rotto la build :D
Queste funzioni ritornano 800 e 600 nonostante l'immagine sia 1024x1024 :confused:
height = ilGetInteger(IL_IMAGE_HEIGHT);
width = ilGetInteger(IL_IMAGE_WIDTH);
Come mai non falliva fino ad adesso ?
L'immagine e' 800x600. Ho fatto il revert al background precedente e ora i test passano.
Ora mi passano... Non capisco cosa succedeva...io facevo l'update e mi contninuava a ripristinare quella di Jocchan... :confused:
Visto che hai scritto il test lo assegno a te :p doh battuto per 11 minuti :doh:
be', allora mi prenoto per il Pair Programming del 4.2.2; chi è l'altro pollo? :D
Ho fatto il commit, date un'occhiata...
Il commento al commit l'avevo messo, ma la build machine non lo fa vedere perchè ho fatto un altro commit con la correzione di uno warning e fa vedere solo quello... E' possibile far apparire i commetti di tutti i commit intercorsi fra la build precedente e quella attuale ?
Il commento al commit l'avevo messo, ma la build machine non lo fa vedere perchè ho fatto un altro commit con la correzione di uno warning e fa vedere solo quello... E' possibile far apparire i commetti di tutti i commit intercorsi fra la build precedente e quella attuale ?
Dovrebbero apparire tutti i commenti sui singoli file affetti da ogni commit.
Ho fatto il commit, date un'occhiata...
Perfetto.
ciao ;)
Oops errore mio, dannate potenze di due :ciapet:
^TiGeRShArK^
09-11-2005, 14:14
ehm..
è possibile abilitare il server svn per permettere la modifica dei log?
ad esempio pure a me era capitato di aver dimenticato di inserire un commento, ma quando sono andato ad editarlo mi diceva ke il serve non era abilitato..
credo ke sarebbe un'opzione piuttosto utile vista le memoria e la sbadataggine dei componenti del gruppo :Prrr:
ehm..
è possibile abilitare il server svn per permettere la modifica dei log?
ad esempio pure a me era capitato di aver dimenticato di inserire un commento, ma quando sono andato ad editarlo mi diceva ke il serve non era abilitato..
credo ke sarebbe un'opzione piuttosto utile vista le memoria e la sbadataggine dei componenti del gruppo :Prrr:
era nelle cose da fare. dopo la creazione di un account diverso per ogni utente e un bel pre-commit hook per impedire messaggi vuoti. prima o poi risolviamo.
ciao ;)
be', allora mi prenoto per il Pair Programming del 4.2.2; chi è l'altro pollo? :D
Se vuoi lo facciamo insieme...anche se, visto che ho già fatto un task, mi sembra più giusto che lo facciano altri... Comunque io al limite domani dopo cena dovrei essere disponibile...
Se vuoi lo facciamo insieme...anche se, visto che ho già fatto un task, mi sembra più giusto che lo facciano altri... Comunque io al limite domani dopo cena dovrei essere disponibile... veramente ieri mi ha contattato ciddimauro in MSN dicendomi che lo voleva fare anche lui, però ieri sera non abbiamo potuto perché io e lui abbiamo orari incompatibili: io torno la sera dall'università e quindi lavoro sempre di sera, lui invece è disponibile a lavorare *prima* di tornare a casa la sera perché a casa non ha il pc (rotto mi pare di aver capito); ieri lui mi ha trovato in MSN qualche minuto prima di tornare a casa, ma era meglio evitare di fare il task in fretta e furia in pochi minuti, allora lui ha detto che mi contattava oggi e forse lo facevamo stasera (credo che abbia intenzione di usare un pc provvisorio).
Nessun problema...se non ci riusciste ed i tempi stringono...io sono qui :)
Ragazzi, i task sono perfettamente chiari prima di cominciare? Nessun dubbio?
71104, discuti la test list con Cesare prima di iniziare e postatela qui sul forum. Io oggi pomeriggio e domani sono via.
fek, abbiamo pensato a questa test list per il task 4.2.2:
- test per coda vuota
- test per coda non vuota
- test per ordine corretto degli elementi della coda (se ne potrebbero fare due)
- test per la correttezza del tipo di evento (pressione o rilascio)
- test per i timestamp
più altri eventuali test da aggiungere durante lo sviluppo o dopo se ce ne fosse bisono.
dunque, mumble mumble, ho analizzato la situazione e le prossime cose da fare sono rimuovere l'uso del bitset in Input e usare la queue in reactToInput (quest'ultima cosa però non è esplicitamente richiesta dal task 4.2.2); è anche possibile che al termine del refactoring le classi AbstractKeyboard e derivate non esistano più secondo me.
intanto per rimuovere il bitset bisogna sicuramente modificare il codice in modo che usi un tipo intero anziché KeyCode per codificare gli eventi della tastiera; per l'esattezza il tipo Keyboard presente nelle librerie che usiamo restituisce i codici della tastiera sotto forma di int, quindi non vedo perché non usare quello: si elimina un sacco di codice inutile (alla fine non capisco neanche come mai si sia deciso di usare i valori della enum al posto di semplici interi).
dopo aver eliminato KeyCode potremo effettuare inserzioni nella coda in base al valore restituito dalla Keyboard; se non rimuovessimo KeyCode non potremmo effettuare l'inserzione perché dato l'int restituito dalla tastiera non sapremmo far corrispondere il valore della enum da inserire; la KEYCODEMAP non ci può aiutare perché funziona precisamente alcontrario: associa interi a valori enum, quindi ci permette di ritrovare l'intero partendo dal valore, a noi serve il contrario.
a questo punto secondo me la classe KeyboardImplementation diverrebbe talmente semplice da poter essere eliminata, ma questo si vedrà dopo.
il passo successivo sarebbe invece quello di modificare reactToInput in modo tale che non usi più le varie funzioni per testare la pressione dei tasti (mi accorgo ora che ce ne sta una per ogni tasto; e se avessimo deciso di usare nel gioco anche i tasti delle lettere e dei numeri che avreste fatto?? :D) ma usi extractKey.
fatto questo bisogna vedere cosa verrà fuori in fatto di giocabilità e quale sarà la sensazione finale dell'utente per quanto riguarda la gestione dell'input; in caso bisognerà lavorare nuovamente sul fatto del "delay" dei tasti.
ditemi le vostre opinioni e organizziamoci su come procedere per questo refactoring che mi sembra abbastanza complesso.
faccio una breve lista di TODOs, che mi sembra utile:
- interazione tra Keyboard e coda di Input: KeyboardImpl deve usare generateKey (che magari andrebbe pure rinominata :p)
- aggiornamento di reactToInput per l'uso di extractKey
- eliminazione del BitSet
ognuno di questi 3 punti non richiede test, richiede solo che si verifichi che i test attualmente presenti funzionino ancora.
Spiego quello che farei... Una cosa di cui non avete tenuto conto è che viene generato un evento di tasto premuto per ogni volta che viene fatto l'update dello stato della tastiera (non per ogni volta che il tasto viene premuto)...
Io avrei fatto un vettore di KeyEvent...ad ogni KeyEvent del vettore è associato un tasto (indicizzato tramite il valore delle costanti di Keyboard)...
Vanno modificati i valori dei KeyEvent di ogni tasto ogni volta che si chiama UpdateKeyboardState...
Il timeStamp associato ad ogni KeyEvent deve essere modificato solo se lo stato è diverso dal precedente...
In questo modo vengono gestiti automaticamente sia la pressione che il rilascio di un tasto...
E mi direte voi...e la coda dov'è ?
Basta realizzare una funzione getLastKeyPressed a cui si passa un timeStamp ed in base a quello si recupera l'ultimo evento generato (scorrendo il vettore di KeyEvent)...
Non c'è bisogno di alcuna estrazione o gestione della coda...
Per la gestione della pressione continua dei tasti (ad esempio per accelerare la gemma verso il basso) basta aggiungere is*KeyReleased e semplicemente si ritorna lo stato del tasto...
In questo modo si sarebbero anche potute scrivere le funzioni di tasto premuto attualmente usate dal codice...
Basta realizzare una funzione getLastKeyPressed a cui si passa un timeStamp ed in base a quello si recupera l'ultimo evento generato (scorrendo il vettore di KeyEvent)...
Spiego meglio questo punto...Volendo sarebbe possibile realizzare una funzione getNextKeyPressed che ritorna il tasto premuto imemdiatamente successivo al timeStamp che gli si passa...
reactToInput potrebbe ciclare fino a quando getNextKeyPressed può ritornare un valore valido... In questo modo non si perde alcun tasto premuto...
cdimauro
11-11-2005, 14:52
intanto per rimuovere il bitset bisogna sicuramente modificare il codice in modo che usi un tipo intero anziché KeyCode per codificare gli eventi della tastiera;
Non è necessario: è sufficiente utilizzare una classe/template che permette di gestire insiemi di valori di tipo KeyCode.
Adesso non ricordo come si chiama: l'ho usata tempo addietro.
per l'esattezza il tipo Keyboard presente nelle librerie che usiamo restituisce i codici della tastiera sotto forma di int, quindi non vedo perché non usare quello: si elimina un sacco di codice inutile (alla fine non capisco neanche come mai si sia deciso di usare i valori della enum al posto di semplici interi).
Perché in questo modo abbiamo disaccoppiato il nostro gioco dal sistema di input utilizzato (che per adesso è LWJGL).
cdimauro
11-11-2005, 14:59
Spiego quello che farei... Una cosa di cui non avete tenuto conto è che viene generato un evento di tasto premuto per ogni volta che viene fatto l'update dello stato della tastiera (non per ogni volta che il tasto viene premuto)...
Se non ricordo male l'update della tastiera può generare più eventi di tasto premuto.
Mi sembra che il codice stia in KeyboardImpl. Attualmente non ho i sorgenti davanti per controllare.
Il timeStamp associato ad ogni KeyEvent deve essere modificato solo se lo stato è diverso dal precedente...
Il timeStamp non dovrebbe essere modificabile per definizione.
Comunque secondo me il sorgente dovrà subire qualche sostanziosa modifica per implementare la gestione dei tasti prendendoli da una coda.
Questo perché a mio avviso l'evento "pressione di un tasto" dovrebbe essere "consumato" da un solo oggetto alla volta, che dovrebbe poi modificare il suo stato interno.
Per far questo la gestione della coda per com'è implementata adesso dovrebbe andare bene.
Vediamo cosa dicono anche gli altri: la questione è delicata, e se magari ci confrontiamo in tanti qualcosa di buono ne verrà fuori molto velocemente. :)
Questo perché a mio avviso l'evento "pressione di un tasto" dovrebbe essere "consumato" da un solo oggetto alla volta, che dovrebbe poi modificare il suo stato interno.
I tasti direzionali infatti agiranno su un solo oggetto alla volta (la coppia di gemme in via di caduta).
Gli altri tasti di cui dovremo rilevare la pressione, però, avranno a che fare con gli elementi più disparati (dall'esecuzione di suoni all'utilizzo di certe feature avanzate).
Quindi, anche se non bisogna inserire ASSOLUTAMENTE nulla che non sia stato richiesto dai task, credo ci convenga scegliere un tipo di implementazione che non ci chiuda delle porte, dato che in futuro poi dovremo riaprirle (e in pratica rifare tutto daccapo).
Ora, io non so dire quale sia il metodo migliore, questo dovete deciderlo voi, posso solo darvi un'idea di dove dobbiamo arrivare ;)
Comunque secondo me il sorgente dovrà subire qualche sostanziosa modifica per implementare la gestione dei tasti prendendoli da una coda.
Quello che intendevo dire è che non importa consumare l'evento...
Possiamo sfruttare il timeStamp per processare la sequenza di eventi...
Faccio un esempio di codice che legge gli eventi di pressione:
while(input.isAnotherKeyPressed(lastEvent.getTimeStamp())
{
lastEvent = input.getNextKeyPressEvent(lastEvent.getTimeStamp());
processInput(lastEvent.getKeyCode());
}
Questo è solo un esempio, reactToInput dovrà solamente leggere un evento, e memorizzarne uno durante il periodo in cui Grid non sarà attivo verso gli input...
Il problema attuale (e lo vedi diminuendo GridInputDelay dal file di cofigurazione) è che per una sola pressione di tasto l'aggiornamento dello stato della tastiera trova il tasto premuto molte volte (perchè l'aggiornamento avviene molte volte ogni decimo di secondo)... Andando a mettere ogni evento di pressione all'interno di una coda si genererebbero decine (se non centinaia) di eventi di pressione di un tasto...
Si può sempre applicare anche la vostra coda, ma comunque il problema fondamentale da risolvere è questo: un nuovo evento di pressione deve essere registrato (come l'avevo pensato io o comunque come l'avete pensato voi) solo dopo che lo stesso tasto è stato rilasciato...
Visto che l'esempio di KeyEvent fatto qualche post fa non ha avuto l'effetto che speravo allora userò una dicitura diversa per questa classe:
class KeyState
{
private boolean isPressed = false;
private long lastPressionTimestamp = 0;
public KeyState()
{
}
public void setKeyState(boolean isPressed, long timeStamp)
{
if(this.isPressed != isPressed)
{
this.timeStamp = timeStamp;
this.isPressed = isPressed;
}
}
public boolean isKeyPressed()
{
return isPressed;
}
public long getTimeStamp()
{
return timeStamp;
}
public boolean isStateChanged(long timeStamp)
{
if(this.timeStamp > timeStamp)
return true;
return false;
}
}
Istanziando un elemento di questa classe per ogni tasto è possibile registrare sia gli eventi di pressione che gli eventi di rilascio di tutti i tasti...
Questo ci può permettere sia a continuare ad usare una gestione come quella precedente (ma senza ripetizioni) che una gestione con una "falsa" coda di tasti:
public KeyPressedEvent getNextKeyPressedEvent(long timeStamp)
{
int minimalTimeDifferenceIndex = keyState.lenght();
long minimalTimeDifference = 0;
for(int i = 0; i < keyState.lenght(); ++i)
{
long timeDifference = keyState[i].getTimeStamp - timeStamp;
if(timeDifference > 0 && timeDifference < minimalTimeDifference)
{
minimalTimeDifferenceIndex = i;
minimalTimeDifference = timeDifference;
}
}
return KeyPressedEvent(keyState[i]);
}
Questa è solo una mia idea di implementazione, ma potremmo benissimo usare una coda che viene alimentata al momento in cui lo stato interno di un KeyState viene cambiato....
^TiGeRShArK^
11-11-2005, 17:42
Si può sempre applicare anche la vostra coda, ma comunque il problema fondamentale da risolvere è questo: un nuovo evento di pressione deve essere registrato (come l'avevo pensato io o comunque come l'avete pensato voi) solo dopo che lo stesso tasto è stato rilasciato...
ehm..
su questo punto non sarei molto d'accordo....
immagina ad esempio quando si spinge il tast down...
dobbiamge gestire la situazione quando il tasto è premuto, non solo quando è rilasciato..... infatti durante la pressione la gemma deve accelerare verso il basso.
Secondo me la soluzione ideale è considerare sia gli eventi di tipo isKeyPressed ke isKeyReleased in modo da avere un controllo più flessibile della pressione dei tasti...
ma su questo è meglio sentire cosa ne pensano il costumer e il coach credo...
Ovviamente lo stato degli altri tasti può variare quando se ne tiene premuto uno, anzi succederà quasi sempre, quindi non possiamo ignorare questo dettaglio.
Se io iniziassi a premere giù, e solo dopo premessi sinistra (cosa lecita e che capiterà molto, molto spesso ai giocatori), il gioco deve rilevare il tutto correttamente.
^TiGeRShArK^: uno non esclude l'altro...come ho detto, prova a diminuire GridInputDelay e vedrai che alla pressione di un tasto la gemma si sposterà più volte...
Semplicemente input può fornire un metodo isKeyPressed...che ritorna keyState[keyIndex].isKeyPressed...senza fare alcun controllo sul tempo...
Ovviamente lo stato degli altri tasti può variare quando se ne tiene premuto uno, anzi succederà quasi sempre, quindi non possiamo ignorare questo dettaglio.
Se io iniziassi a premere giù, e solo dopo premessi sinistra (cosa lecita e che capiterà molto, molto spesso ai giocatori), il gioco deve rilevare il tutto correttamente.
Alla pressione continua del tasto Destra...la gemma si deve spostare sempre verso destra, senza che il tasto Destra debba essere rilasciato e poi premuto nuovamente ?
Altrimenti basta fare la differenza fra i timeStamp...e se è maggiore di un certo timeout si cambia il timeStamp vecchio con quello nuovo...
Un altra possibilità sarebbe temporizzare anche la lettura degli input dal main del programma...forse la soluzione più semplice... Dovrebbe bastare temporizzare l'aggiornamento del vettore dei tasti con un tempo di 100 ms (e 150 ms per GridInputDelay)...poi si potrebbe continuare ad usare la coda così come è stata implementata...
Alla pressione continua del tasto Destra...la gemma si deve spostare sempre verso destra, senza che il tasto Destra debba essere rilasciato e poi premuto nuovamente ?
Esatto, e questo implica comunque un certo delay :)
Purtroppo per i dettagli implementativi non saprei cosa suggerire, dato che non è il mio campo: basta solo che il risultato sia che ogni pressione, contemporanea ad altre o meno (ed a qualsiasi velocità), sia registrata ed eseguita correttamente.
La situazione è complicata... Se un tasto resta premuto dovremmo ad esempio generare un nuovo evento solo ogni TOT ms... Pena la registrazione di troppi eventi... La soluzione che ho proposto sopra può essere riciclata a questo fine...
Ditemi cosa ne pensate (a questo punto che la coda tornerebbe comunque utile)...ma il bitset dovrebbe prendere un nuova forma (cioè il vettore di KeyState)...
La situazione è complicata... Se un tasto resta premuto dovremmo ad esempio generare un nuovo evento solo ogni TOT ms... Pena la registrazione di troppi eventi... La soluzione che ho proposto sopra può essere riciclata a questo fine...
Ditemi cosa ne pensate (a questo punto che la coda tornerebbe comunque utile)...ma il bitset dovrebbe prendere un nuova forma (cioè il vettore di KeyState)...
Personalmente mi piace la tua soluzione. Provate a reciclare un po della tua classe keyevent e la coda. Potrebbe scapapre fuori qualcosa di buono. :)
ciao ;)
class KeyState
{
private boolean isPressed = false;
private long timeStamp = 0;
public KeyState()
{
}
public void update(boolean isPressed, long timeStamp)
{
if(this.isPressed != isPressed)
{
this.timeStamp = timeStamp;
this.isPressed = isPressed;
//qui è possibile inserire l'evento in coda
}
else if(this.isPressed && timeStamp - this.timeStamp > 100)
{
time.timeStamp = timeStamp;
//qui è possibile inserire l'evento in coda per
//ripetere un tasto non rilasciato
}
}
public boolean isKeyPressed()
{
return isPressed;
}
public long getTimeStamp()
{
return timeStamp;
}
}
A questo punto è anche possibile abbassare GridInputDelay anche a 50 ms (anzi forse è anche possibile togliere il delay!!!)...in questo modo non si perde nemmeno un tasto...
Ovviamente in UpdateKeyboardState bisogna ciclare sui tasti per fare un update su tutti i KeyState...
Riguardo all'estrazione dalla coda sono comunque dubbioso... Se consideriamo che i tasti debbano essere estratti solo da un utilizzatore allora d'accordo, se invece non vogliamo estrarre i tasti ribadisco l'opzione in base al timeStamp...
Che ne dite ?
Per dirlo dovrei provarlo.
E' possibile avere una build funzionante con le tue modifiche?
Ci provo...anche se visto che non c'è la coda potremmo anche perdere qualche tasto...
Ci provo...anche se visto che non c'è la coda potremmo anche perdere qualche tasto...
Ah allora non fa niente, pensavo ci fosse ;)
Quando la cosa è sufficientemente completa fate un fischio così testo subito :D
Ti posso dare una versione di test solo per te...
Altrimenti invio una build, ma non mi sembra il caso con il codice di prova...
Per ora gestisco in questo modo solo i pulsanti di destra e sinistra...
Ti posso passare solo i sorgenti da metere nelle rispettive cartelle (solo Game.java e Input.java) ?
Azzz...se funziona bene...
Ho impostato la ripetizione del tasto premuto ogni 200 ms, GridInputDelay è stato impostato a 1 da codice (non capisco come mai mi saltava due caselle alla volta se lo impostavo a 0, nonostante ci sia la SleepOneMillisecond nel main loop)....
Ti posso dare una versione di test solo per te...
Altrimenti invio una build, ma non mi sembra il caso con il codice di prova...
Per ora gestisco in questo modo solo i pulsanti di destra e sinistra...
Ti posso passare solo i sorgenti da metere nelle rispettive cartelle (solo Game.java e Input.java) ?
Purtroppo non posso compilare i sorgenti, ma una bella versione di test (senza commit) sarebbe ottima.
Inviami la tua mail a cionci@questo_sito...
Ora mi sto domandando se la coda serve ancora :boh:
Inviami la tua mail a cionci@questo_sito...
Ora mi sto domandando se la coda serve ancora :boh:
Puoi fare un branch in Subversion per provare la tua soluzione, e Jocchan puo' testare quella.
Nel frattempo gli altri possono andare avanti col task e implementare la coda di input come richiesto? Mi serve che siano registrati gli eventi di pressione e rilascio di ogni tasto.
Mail inviata ;)
Olè, bentornato Fek!
Per chi la vuole provare (da notare che non esclude la coda) allego i due file modificati...
Aspetta che provo a farti un branch e puoi fare i tuoi test li'.
Nono...non serve... Tanto è solo per questa prova... Magari dai un'occhiata a questi due file... Ovviamente ho rappezzato velocemente il codice per gestire KeyState solo su due tasti...
Cionci, se fai l'update del repository, in branches/InputTest hai la tua branch per fare qualche esperimento con la tua soluzione. Puoi fare tranquillamente i commit li' e non possiamo fare gli update da li'.
Ho fatto l'update su: svn://spartacus.dnsalias.net/diamonds/branches/InputTest
E' già sabato e mancano due task... a quanto pare un pò li abbiamo mescolati al secondo (e questo è un errore, ma finchè siamo all'interno delle specifiche va bene così). Com'è la situazione attuale?
Jocchan: hai dato un'occhita ? Piuttosto che ritardare la lettura degli input da parte di Grid per evitare ripetizioni, mi sembra più logico evitare le ripetizioni ritardandole da Input... Cosa ne pensate ? Vorrei una opinione anche da fek...
Dopo una riflessione sono giunto alla conclusione che bisogna comunque aggiungere la coda, ma la distanza fra due aggiornamenti successivi dello stato della tastiera deve essere di almeno un millisecondo (questo dovrebbe già accadere con la sleepOneMilliSecond, ma non siamo in un sistema operativo real time, quindi una Sleep non è comunque garantito che faccia passare un millisecondo, comunque con una piccola modifica psosiamo sistemare)...
Jocchan: hai dato un'occhita ?
Più di una, il gioco risponde benissimo ai comandi.
Ci sono solo due imperfezioni da limare:
- quando si premono sx e dx insieme, la gemma si muove in maniera strana
- la velocità di discesa è un pò troppo elevata
Ma vedremo come risolvere il tutto in un lampo :)
E' già sabato e mancano due task... a quanto pare un pò li abbiamo mescolati al secondo (e questo è un errore, ma finchè siamo all'interno delle specifiche va bene così). Com'è la situazione attuale?
La situazione attuale e' che ci servono i task entro stasera.
Chi riesce a lavorarci oggi pomeriggio? Io sono presente per un po' di pair programming.
io mi sa che esco ( :Prrr: ) ma quando torno (verso le 8 e mezza) ci posso sicuramente lavorare... intanto adesso provo a leggere qualche task tra quelli che mancano e a fare una test list...
siccome il 4.2.4 non l'ho proprio capito ( :confused: ) e sembra anche essere dipendente dal 4.2.3, mi prenoto per il 4.2.3; ora analizzo la situazione el codice attuale, comunque direi che essenzialmente bisogna mettere tra i test di Grid i test già presenti per testare reactToInput.
namo bene, appena lo lancio eccezione -.-'
chi è che si è scordato di mettere il parametro "gravity" in Config? :D
oltrettutto non avete manco aggiornato la knowledge... :nonsifa:
devo andare a pranzo -.-'
BlueDragon
12-11-2005, 13:50
namo bene, appena lo lancio eccezione -.-'
chi è che si è scordato di mettere il parametro "gravity" in Config? :D
oltrettutto non avete manco aggiornato la knowledge... :nonsifa:
A me funziona bene, ma il synchronize prima mi mostrava dei class ed ora mi mostra come da aggiungere dei file che già ho....quindi qualcosa di strano c'è...Cmq il mio progetto l'ho rifatto da poco cancellando tutto e facendo Check Out As a Project da SVN Repository exploring, quindi dovrebbe essere l'ultima versione.
Purtroppo la macchina della build sembra essere giù (o almeno i siti web) quindi non possiamo controllare com'è la situazione lì.
namo bene, appena lo lancio eccezione -.-'
chi è che si è scordato di mettere il parametro "gravity" in Config? :D
oltrettutto non avete manco aggiornato la knowledge... :nonsifa:
Io ho fatto il commit, ma funzionava tutto (la Gravity l'ho tolto da Config)...
La build machine dopo il mio commit era ok !!!
71104: hai rifatto il commit, ma erano i tuoi sorgenti ad essere indietro rispetto al mio aggiornamento...
^TiGeRShArK^
12-11-2005, 17:52
ehm...
colgo l'occasione per ricordare di fare SEMPRE l'update prima di fare il commit....
in questo modo potremmo fare eventuali merge e quindi committare il codice corretto...
BlueDragon
12-11-2005, 19:08
Ragazzi, i task sono perfettamente chiari prima di cominciare? Nessun dubbio?
Dopo aver "giocato" un po' con il task 4.2.2 mi sono reso conto che i task non sono chiari..chiedo scusa per non averlo detto prima.
Anzi, per la verità leggendo la storia non è chiaro quali funzionalità si vogliano aggiungere (a parte la gravità aumentata) e perché stiamo implementando una coda per ottenerle.
E' chiaro che conoscendo il gioco ed il codice io ho un'idea di cosa manchi alla gestione di input per raggiungere un certo livello di risposta, ma questa mancanza non è stata esplicitata chiaramente (secondo me) né nella storia né nei task..anzi, seguendo l'idea che ho in mente mi viene da pensare che il task 4.2.3 non sia nemmeno giusto rispetto a quello che io penso Jocchan voglia ottenere, ma che sia stato scelto su supposizioni a livello di codice attuale.
Per chiarire, vi esprimo sotto forma di test come penso dovrebbe essere la gestione dell'input.
Queste sono due cose che già siamo capaci di gestire con il vecchio codice:
1) Mentre il tasto rimane premuto, non ripetere il movimento prima che sia passato il delay:
grid.insertGem(2, 5, gem);
grid.setGemUnderControl(gem);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Pressed);
grid.reactToInput(input, timer);
timer.setTime(timer.getTime() + grid.getInputDelay() - 1);
grid.reactToInput(input, timer);
assertTrue( "Gem has moved more than once with Left being pressed for less than Delay",
grid.isGemAt(2, 4));
2) Il tasto rimane premuto, ripetere il movimento ogni tot millisecondi:
grid.insertGem(2, 5, gem);
grid.setGemUnderControl(gem);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Pressed);
grid.reactToInput(input, timer);
timer.setTime(timer.getTime() + grid.getInputDelay()+1);
grid.reactToInput(input, timer);
assertTrue( "Gem isn't moving according to the correct delay with Left Key being pressed",
grid.isGemAt(2, 3));
3) Se teniamo il tasto premuto a lungo, comunque la gemma deve smettere di muoversi appena lasciamo il tasto:
(stesso test di prima con una aggiunta)
grid.insertGem(2, 5, gem);
grid.setGemUnderControl(gem);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Pressed);
grid.reactToInput(input, timer);
timer.setTime(timer.getTime() + grid.getInputDelay()+1);
grid.reactToInput(input, timer);
assertTrue( "Gem isn't moving according to the correct delay with Left Key being pressed",
grid.isGemAt(2, 3));
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Released);
timer.setTime(timer.getTime() + grid.getInputDelay()+1);
grid.reactToInput(input, timer);
assertTrue( "Gem didn't stop moving after Key being released",
grid.isGemAt(2, 3));
Queste invece sono delle cose che non siamo capaci di gestire con il codice vecchio, e che secondo me sono richieste da Jocchan nella sua descrizione della storia:
4) Se l'utente preme due volte nella stessa direzione rapidamente, il gioco deve rispondere due volte, non deve attendere il delay (qui ci serve la gestione degli eventi per distinguere due pressioni successive):
grid.insertGem(2, 5, gem);
grid.setGemUnderControl(gem);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Pressed);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Released);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Pressed);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Released);
grid.reactToInput(input, timer);
assertTrue( "Gem didn't move twice with left pressed twice by user.",
grid.isGemAt(2, 3));
Perché non deve attendere il delay? Perché il gioco deve rispondere prontamente, ed il delay a mio parere è stato introdotto *solo* per evitare che la gemma non si muovesse troppo velocemente tenendo premuto il tasto, non per imporre lag al giocatore :)
5) Se l'utente preme rapidamente due volte verso sinistra e poi a destra, il gioco deve riprodurre correttamente tutta la sequenza (ed ecco che ci serve la coda):
grid.insertGem(2, 5, gem);
grid.setGemUnderControl(gem);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Pressed);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Released);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Pressed);
input.generateKeyEvent(KeyCode.vk_Left, KeyState.Released);
input.generateKeyEvent(KeyCode.vk_Right, KeyState.Pressed);
input.generateKeyEvent(KeyCode.vk_Right, KeyState.Released);
grid.reactToInput(input, timer);
assertTrue( "Grid didn't react correctly to fast sequence.",
grid.isGemAt(2, 4));
Non mi ricordo se volevo aggiungere anche un altro test, ma mi ci è voluto un po' per fare tutto questo, quindi mi fermo qui..spero sia venuto abbastanza chiaro :)
Dragoblu
PS: Avevo provato a dire tutto a parole ma era un incubo scrivere un post decente...meno male che ci sono i test.. :sofico:
Perché non deve attendere il delay? Perché il gioco deve rispondere prontamente, ed il delay a mio parere è stato introdotto *solo* per evitare che la gemma non si muovesse troppo velocemente tenendo premuto il tasto, non per imporre lag al giocatore
Jocchan, un commento su questo?
Jocchan, un commento su questo?
Ne ho già parlato con VICIUS e Jocchan e la modifica che ho fatto io punta proprio a questo... Eliminare il delay e spostare la generazione di eventi per il tasto ripetuto in un'altra classe...
VISIUS mi ha detto di trasporta il tutto nel main branch, ma sto trovando qualche difficoltà, anche perchè la cosa diventa abbastanza complessa se deve funzionare per tutti i tasti e non solo per destra e sinistra (come avevo fatto in InputTest)...
Ne ho già parlato con VICIUS e Jocchan e la modifica che ho fatto io punta proprio a questo... Eliminare il delay e spostare la generazione di eventi per il tasto ripetuto in un'altra classe...
VISIUS mi ha detto di trasporta il tutto nel main branch, ma sto trovando qualche difficoltà, anche perchè la cosa diventa abbastanza complessa se deve funzionare per tutti i tasti e non solo per destra e sinistra (come avevo fatto in InputTest)...
Esatto, per questo sono ancora convinto che la soluzione della coda di input sia la migliore, perche' ci permette di analizzare in reactToInput gli eventi e gestirli di conseguenza.
Ma la coda rimane... L'unica cosa che cambia è che al posto del BitSet c'è la classe che sto mettendo a punto... Ed è questa stessa classe che può generare gli eventi e metterli in coda...
Ma la coda rimane... L'unica cosa che cambia è che al posto del BitSet c'è la classe che sto mettendo a punto... Ed è questa stessa classe che può generare gli eventi e metterli in coda...
Perfetto :)
La stai scrivendo TestDriven? O meglio, consideriamo il tuo come uno spike e la riscriviamo TestDriven io e te nel main branch domani pomeriggio?
BlueDragon
12-11-2005, 20:06
Ne ho già parlato con VICIUS e Jocchan e la modifica che ho fatto io punta proprio a questo... Eliminare il delay e spostare la generazione di eventi per il tasto ripetuto in un'altra classe...
VISIUS mi ha detto di trasporta il tutto nel main branch, ma sto trovando qualche difficoltà, anche perchè la cosa diventa abbastanza complessa se deve funzionare per tutti i tasti e non solo per destra e sinistra (come avevo fatto in InputTest)...
Facendo delle prove sul codice io penso di essere riuscito ad implementare il necessario per passare i test di cui sopra e non è troppo ingarbugliato, anzi.
Ho usato la coda fornita dal Task 4.2.2, semplicemente aggiungendo la parte in KeyboardImplementation affinché venga eseguito un input.generaKeyInput per ogni evento della tastiera LWJGL (che ha anch'essa una coda e segnala 1 evento per la pressione ed 1 evento per il rilascio, non ci sono eventi di "tastoTenutoPremuto" per la Keyboard di LWJGL).
Dopodiché, nel reactToInput di Grid estraggo tutti gli eventi dalla nostra coda ed eseguo le seguenti attività:
1) Per ogni evento su KeyDown, moltiplico o riporto a normale la gravità (a seconda se l'evento è pressed o released).
2) Se ci sono eventi di Pressed su Left o Right, li eseguo tutti immediatamente, non importa il delay. Però mi segno il timestamp di quando li eseguo.
3) Se "isLeftKeyPressed()" (o isRightKeyPressed()) è true ed è passato abbastanza tempo dall'ultima volta che mi sono mosso, ripeto il movimento.
Dovrebbe soddisfare i test che ho elencato..non ne sono sicuro perché ho scritto il codice "tanto per giocare" e solo dopo, quando ho avuto la necessità di postare e spiegarmi, ho creato i test.
Ora provo ad applicarli per vedere se il codice passa...
PS: Sono loggato sul nostro canale IRC:
Canale: #diamond_crush
Server: irc.azzurra.org
Porte: 6665-6667
Domani non ci sono...e non l'ho scritta testDriven :(
Visto lo spike credevo di fare poche modifche per farne un'altro... Invece non sono poi poche :)
Ti posso dare quello che ho scritto fino ad adesso, il funzionamento è davvero elementare... Certo, i test ci vorrebbero, ma ora non ho tempo di farli...
Il problema principale è questo, io credevo che venissero ripetuti gli eventi di tasto giù fino a quando il tasto rimane premuto...invece LJWGL non li ripete...
Quindi mi trovo in difficoltà perchè lo stato dei tasti della mia classe dovrebbe essere aggiornato ogni volta, per generare gli eventuali tasti ripetuti...
Io ti posto il codice, caso mai servisse... Purtroppo mi devo fermare...
package it.diamonds.engine.input;
import java.util.Map;
import java.util.HashMap;
import it.diamonds.engine.input.Input.KeyCode;
public class KeyboardState
{
private Map<Integer, KeyState> keysState;
private class KeyState
{
private boolean isPressed = false;
private long timeStamp = 0;
public KeyState()
{
}
public void update(boolean isPressed, long timeStamp)
{
if(this.isPressed != isPressed)
{
this.timeStamp = timeStamp;
this.isPressed = isPressed;
//qui potrebbe essere generato un evento da mettere in coda
}
else if(this.isPressed && timeStamp - this.timeStamp > 200)
{
this.timeStamp = timeStamp;
//qui ptorebbe essere generato un evento da mettere in coda
}
}
public boolean isPressed()
{
return isPressed;
}
public long getTimeStamp()
{
return timeStamp;
}
public boolean isStateChanged(long timeStamp)
{
return timeStamp <= this.timeStamp;
}
}
public KeyboardState()
{
keysState = new HashMap<Integer, KeyState>();
}
public void updateKey(int key, boolean state, long timeStamp)
{
if(!keysState.containsKey(key))
keysState.put(key, new KeyState());
keysState.get(key).update(state, timeStamp);
}
public boolean isKeyPressed(int key)
{
if(!keysState.containsKey(key))
return false;
return keysState.get(key).isPressed();
}
public long getTimeStamp(KeyCode key)
{
if(!keysState.containsKey(key))
return 0;
return keysState.get(key).getTimeStamp();
}
public boolean isStateChanged(int key, long timeStamp)
{
if(!keysState.containsKey(key))
return false;
return keysState.get(key).isStateChanged(timeStamp);
}
}
3) Se "isLeftKeyPressed()" (o isRightKeyPressed()) è true ed è passato abbastanza tempo dall'ultima volta che mi sono mosso, ripeto il movimento.
Se memorizzi due timeStamp distinti e azzeri i timeStamp se il tasto viene rilasciato allora è ok... Ed è anche una buona soluzione...anzi sicuramente più semplice della mia...
BlueDragon
12-11-2005, 20:48
Se memorizzi due timeStamp distinti e azzeri i timeStamp se il tasto viene rilasciato allora è ok... Ed è anche una buona soluzione...anzi sicuramente più semplice della mia...
Sì, ogni volta che "ripeto il movimento" aggiorno il timeStamp, affinché sia necessario un altro intervallo di delay prima di ripetere ancora.
Per quanto riguarda la separazione in due timeStamp, uno per il tasto destro ed uno per sinistro, in teoria sembra necessario (io avrei voluto farlo già qualche task fa) ma nella pratica non lo è.
Se c'è un solo tasto premuto, usa lui la variabile del timestamp.
Se ce ne sono due premuti assieme, la possono comunque condividere, anzi è anche meglio.
Se ci fossero due timestamp infatti la sequenza sarebbe questa:
Time/Action
0.000 L'utente preme Left, la gemma si sposta a sinistra
0.007 L'utente preme Right, la gemma ritorna a destra
0.010 Delay passato per Left, la gemma si sposta a sinistra
0.017 Delay passato per Right, la gemma ritorna a destra
0.020 Delay passato per Left, la gemma si sposta a sinistra
0.027 Delay passato per Right, la gemma ritorna a destra
[etc etc]
Quindi la gemma fa avanti ed indietro continuamente..
Con un solo timestamp:
Time/Action
0.000 L'utente preme Left, la gemma si sposta a sinistra
0.007 L'utente preme Right, la gemma ritorna a destra
0.017 Delay passato per Left & Right, Grid applica un avanti ed indietro ma quando viene chiamato il render(), la gemma sembra non essersi mossa
0.027 Delay passato per Left & Right, Grid applica un avanti ed indietro ma quando viene chiamato il render(), la gemma sembra non essersi mossa
0.037 Delay passato per Left & Right, Grid applica un avanti ed indietro ma quando viene chiamato il render(), la gemma sembra non essersi mossa
[etc etc]
Per quanto riguarda il momento del rilascio, credo che in entrambe le implementazioni ci sia il rischio che venga riprodotto un singolo movimento a sinistra o a destra, a seconda della sua rapidità nel sollevare le dita. Comunque testando visivamente il codice non sembra capitare così spesso come accadeva con il codice precedente. Da vedere con Jocchan quanta precisione vuole...in fondo nel gioco non vedo perché qualcuno debba tenere a lungo premuti entrambi i tasti :p
Ora ceno dopo metto il codice che ho scritto sotto test :)
Domani non ci sono...e non l'ho scritta testDriven :(
Visto lo spike credevo di fare poche modifche per farne un'altro... Invece non sono poi poche :)
Ti posso dare quello che ho scritto fino ad adesso, il funzionamento è davvero elementare... Certo, i test ci vorrebbero, ma ora non ho tempo di farli...
Ok, allora Jocchan puo' testare l'idea nel branch e darci il suo parere. Se accetta l'idea la riscrivi daccapo Test Driven. Adesso preferisco imporre che tutto il codice di produzione senza eccezioni sia Test Driven.
Jocchan l'ha già testata...ha detto che gli piace...
Se ci fossero due timestamp infatti la sequenza sarebbe questa:
Time/Action
0.000 L'utente preme Left, la gemma si sposta a sinistra
0.007 L'utente preme Right, la gemma ritorna a destra
0.010 Delay passato per Left, la gemma si sposta a sinistra
0.017 Delay passato per Right, la gemma ritorna a destra
0.020 Delay passato per Left, la gemma si sposta a sinistra
0.027 Delay passato per Right, la gemma ritorna a destra
[etc etc]
Quindi la gemma fa avanti ed indietro continuamente..
Ma con un solo delay questa situazione è gestita male:
0.000 L'utente preme Left, la gemma si sposta a sinistra
0.007 L'utente preme Right, la gemma non si sposta a destra
0.010 Delay passato per Left, la gemma si sposta a sinistra
Quindi due spostamenti a sinistra con uno solo che sarebbe dovuto avvenire...
Jocchan l'ha già testata...ha detto che gli piace...
Ok, in tal caso la inserira come prossima storia e possiamo creare i task relativi.
BlueDragon
12-11-2005, 21:40
Ma con un solo delay questa situazione è gestita male:
0.000 L'utente preme Left, la gemma si sposta a sinistra
0.007 L'utente preme Right, la gemma non si sposta a destra
0.010 Delay passato per Left, la gemma si sposta a sinistra
Quindi due spostamenti a sinistra con uno solo che sarebbe dovuto avvenire...
No, viene gestita bene :)
Quando vengono ricevuti gli eventi di pressione, essi vengono eseguiti senza considerare il timestamp. Vengono eseguiti e basta, così come vuole l'utente.
Il timestamp serve solo per controllare se un certo tasto è stato tenuto premuto per più di un certo tempo.
Cmq il mio codice funziona e supera i test che avevo proposto...se volete cancello tutto e riscrivo (o riscriviamo a più mani) partendo dai Test.
No, viene gestita bene :)
Quando vengono ricevuti gli eventi di pressione, essi vengono eseguiti senza considerare il timestamp. Vengono eseguiti e basta, così come vuole l'utente.
Il timestamp serve solo per controllare se un certo tasto è stato tenuto premuto per più di un certo tempo.
Cmq il mio codice funziona e supera i test che avevo proposto...se volete cancello tutto e riscrivo (o riscriviamo a più mani) partendo dai Test.
Lavora pure nel branch di cionci e implementa anche questa soluzione, magari dietro uno switch per passare da una all'altra. Poi la decisione di che cosa fare e' solo di Jocchan.
Direi di portare questa Storia al prossimo Ciclo e usiamo la scorsa settimana come spike su questo problema che non e' di poca importanza.
Sono mancato per tutto il tardo pomeriggio, quindi rispondo solo ora.
Il lavoro di Cionci è stato ottimo, dato che il gioco risponde prontamente a tutti i comandi (e sono rimasto a picchiettare sui tasti a velocità folli... tutto sempre perfetto).
L'unico difetto è che premendo contemporaneamente sia sinistra che destra la gemma sembra sparire per un istante, ma questo si può correggere.
La velocità va un pò calibrata, sto smanettando con i settaggi e mi sto facendo un'idea, ma per il resto mi sembra che già la "Cionci version" vada più che bene.
Se, a parte questo piccolo difetto che possiamo considerare un bug, abbiamo soddisfatto i requisiti della storia (una pronta risposta agli input del giocatore), allora cosa manca ancora?
71104: hai rifatto il commit, ma erano i tuoi sorgenti ad essere indietro rispetto al mio aggiornamento... cheee?? O_o
ti assicuro che è impossibile, io prima di iniziare a lavorare lo faccio sempre l'update... O_o oltrettutto non penso sia mai esistita nel repository una revisione che da' eccezione per mancanza di parametri in Config... secondo me era un problema di Tortoise... comunque vabbè, ora ripiglio il task e penso ai test.
come non detto, :fagiano: vedo che stanno cambiando un sacco di cose... :fagiano:
[...] ora ripiglio il task e penso ai test.
Il tuo test è un refactoring se non sbaglio. Non servono test. Parti a razzo :D
ciao ;)
cdimauro
13-11-2005, 08:39
Una riflessione.
Quando si sviluppavano giochi 2D ai tempi di C64, Amiga, ecc., si procedeva così:
1) il gioco girava a una frequenza fissa (50 o 60 hz/fps, ecc.);
2) per ogni frame si leggevano le porte di input di tastiera e joystick, e si aggiornava la bitmap dei tasti premuti e quella dei joystick;
3) la logica del gioco analizzava queste bitmap e procedeva all'aggiornamento dello stato dell'oggetto del giocatore 1, del giocatore 2 (se presente) e quello degli altri oggetti.
Piuttosto semplice.
Qui prima di questi task funzionava più o meno così, con una bitmap dei tasti premuti che veniva analizzata.
Non capisco perché adesso ci stiamo complicando la vita con code et similia.
Tutto qui.
Prima c'era anche un delay sulla reattività dei tasti...e questo non va bene :)
Se, a parte questo piccolo difetto che possiamo considerare un bug, abbiamo soddisfatto i requisiti della storia (una pronta risposta agli input del giocatore), allora cosa manca ancora?
Mancano i test. Quindi manca tutta la storia. (Ricordo: un task e' finito quando i test passano, non prima).
Se la versione di Cionci per te va bene, allora la sua implementazione diventera' la prima Storia del prossimo Ciclo. Con tutti i test.
Nella code base non entra codice non testato e tutto il codice va scritto Test Driven.
Mancano i test. Quindi manca tutta la storia. (Ricordo: un task e' finito quando i test passano, non prima).
Se la versione di Cionci per te va bene, allora la sua implementazione diventera' la prima Storia del prossimo Ciclo. Con tutti i test.
Nella code base non entra codice non testato e tutto il codice va scritto Test Driven.
Benissimo, allora è quello che faremo nel prossimo ciclo :)
Vediamo comunque a cosa arriva BlueDragon, visto che potrebbe aver risolto il problema in un altro modo...
Vediamo comunque a cosa arriva BlueDragon, visto che potrebbe aver risolto il problema in un altro modo...
Buona idea.
Vorrei precisare che sia tu sia BD state facendo una cosa perfettamente corretta: sono due spike che cercano di risolvere il problema in maniera piu' semplice e sono correttamente portati avanti in un branch.
Quando Jocchan decidera' la soluzione per lui migliore, la reimplementeremo nella code base con tutti i test necessari.
Il tuo test è un refactoring se non sbaglio. Non servono test. Parti a razzo :D
Nella code base non entra codice non testato e tutto il codice va scritto Test Driven.
:nonsifa:
piuttosto invece ho bisogno di un aggiornamento sul punto della situazione perché ho visto che cionci ha scritto del codice ma non ho capito cosa fa; cos'è che manca attualmente per finire la storia? il task 4.2.3 serve ancora?
Fatemi testare anche la soluzione di BD e vi saprò dire quale delle due è migliore.
piuttosto invece ho bisogno di un aggiornamento sul punto della situazione perché ho visto che cionci ha scritto del codice ma non ho capito cosa fa; cos'è che manca attualmente per finire la storia? il task 4.2.3 serve ancora?
Prendi questo dal repository:
svn://spartacus.dnsalias.net/diamonds/branches/InputTest
Fai una prova con i due giochi e dimmi se noti una differenza nel movimento :)
BlueDragon
13-11-2005, 14:36
piuttosto invece ho bisogno di un aggiornamento sul punto della situazione perché ho visto che cionci ha scritto del codice ma non ho capito cosa fa; cos'è che manca attualmente per finire la storia? il task 4.2.3 serve ancora?
Sai che non lo so? Non c'è un post in cui è scritto "fermi tutti, si passa al prossimo giro".. anche se mi è sembrato di capire così.
Cmq ho caricato un nuovo branch in branches\trunk, dove ho messo il codice che ho provato ieri.
Contiene:
1) Implementazione del collegamento tra KeyboardImplementation & Input, affinché venga riempita la coda (codice abbastanza brutto, server refactoring visto che ho dovuto fare un giro per aggirare l'enum necessaria a Input.generateKeyEvent).
2) Implementazione del task 4.2.3, Grid che usa la coda di Input (scritta non TestDriven).
3) I Test che ho scritto qualche pagina fa sui requisiti del movimento messi in
TestGridReactionToInput (il codice li passa tutti).
Jocchan ti basta sapere che è in branches\trunk per testarlo? (Non ricordo come sei attrezzato con Eclipse :))
PS: Ho visto che cionci ha postato mentre scivevo...ciao Cionci! :)
Utilizzo allora anche io la sua notazione, il mio branch è in:
svn://spartacus.dnsalias.net/diamonds/branches/trunk
[non ho rinominato la cartella finale perché il comando da Eclipse non era chiarissimo e non ho voluto combinare pasticci nel repository :p ]
Prendi questo dal repository:
svn://spartacus.dnsalias.net/diamonds/branches/InputTest
Fai una prova con i due giochi e dimmi se noti una differenza nel movimento :) non mi va, sono pigro :fagiano:
quando faccio il checkout lo faccio solo di trunk, percui branches non ce l'ho :fagiano:
non è che me lo passi via email a atomino85(at)gmail(dot)com oppure lo alleghi a un post plz? :fagiano:
Ti allego la directory bin al post... Ora provo...
Ti allego la directory bin al post... Ora provo... grazie :)
Contiene:
1) Implementazione del collegamento tra KeyboardImplementation & Input, affinché venga riempita la coda (codice abbastanza brutto, server refactoring visto che ho dovuto fare un giro per aggirare l'enum necessaria a Input.generateKeyEvent).
2) Implementazione del task 4.2.3, Grid che usa la coda di Input (scritta non TestDriven).
3) I Test che ho scritto qualche pagina fa sui requisiti del movimento messi in
TestGridReactionToInput (il codice li passa tutti).
Quello che non ho capito è se per il task 4.2.3 hai bisogno di codice non testato nella codebase...ad occhio mi sembra di sì...
Sai che non lo so? Non c'è un post in cui è scritto "fermi tutti, si passa al prossimo giro".. anche se mi è sembrato di capire così.
Cmq ho caricato un nuovo branch in branches\trunk, dove ho messo il codice che ho provato ieri.
Contiene:
1) Implementazione del collegamento tra KeyboardImplementation & Input, affinché venga riempita la coda (codice abbastanza brutto, server refactoring visto che ho dovuto fare un giro per aggirare l'enum necessaria a Input.generateKeyEvent).
2) Implementazione del task 4.2.3, Grid che usa la coda di Input (scritta non TestDriven).
3) I Test che ho scritto qualche pagina fa sui requisiti del movimento messi in
TestGridReactionToInput (il codice li passa tutti).
Jocchan ti basta sapere che è in branches\trunk per testarlo? (Non ricordo come sei attrezzato con Eclipse :))
PS: Ho visto che cionci ha postato mentre scivevo...ciao Cionci! :)
Utilizzo allora anche io la sua notazione, il mio branch è in:
svn://spartacus.dnsalias.net/diamonds/branches/trunk
[non ho rinominato la cartella finale perché il comando da Eclipse non era chiarissimo e non ho voluto combinare pasticci nel repository :p ]
Non ho Eclipse ma posso accedere al repository via Tortoise. Vedo di creare la cartella Branches e scaricare il tuo codice, sperando sia già compilato.
Non ho Eclipse ma posso accedere al repository via Tortoise. Vedo di creare la cartella Branches e scaricare il tuo codice, sperando sia già compilato.
No...non è compilato...
BlueDragon: inviagli la cartella bin compressa via mail...
Jocchan: fai una copia dei file che ti ho mandato io e sovrascrivi la cartella bin con quello che ti invia lui (cancella prima la cartella bin per essere sicuro)...
71104: l'ho inviato via mail perchè era troppo grande...
71104: l'ho inviato via mail perchè era troppo grande... si, ho letto (Gmail Notifier rulez :D), ma non riesco ad avviare perché non ho mai capito come si usa sto benedetto comando java... ti ho risposto in mail ^^'
BD, il mio contatto MSN è jocchanTOGLIQUESTOPERLOSPAMhotmail.it e la mail è jocchan83TOGLIQUESTOPERLOSPAMyahoo.it :)
EDIT: Grazie Cionci, ovviamente avrei tolto tutto dopo aver contattato BD :D
cionci, da me la tua versione avviata col bat non funziona O_o'
mi da eccezione perché non trova il para,etro gravity in Config!!! O_O'
EDIT: devo avere qualche problema in locale, faccio il checkout di trunk.
Nono...è giusto.. Aggiungilo... Questo perchè le modifiche che ho fatto alla distribuzione principale sono successive alla copia del progetto su cui ho lavorato io...
Aggiungilo a mano e dovrebbe funzionare (valore 1)...
alleluja, ce l'ho fatta :D
si, effettivamente la resa è migliore, ma ancora c'è il problema se non erro che il framerate è lo stesso della frequenza di poll della tastiera, è quello il motivo percui la resa è migliore, e questa cosa secondo me va corretta.
inoltre adesso che la gemma è più veloce si inizia a notare un fastidioso effetto di flickering della gemma, per ora è una cosa leggerissima appena accennata, non so se succede anche a voi...
alleluja, ce l'ho fatta :D
si, effettivamente la resa è migliore, ma ancora c'è il problema se non erro che il framerate è lo stesso della frequenza di poll della tastiera, è quello il motivo percui la resa è migliore, e questa cosa secondo me va corretta.
No, il poll della tastiera viene fatto ogni millisecondo circa...controlla Game.java ;)
Bene, dopo aver testato intensivamente sia la versione di Cionci che quella di Blue Dragon, direi proprio ci conviene ripartire dalla seconda.
Entrambe rispondono ottimamente ai controlli (e quindi un bel "bravissimi" ad entrambi ci sta tutto), anche pigiando tasti come dei forsennati.
L'unico motivo per cui andremo avanti con la versione di BD è che nella prima bisogna correggere un piccolo bug (un comportamento strano della gemma quando si premono sx e dx contemporaneamente), mentre nella seconda questo problema non sussiste.
Insomma, si tratta di una piccolezza, ma è pur sempre del lavoro in meno.
Chiudiamo qui il quarto ciclo, datemi il tempo di fare un paio di ritocchi al Development Plan (che potete già trovare nella cartella Docs del repository) e andremo avanti col ciclo 5.
Ci aggiorniamo più tardi ;)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.