View Full Version : CrushBox
Ho tirato fuori il comportamento del crushBox da PlayField a CrushBox.
I test passano tutti.
Però la crushBox nn si comportà come prima.
Mi sono messo a testare come funziona esattamente.
Sta in piedi per volontà divina o qualcosa di più grosso.
Proverò a illustrarvi il comportamento attuale, poi jocchan, mi deve dire quanto devo replicare di questo comportamento.
Ora vi faccio un esempio dello svolgimento
Parte una crush.
Viene settata la texture giusta
Viene inizializzata la posizione dello sprite, la pulsazione e lo sprite viene reso visibile
viene memorizzato il timestamp
viene spostata la texture verso l'esterno
poi per i prossimi update ci sarà questo ciclo
Viene settata la texture giusta
viene memorizzato il timestamp
viene spostata la texture verso l'esterno
qua si notano gia varie cose.
Il timestamp viene aggiornato a ogni ciclo per cui serve a poco.
Inoltre la texture viene spostata verso l'esterno. Ma guardando il gioco(la grafica) questo non avviene.
La textura si espande e si riduce senza spostarsi.
!!!!!!!!!
Questo succede perchè la pulsazione resetta la posizione dello sprite.
Per cui lo sprite viene spostato. Ma poi durante la draw, lo sprite torna nella posizione precedente.
L'evento che ci fa uscire da questo ciclo è lo sprite che finisce un ciclo di pulsazione.
In questo caso entriamo nel seguente ciclo
Viene settata la texture giusta
viene memorizzato il timestamp
viene stoppata la pulsazione
viene spostata la texture verso l'esterno
Dopo di che riprende il ciclo
Viene settata la texture giusta
viene memorizzato il timestamp
viene spostata la texture verso l'esterno
Qua si nota che ancora, il timestamp nn serve a nulla, visto che viene memorizzato a ogni ciclo.
Ma stavolta, lo spostamento della texture verso l'esterno funziona, visto che la pulsazione non c'è più.
Si va avanti con questo ciclo, fino a quando si verificano 2 eventi
La gemsPair venuta fuori dopo la crush arriva a terra.Perchè?????
Perchè quando questo capita questo evento, viene resettata la chainCrush(GemsPairOnControlState riga 41) . Per cui sarà passato come crush 0 e il ciclo diverrà:
viene spostata la texture verso l'esterno
Finalmente non salviamo più il timeStamp.
Precedentemente o successivamente, lo sprite sarà uscito dallo schermo.
In questo caso smettiamo anche di spostare la texture verso l'esterno
Ma il ciclo rimane.
A questo punto, se dall'ultimo timeStamp passato sono passati sufficienti millisecondi(crushBoxUpdateRate da config) allora lo sprite viene reso invisibile(in teoria lo era gia, visto che era fuori schermo).
A questo punto si aspetta la prossima crush.
mi pare il tutto abbastanza fragile. Se lo si vuole rivedere, va capito bene come si deve comportare il crushBox. Jocchan? Fran? :help:
Il comportamento della crushbox deve essere questo:
- comparire nella posizione prefissata
- ingrandirsi fino al valore indicato in config (senza spostarsi)
- tornare alle dimensioni normali (sempre senza spostarsi)
- scorrere fuori dallo schermo
- venire cancellata.
quindi va bene che non si muova mentre sta pulsando ;)
Altra cosa. Nel PlayfieldDescriptor vengono passate la warningBox e la counterBox, ma per il gameOverBox e la crushBox viene passata solo la posizione.
Forse e' YAGNI, ma sarebbe molto piu' sensato uniformare le cose ( il che implica anche una semplificazione del codice della create dei playfield)
Il comportamento della crushbox deve essere questo:
- comparire nella posizione prefissata
- ingrandirsi fino al valore indicato in config (senza spostarsi)
- tornare alle dimensioni normali (sempre senza spostarsi)
- scorrere fuori dallo schermo
- venire cancellata.
quindi va bene che non si muova mentre sta pulsando ;)
Ok.
Per cui crushBoxUpdateRate lo casso.
Se capita una doppia crush, vuoi che il comportamento sia identico, tranne che a un certo punto dell'ingrandimento cambia la texture?
Se capita una doppia crush, vuoi che il comportamento sia identico, tranne che a un certo punto dell'ingrandimento cambia la texture?
Cosa intendi per doppia crush?
Una nuova crush prima che la crushbox sia sparita?
E' possibile?
Cosa intendi per doppia crush?
Una nuova crush prima che la crushbox sia sparita?
E' possibile?
una crush doppia, cioè quando una cancellazione(di chest) ne genera un altra per la caduta
una crush doppia, cioè quando una cancellazione(di chest) ne genera un altra per la caduta
Aspetta, prima di tutto la crush tecnicamente sarebbe l'insieme delle cancellazioni a catena (via chest) :P
La crushbox deve essere mostrata dopo che queste cancellazioni consecutive terminano, non prima, e quindi viene già scelta la texture giusta.
Aspetta, prima di tutto la crush tecnicamente sarebbe l'insieme delle cancellazioni a catena (via chest) :P
La crushbox deve essere mostrata dopo che queste cancellazioni consecutive terminano, non prima, e quindi viene già scelta la texture giusta.
attualmente non è così.
Avviene la prima crush.
Il crushBox non viene fuori.
Scendono le gemme e avviene una seconda crush.
Viene mostrato il crushbox 2x.
Questo incomincia a espandersi.
Scendono le gemme e avviene una terza crush.
Mentre il crushBox continua ad espandersi, viene cambiata la texture nel 3x.
E cosi via.
Come non detto, ho controllato ed è giusto il comportamento attuale.
Ricordavo male io.
Come non detto, ho controllato ed è giusto il comportamento attuale.
Ricordavo male io.
ok, allora quella parte la replico così come è ora
ok, allora quella parte la replico così come è ora
Ottimo lavoro.
Ottimo lavoro.
fatto e committato.
mancano i test da parte di playField che usa il crushBox, ma crushBox è interamente testata.
fatto e committato.
mancano i test da parte di playField che usa il crushBox, ma crushBox è interamente testata.
Bene. Aggiungi i test di playfield e abbiamo finito qui?
non ho ancora aggiunto i test da playField...
ma volevo porre alla vs attenzione questo codice(fatto da me) per crushBox
public void update(int crushCounter)
{
if (crushCounter >= 2 && crushCounter > this.crushCounter)
{
if (!isPulsing())
{
show();
startPulsation(new SinglePulsation(crushBoxPulsationLength, crushBoxSizeMultiplier));
}
this.crushCounter = crushCounter;
setTexture(getTexture(crushCounter));
}
if (!isHidden())
{
if (getPulsation() != null)
{
if (getPulsation().ended())
{
stopPulsation();
}
}
else if (!isOffScreen())
{
setPosition(getPosition().getX() + speed, getPosition().getY());
} else
{
hide();
this.crushCounter = 1;
}
}
}
ci sono troppi if...sta sotto il limite di checkStyle, ma non è cmq il max da vedere. Si potrebbe estrarre qualche metodo, ma poi il metodo risultante avrebbe poco significato da solo(aka si abbasserebbe la complessita ciclotomatica in maniera fittizia IMHO)..
se qualcuno ha qualche idea, killi pure sto codice.
ps. sono ammesse le tecniche okuto e nanto.
ci sono troppi if...sta sotto il limite di checkStyle, ma non è cmq il max da vedere. Si potrebbe estrarre qualche metodo, ma poi il metodo risultante avrebbe poco significato da solo(aka si abbasserebbe la complessita ciclotomatica in maniera fittizia IMHO)..
se qualcuno ha qualche idea, killi pure sto codice.
ps. sono ammesse le tecniche okuto e nanto.
Quando i metodi da estrarre non sarebbero chiari, vuol dire che non e' chiaro a te per primo cio' che il metodo sta facendo, e come potrebbe farlo meglio. Pensaci un po' e togli tutti questi if. Questo metodo mi fa pensare che checkstyle e' troppo buono: lo stringo un po'.
PS. Il prossimo commento in italiano che leggo scatta il revert automatico
//TODO sono incazzato per l'inter, per cui questo metodo da CC di 8 se lo semplifica qualcun'altro
Sono anch'io incazzato per l'Inter, ma non lo scrivo nella codebase :)
jappilas
15-03-2008, 13:24
//TODO sono incazzato per l'inter, per cui questo metodo da CC di 8 se lo semplifica qualcun'altro
:mbe:
:nonsifa:
:banned:
Se i metodi da estrarre non sarebbero chiari, vuol dire che non e' chiaro a te per primo cio' che il metodo sta facendo, e come potrebbe farlo meglio. Pensaci un po' e togli tutti questi if. Questo metodo mi fa pensare che checkstyle e' troppo buono: lo stringo un po'.
ho provato a cambiare in questo
public void update(int crushCounter)
{
if (onCreation(crushCounter))
{
show();
startPulsation(new SinglePulsation(crushBoxPulsationLength, crushBoxSizeMultiplier));
}
if (onChangeTexture(crushCounter))
{
this.crushCounter = crushCounter;
setTexture(getTexture(crushCounter));
}
if (onStopPulsing())
{
stopPulsation();
}
if (onMovingOut())
{
setPosition(getPosition().getX() + speed, getPosition().getY());
}
if (onHide())
{
hide();
this.crushCounter = 1;
}
}
private boolean onHide()
{
return !isHidden()
&& isOffScreen()
;
}
private boolean onMovingOut()
{
return !isHidden()
&& getPulsation() == null
&& !isOffScreen()
;
}
private boolean onStopPulsing()
{
return !isHidden()
&& getPulsation() != null
&& getPulsation().ended()
;
}
private boolean onChangeTexture(int crushCounter)
{
return crushCounter >= 2
&& crushCounter > this.crushCounter
;
}
private boolean onCreation(int crushCounter)
{
return onChangeTexture(crushCounter)
&& !isPulsing()
;
}
ho "srotolato" alcune condizioni, percui alla fine le condizioni esaminate sono di più. Però da leggere è probabilmente più chiaro, e si riesce a capire meglio quando capita qualcosa.
E' cambiato però un comportamento. Prima il crushBox incominciava a spostarsi verso l'esterno 2 turni dopo rispetto a quando smetteva di pulsare. Penso che sia più corretto che incominci a spostarsi il turno direttamente successivo.
//TODO sono incazzato per l'inter, per cui questo metodo da CC di 8 se lo semplifica qualcun'altro
Sono anch'io incazzato per l'Inter, ma non lo scrivo nella codebase :)
quella roba l'ho incominciata a scrivere martedi sera dopo 2 birre, e poi mi sono dimenticato di toglierla quando ho finito e committato...
fra l'altro è stato abbastanza lungo capire come funzionava prima il codice, far passare i test, vedere che cmq nn funzionava come prima, mettersi in debug in gioco(con doppio schermo per vedere che succedeva e quando succedeva), spiegarlo a joc, l'inter che esce, etc etc che ormai odiavo il crushBox, volevo solo vederlo funzionare senza che checkStyle mi stracciasse la wuallera...
E' cambiato però un comportamento. Prima il crushBox incominciava a spostarsi verso l'esterno 2 turni dopo rispetto a quando smetteva di pulsare. Penso che sia più corretto che incominci a spostarsi il turno direttamente successivo.
Non committare.
Ho rifattorizzato cosi':
public void update(int newCrushCounter)
{
if (canUpdateCounter(newCrushCounter))
{
updateCounter(newCrushCounter);
}
if (isHidden())
{
return;
}
if (!isPulsing())
{
if (isOffScreen())
{
hide();
resetCounter();
}
moveRight(speed);
}
updatePulsation();
}
private void updateCounter(int newCrushCounter)
{
setCrushCounter(newCrushCounter);
if (!isPulsing())
{
startSinglePulsation(pulsationLength, sizeMultiplier);
}
}
private boolean canUpdateCounter(int newCrushCounter)
{
return newCrushCounter >= 2 && newCrushCounter >= this.crushCounter;
}
private void setCrushCounter(int newCrushCounter)
{
this.crushCounter = newCrushCounter;
updateTexture(crushCounter);
}
Ed ho portato su qualche metodo che appartiene logicamente a Sprite.
Ultimo colpetto:
public void update(int newCrushCounter)
{
if (canUpdateCounter(newCrushCounter))
{
updateCounter(newCrushCounter);
}
if (isHidden())
{
return;
}
updatePosition();
updatePulsation();
}
private void updatePosition()
{
if (isPulsing())
{
return;
}
if (isOffScreen())
{
hide();
resetCounter();
}
else
{
moveRight(speed);
}
}
Si legge come fosse inglese vero?
I test erano ottimi, ho lavoro senza mai lanciare il gioco, semplicemente guardando fallire i test per capire la logica di questo codice.
I test erano ottimi, ho lavoro senza mai lanciare il gioco, semplicemente guardando fallire i test per capire la logica di questo codice.
Grazie, lo so che siamo bravi :sofico:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.