Größenunabhängig!?

Verschiedenes zu Qt
Antworten
Dragonix
Beiträge: 11
Registriert: 25. September 2006 22:21

Größenunabhängig!?

Beitrag von Dragonix »

Hi mal wieder :)
Hab mal wieder ein Problem, nämlich folgendes:
Ich lasse ein QRect mit den Coordinaten (0,0, 50, 20) zeichnen; wenn ich das Fenster jetzt allerdings maximiere, ist das Rect zwar noch genauso groß, allerdings das Fenster größer ==> das ganze Layout verschiebt sich.
Kann man das irgendwie umgehen? Also gibts eine Funktion, die automatisch alles Propotional zur Fenstergröße macht? Ich lass das QRecht jetzt immer so zeichnen: QRect(0, 0, width() / 20, height() / 30); aber das ist m.e. nicht besonders übersichtlich und das resultat ist auch wenig zufriedenstellend.

Nächste Frage:
Wenn ich mein kleines Spiel (immer noch ein Breakout spiel, hab doch noch nciht aufgegeben) maximiere, dann bewegt sich der Ball sehr langsam (ist logisch, da er sich ja auch nur 1 Pixel / sekunde bewegt, und das Fenster ja jetzt größer ist, dass ist wieder ein verhältnis Problem wie oben, an dem ich gerade arbeite) aber die Performance geht auch in den Keller. Hat er das Bild vorhin noch alle 5 msec (QTimer) gezeichnet, updatet ers jetzt vlt alle 10 sekunden. Ist das normal? Merken du ichs daran, dass ich mir die gezeichneten Frames ausgeben lasse...




Vielen Dank im Voraus,
Matthias
webmaster1987
Beiträge: 73
Registriert: 2. September 2006 18:30
Wohnort: Köln
Kontaktdaten:

Beitrag von webmaster1987 »

also zum ersten würde ich sagen das ist der richtige ansatz brauchst du ein rechteck oder muss es ein quadrat sein?

für frage 2 würde ich gern ein bisschen code sehen
DOUBLE ist wie FLOAT nur in HD
Dragonix
Beiträge: 11
Registriert: 25. September 2006 22:21

Beitrag von Dragonix »

Was für Code? Alles wär glaub ein bischen zu viel fürs forum...
Reicht paintEvent(QPaintEvent *) (und die Funktionen die dadurch aufgerufen werden)?
grazerstudent
Beiträge: 3
Registriert: 19. September 2006 15:52

update(x,y,w,h)

Beitrag von grazerstudent »

Ich glaube, du hast das gleiche Problem wie ich.
Ich nehme an, dass du immer das gesamte Widget updatest, statt nur den Teil, der wirklich neu gezeichnet werden müsste. (Daher die schlechtere Performance, trotz gleicher Aktion).

Ich habe lange geglaubt, dass ich nur den veränderten Teil neu zeichnen würde [ mit repaint(x,y,w,h)]. Allerdings funktioniert genau diese repaint-Funktion zumindest mit Qt 4.0.0 nicht. Sie zeichnet immer das ganze widget neu, egal, was du als Rechteck definiert hast.
Ich verwende deshalb die update(x,y,w,h)-Funktion. Die zeichnet wirklich nur das Kastl neu, das man ihr übergibt.

Ob repaint(qrect) funktioniert, hab ich noch nicht ausprobiert.

Würd mich freun, wenn ich dir helfen konnte.
lg georg
webmaster1987
Beiträge: 73
Registriert: 2. September 2006 18:30
Wohnort: Köln
Kontaktdaten:

Beitrag von webmaster1987 »

jo ich denke das und alle stellen an dennen du es aufrufst
DOUBLE ist wie FLOAT nur in HD
Dragonix
Beiträge: 11
Registriert: 25. September 2006 22:21

Beitrag von Dragonix »

Also, hier mal ne kleine Zusammenfassung was die files sind:
Gameboard: 'Master Widget', erbt von QWidget; sorgt dafür das der rest gezeichnet wird (Ball und Paddle)

Ball: Der Ball, erbt von QObject
Paddle: Das Paddle, erbt auch von QObject

Hier mal die einzelnen Zeichenpassagen:
paintEvent vom Gameboard:

Code: Alles auswählen

void Gameboard::paintEvent(QPaintEvent *)
{
	QPainter painter(this);
	if(mGameOver)
	{
		painter.setPen(Qt::red);
		painter.setFont(QFont("Courier", 48, QFont::Bold));
		painter.drawText(rect(), Qt::AlignCenter, tr("Game Over"));
	}
	mainPaddle->redraw(painter);
//	mBrick1->paintBrick(painter);
	Ball1->redraw(painter);
	painter.setFont(QFont("Courier", 12, QFont::Bold));
	painter.drawText(width() - 100, height() - 100, QString::number(++mPaintedFrames));
}
Hier der redraw vom Paddle:

Code: Alles auswählen

