Programmieren - alles kontrollieren 4.941 Themen, 20.708 Beiträge

DirectX C++: Fragen zu Tetris

Yves3 / 10 Antworten / Baumansicht Nickles

hallo

ich programmiere im moment ein tetris. es ist mein erstes projekt und bisher hat eigentlich alles ziemlich gut funktioniert.

jetzt habe ich aber ein problem, bei dem ich noch keine brauchbare lösung finden konnte.

ich möchte, dass man einen block noch in letzter sekunde seitwärts unter einen anderen schieben kann.
das funktiniert aber nur, wenn die lücke höher als eine block ist.

ich wäre sehr dankbar, wenn sich jemand den code mal anschauen und mir ein paar lösungsansätze liefern könnte.

ach und noch was:
bei den meisten schriftarten sinkt die framerate vom maximum (60) auf 30 wenn ich sie verwende.
deshalb verwende ich im moment die schrift "Broadway BT", die ist aber ziemlich unpassend und hässlich.
was kann ich tun, um auch andere schriftarten einsetzen zu können?

den source und eine kompillierte version könnt ihr hier downloaden:

http://www.gmbtechnik.ch/yves/code/tetris_source.rar

vielen dank für alle antworten!

bei Antwort benachrichtigen
mr.escape Yves3 „DirectX C++: Fragen zu Tetris“
Optionen

Ohne den code jetzt gesehen zu haben, würde ich das problem mit dem darunter schieben so realisieren, dass ich das "festmachen" um einige zehntel sekunden verzögere, d.h. z.b. ein bis drei frames (am besten durch probieren zu ermitteln).

Alternativ könnte das "festmachen" auch erst erfolgen, wenn die nächste bewegung nach unten erfolgen soll das aber nicht geht. Damit könnte ein stein noch eine kurze zeit hin und her rutschen und könnte so auch noch tiefer als eine position seitlich rein. Eigentlich ist das sogar einfacher und eleganter als meine erste idee.

mr.escape

"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Yves3 mr.escape „DirectX C++: Fragen zu Tetris“
Optionen

bei mir ist das eben ein bisschen anders.
ich bewege den block nicht stufenweise.
ich müsste irgendwo eine kleine pause einbaue, dann würde aber die ganze spielschliefe gebremst und das ist nicht akzeptabel.
oder lässt sich das irgenwie umgehen?

gruss yves

bei Antwort benachrichtigen
PaoloP Yves3 „DirectX C++: Fragen zu Tetris“
Optionen

Sorry, aber ich werde jetzt nicht deinen Code durchgehen.
Was die Schriftart betrifft sind das immer noch GDI-Funktionen und die sind der Performance unberechenbar-leider. Die meisten Entwickler bauchen sich einen Schrif-Blitter d.h. du schreibts genau so wie Sprites auf den Bildschirm zauberst, die einzelnen Buchstaben kannst z.B. in Paint schreiben und entsprechend einrücken.
Dann musst du eine Klasse entwickeln die sich darum kümmert das schreiben/blitten zu übernehmen, da gibts übrigens fertige Klassen im Netz.
Das 2. gute daran ist das Du auf keine Schrift mehr angwiesen bist die auf dem Rechner des Endbenutzers vorhanden sein muss. mir persönlich sind kleine games ohne jede abhängigkeit also auch keine installation am liebsten.


Jedes mal wenn jemand "Cloud" sagt, verliert ein Engel seine Flügel.
bei Antwort benachrichtigen
Yves3 PaoloP „Sorry, aber ich werde jetzt nicht deinen Code durchgehen. Was die Schriftart...“
Optionen

danke, ich werd es so machen.
ein bisschen mehr aufwand aber es sieht dann auch besser aus.

bei Antwort benachrichtigen
DaWoo Yves3 „DirectX C++: Fragen zu Tetris“
Optionen

*kinnladerunterfall* gut gemacht, ich kenn mich leider nicht so gut aus aber bei mir hab ich Framerates von 220 FPS.

bei Antwort benachrichtigen
Yves3 DaWoo „ kinnladerunterfall gut gemacht, ich kenn mich leider nicht so gut aus aber bei...“
Optionen

danke für dein komliment!
220 FPS? hast du die begrenzung rausgenommen oder hat sie nicht funktioniert?

gruss yves

bei Antwort benachrichtigen
DaWoo Yves3 „DirectX C++: Fragen zu Tetris“
Optionen

Vsync ist aus. Hab eine Radeon 9500 als 9700 Pro gemoddet und fast 9800r Taktung. Spiel lief aber so eine ganz normale Geschwindigkeit, also nicht unspielbar rasant.

bei Antwort benachrichtigen
Yves3 Nachtrag zu: „DirectX C++: Fragen zu Tetris“
Optionen

naja diesen post schaut sich wohl niemand mehr an aber ich schreibe es troztdem mal ;-)

hab mir heute mehr so zufällig die statistik der zugriffe auf den server angeschaut.
hatte 21 zugriffe auf die datei tetris_source.rar :-)

war doch ein bisschen überrascht, dass sich soviele den sourcecode angeschaut haben um mir zu helfen, oder auch einfach nur aus interesse. (oder um das game mal auszuprobieren *lol*)

danke nochmal!

bei Antwort benachrichtigen
mr.escape Yves3 „naja diesen post schaut sich wohl niemand mehr an aber ich schreibe es troztdem...“
Optionen

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

"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen
Yves3 mr.escape „Ich habe mir die exe und den sourcecode jetzt doch mal angeschaut. Ein paar...“
Optionen

danke, dass du dir schon wieder zeit für mich genommen hast!

deine ersten beiden tipps hab ich bereits angewendet.

über die reihenfolge der bedingungen hab ich mir bisher nie gedanken gemacht. wieder was gelernt :-)

den dritten punkt schau ich mir jetzt auch noch an, mal sehen ob ich s so hinbekomme.

gruss yves

bei Antwort benachrichtigen