Ich habe mir die exe und den sourcecode jetzt doch mal angeschaut.
Ein paar allgemeine vorschläge:
1. BlockVector in CBlock::ResizeVector nicht immer wieder resizen, sondern im konstruktor einmal auf maximalgröße anlegen (4x4?) und in CBlock::ResizeVector (bzw. in einer neuen methode CBlock::CleanVektor) jedes mal nur den aktiven bereich löschen (=STANDARD). Dadurch können in CBlock::Reset alle BlockVector[0][1] = STANDARD; entfallen.
Also:
ResizeVector(4, 4);
nach CBlock::CBlock() (das gleiche gilt für TempVector in CBlock::Rotate, was in CBlock::CBlock() ja schon halb passiert, aber leider mit undefinierten werten für m_VecRows und m_VecCells)
und neue löschfunktion (CBlock::CleanVektor) für BlockVector (dann gleich auch für TempVector).
2. in fällen wie z.b.
if(DetectCollision(Rows+1, Cells) == true || m_VPosition >= 700-m_VecRows*50)
oder
if(Dir == LEFT && DetectCollision(Rows, Cells-1) == false && m_HPosition-50 >= (SCR_WIDTH-600)/2)
immer die billigen ausdrücke nach links, denn damit erspart man sich oft einen aufwändigen aufruf einer methode, obwohl ein einfacher integer-vergleich auch gereicht hätte (z.b. wenn ich ganz links bin, brauche ich keine kollisionserkennung um zu wissen, dass ich nicht weiter nach links kann).
Um das rutschen in letzter sekunde zu ermöglichen, müsste man eine "eindringtiefe" definieren, die ein block nach unten eindringen könnte, ohne dass die bewegung beendet ist. Ein sinnvoller wert wäre eine halbe bis maximal ganze blockhöhe (evtl. durch schwierigkeitsgrad änderbar).
Sobald eine kollision bemerkt wird, wird die eindringtiefe berechnet. Ist diese klein genug, erfolgt die darstellung um diesen wert höher (also nicht eingetaucht) und es läuft alles weiter wie gehabt. Wird eine seitwärtsbewegung vorgenommen, und die bahn ist wieder frei, wird die nächste kollisionserkennung keine kollision mehr erkennen und die neue eindringtiefe ist 0.
Also:
in class CBlock
kommt
int Penetration;
rein, in
CBlock::Move(int Framerate)
käme die berechnung der aktuellen eindringtiefe hinzu. Aus
if(DetectCollision(Rows+1, Cells) == true || m_VPosition >= 700-m_VecRows*50)
wird
Penetration=0;//soweit kein offset
if(DetectCollision(Rows+1, Cells) != true && m_VPosition < 700-m_VecRows*50)
return;//weder kollision noch boden
int tempPenetration =(int)m_VPosition % 50;
if(tempPenetration<=maxPenetration){//kollision, aber nicht lange/tief genug
Penetration=tempPenetration
return;
}
//richtige kollision, rest wie gehabt
und in
CBlock::Draw
wird aus
rDestRect.top = m_VPosition+j*50;
rDestRect.bottom = m_VPosition+j*50+50;
das hier
rDestRect.top = m_VPosition-Penetration+j*50;
rDestRect.bottom = rDestRect.top+50;
Ich habe das nicht ausprobiert und evtl. muss noch die endposition beim festmachen angepasst werden, aber in etwa sollte das so laufen.
mr.escape