void Paddle::redraw(QPainter &painter)
{
	painter.save();
	painter.translate(0, parentGameboard->height());		//because we 'translated' the cosy...
	mPaddleCenterPoint.setY(mPaddleCenterPoint.y() - parentGameboard->height());	//...we need to change the y point!
	painter.setBrush(Qt::white);

	if(mPaddleCenterPoint.y() < - 25)
		mPaddleCenterPoint.setY( - 25);
	else if(mPaddleCenterPoint.y() > -5)
		mPaddleCenterPoint.setY(-5);

	if(mPaddleCenterPoint.x() < (mPaddle().width()/2)-1)
		mPaddleCenterPoint.setX((mPaddle().width()/2)-1);
	else if(mPaddleCenterPoint.x() > parentGameboard->width()-(mPaddle().width()/2)-1)
		mPaddleCenterPoint.setX(parentGameboard->width()-(mPaddle().width()/2)-1);

	painter.drawRect(mPaddle());
	painter.restore();
}
Hier der redraw vom Ball:

Code: Alles auswählen

void Ball::redraw(QPainter &painter)
{
	painter.save();
	painter.translate(0, parentGameboard->height());

	painter.setBrush(Qt::white);
	painter.drawPie(mBall(), 0, 16 * 360);
	painter.restore();
}
Dann... gibts eine Funktion namens moveBall() die alle 5 msec aufgerufen wird und die nächste Position des balls berechnet (dementsprechend wird alle 5 msec das bild neu gezeichnet):

Code: Alles auswählen

void Ball::moveBall()
{

	float x = x_vel * parentGameboard->width() / 300;
	float y = y_vel * parentGameboard->height() / 300;
	QRegion region(mBall());

	mBallCenterPoint = QPoint(mBallCenterPoint.x() + qRound(x), (mBallCenterPoint.y() - qRound(y)));
	
//Hier sind seeeeehr viele Kolisionsabfragen(vlt 15 else-if), aber laut //irgendeiner winapi funktion dauert es 0 ms... (irgendwas mit GetTickCount() oder so); ich glaub aber nicht, dass es zu viel abfragen //sind, da es im kleinen fenster ja auch geht, und im großen fenster wird die funktion ja auch nicht öfters aufgerufen / hat ja auch nicht mehr zu tun...


	region.unite(mBall());
	emit regionUpdate(region);//ein signal das mit update(QRegion &) //vom Gameboard aufruft.
}

Dann noch die Funktion, die das Paddle dahinsetzt wo der mauscurser ist:

Code: Alles auswählen

void Paddle::setPaddleCenterPoint(const QPoint &nPoint, const int &gameStarted)
{
	if(mPaddleCenterPoint != nPoint)
	{
		QRegion region(mPaddle());
		mPaddleCenterPoint = nPoint;
		region.unite(mPaddle());
		emit regionUpdate(region);		//the changed region is updated
	}
}
Sollt ich dir regionen vlt 'fest' einbauen? Die werden ja jetzt jedesmal neu erstellt, oder?!
Soll ich euch vlt auch mal die EXE + sources hochladen?
Dragonix
Beiträge: 11
Registriert: 25. September 2006 22:21

Beitrag von Dragonix »

*drück, schieb*
Hier mal der komplette sourcecode + exe + qt-dlls:
**Link entfernt**

Arbeite atm mit setfixedsize, aber so richtig glücklich machen tuts micht nicht.
Aaaaaber: Ich bekomms nicht hin, dass sich der ball gleichschnell bewegt :( Könnt ihr das vlt auch einfach mal testen? Also nur die compilerte exe ausführen und mir sagen obs bei euch auch so ist? Danke :)
Zuletzt geändert von Dragonix am 5. Oktober 2006 21:35, insgesamt 1-mal geändert.
webmaster1987
Beiträge: 73
Registriert: 2. September 2006 18:30
Wohnort: Köln
Kontaktdaten:

Beitrag von webmaster1987 »

habe es versucht bei mir kann ich es nicht kompilieren ich hab windows + qt 4.1.4
DOUBLE ist wie FLOAT nur in HD
Dragonix
Beiträge: 11
Registriert: 25. September 2006 22:21

Beitrag von Dragonix »

Compiler?
Habs mim VS2005 gemacht.
Einen Moment, ich schau mal ob ichs auch mim mingw hinbekomm ;)
Denk aber ich weis schon worans liegt...
eine frage, der bringt mir immer warnings wie:
No new line at EOF. Was hat das zu bedeuten? Ist das wichtig das am ende ne neue zeile ist!?
webmaster1987
Beiträge: 73
Registriert: 2. September 2006 18:30
Wohnort: Köln
Kontaktdaten:

Beitrag von webmaster1987 »

das hab ich meinen lehrer auch mal gefragt :D

:idea:

da will einem der compiler zeigen das man evl. nicht mit dem code fertig ist da laut compiler logik ein code erst "fertig" ist wenn man am schluss eine leerzeile setzt.
DOUBLE ist wie FLOAT nur in HD
Dragonix
Beiträge: 11
Registriert: 25. September 2006 22:21

Beitrag von Dragonix »

Ok thx, ich editier den link oben nochmal raus, der code lässt sich ja keine 10 Zeilen übersetzen (zumindest mit mingw) :oops:
Ich hoff mal das ich die falsche version geuploaded hab :oops:
Aber Thx :)

Manmanman, was der MSVC auf dem niedrigsten (oder höchsten) warninglevel nicht nazeigt, stört den MinGW so arch, dass ers nedd compilert... des dauert doch etwas länger als geplant...
Antworten