Mausabfrage an Bildwiederholrate gebunden?
Übersicht

![]() |
Ryo SaebaBetreff: Mausabfrage an Bildwiederholrate gebunden? |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
ich habe erst vor kurzem begonnen, mit Blitz3D zu arbeiten und habe mir erstmal ein etwas weniger kompliziertes Projekt als Einstieg ausgesucht: PONG! Ich gehe einfach mal davon aus, dass sich jeder etwas darunter vorstellen kann ^_-. In meiner PONG Variante hat man nun allerdings die Möglichkeit, seinen Schläger (aka Paddle) per Maus in X und Y Richtung zu bewegen. Als ich den Schläger nun aber immer an der Mausposition anzeigen ließ, fiel mir auf, dass der "MouseSpeed" erschreckend hoch war. Der Mauszeiger legte bei einem Schleifendurchlauf meines Programms, bis zu 500 und mehr Pixel zurück (bei einer Auflösung von 640x480), wenn ich meine Maus wirklich schnell bewegte. Das macht eine genaue Kollisionsabfrage natürlich unmöglich, wenn ich die Kollisionsmaske des Schlägers mit der des Balles vergleichen würde, würde es bei solchen großen Sprüngen vermehrt vorkommen, dass man durch den Ball "durchschlägt". Die Lösung schien mir nun, eine maximale Geschwindigkeit des Schlägers als Obergrenze festzusetzen. Dies hab ich folgendermaßen umgesetzt: Code: [AUSKLAPPEN] Function PlayerControls ()
;player1 pl1\mouse_x = MouseX () pl1\mouse_y = MouseY () ;mouse movement restriction ;(can only move pl1\mouse_x_max and pl1_mouse_y_max pixel per loop) If pl1\mouse_x > pl1\mouse_x_old + pl1\mouse_x_max pl1\mouse_x = pl1\mouse_x_old + pl1\mouse_x_max pl1\mouse_x_old = pl1\mouse_x MoveMouse pl1\mouse_x, pl1\mouse_y ElseIf pl1\mouse_x < pl1\mouse_x_old - pl1\mouse_x_max pl1\mouse_x = pl1\mouse_x_old - pl1\mouse_x_max pl1\mouse_x_old = pl1\mouse_x MoveMouse pl1\mouse_x, pl1\mouse_y Else pl1\mouse_x_old = pl1\mouse_x EndIf If pl1\mouse_y > pl1\mouse_y_old + pl1\mouse_y_max pl1\mouse_y = pl1\mouse_y_old + pl1\mouse_y_max pl1\mouse_y_old = pl1\mouse_y MoveMouse pl1\mouse_x, pl1\mouse_y ElseIf pl1\mouse_y < pl1\mouse_y_old - pl1\mouse_y_max pl1\mouse_y = pl1\mouse_y_old - pl1\mouse_y_max pl1\mouse_y_old = pl1\mouse_y MoveMouse pl1\mouse_x, pl1\mouse_y Else pl1\mouse_y_old = pl1\mouse_y EndIf paddle (pl1\obj)\x_pos = pl1\mouse_x paddle (pl1\obj)\y_pos = pl1\mouse_y Collision () End Function Soweit so gut, aber nun muss man einen Spagat schlagen, zwischen der Schnelligkeit des Schlägers und der Genauigkeit der Kollisionsabfrage. Ich habe pl1\mouse_x_max und pl1\mouse_y_max ersteinmal auf die Hälfte der Breite meines Schlägers gesetzt, sodass sich die Kollisionsmasken von Ball und Schläger, selbst bei hohen Geschwindigkeiten, nicht komplett verfehlen, aber nun ist das auch alles etwas ungenau. Die beste Lösung wäre nun, so dachte ich mir, einfach die Anzahl der Schleifendurchläufe meines Programms zu erhöhen. Bisher lief das Programm mit 100 Durchläufen pro Sekunde, ich hab dies einfach mal probeweise auf 1000 gestellt und siehe da, ich kann den Ball nun pixelgenau schnell bewegen (wo er vorher 10-20 Pixel große Sprünge machen musste, um diese Geschwindigkeit zu erreichen, was die Kollisionsabfragen ungenauer machte). Das mir unerklärliche Problem ist nun, dass sich der Schläger immer noch mit genau derselben Maximalgeschwindigkeit bewegt, wie mit 100 Durchläufen. Deshalb meine Frage: ist die Abfrage der Mausbewegung an die Bildschirmwiederholfrequenz (die bei mir auf 100Hz steht) gebunden oder hab ich einen Fehler in meinem "Mauszeigerverlangsamungscode"? Die Tastaturabfrage funktionierte nähmlich im Gegensatz zur Mausabfrage problemlos, als ich den Schläger testweise per Tastatur steuerte, war es mir ohne weiteres möglich, ihn schnell mit Pixelpräzision zu bewegen. |
||
![]() |
skey-z |
![]() Antworten mit Zitat ![]() |
---|---|---|
wenn du im 3D modus bist und den vSync ausschaltest(Flip 0) sind die Frames pro Sekunde nicht an die Bildwiederholrate des Monitors gekoppelt.
Wie stellst du eigentlich die Wiederholrate ein? |
||
Awards:
Coffee's Monatswettbewerb Feb. 08: 1. Platz BAC#57: 2. Platz |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ja, ich weiß, genau so hatte ich's gemacht.
Hier mal meine Spielschleife: Code: [AUSKLAPPEN] ;Main Game Loop Repeat Cls WaitTimer (frame_Timer) ...Funktionsaufrufe... Flip (0) Until KeyHit (1) End Den frame_timer habe ich wie gesagt zu Probezwecken auf 1000 gesetzt. Der Schläger ließ sich nun mit der Tastaturabfrage pixelgenau und schnell steuern, mit der Mausabfrage allerdings nicht, da war es wie gesagt immer noch so "langsam" als stünde der frame_timer noch auf 100. |
||
![]() |
Tankbuster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: wie gesagt immer noch so "langsam" als stünde der frame_timer noch auf 100. vielleicht weil dein PC nicht mehr "schafft"^^
|
||
Twitter
Download Jewel Snake! Windows|Android |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
Nein, ich glaube das kann ich ausschließen denn: das Spiel ist noch zu simpel, ich erreiche die 1000 Durchläufe und mit der Tastaturabfrage statt der Mausabfrage funktioniert es ja auch. ^_-
Die Maximalgeschwindigkeit der Maus scheint immer gleich, egal ob 100, 500 oder 1000 Durchläufe. Ich nehme daher stark an, dass das Problem entweder an einem Fehler in meinem "mouse movement restriction" Code liegt, oder aber daran, dass die Befehle MouseX() und MouseY(), im Gegensatz zu anderen Befehlen wie zB. KeyDown(), an die Bildwiederholfrequenz gebunden sind, soll heißen: ist die Bildwiederholfrequenz auf 100Hz, dann liefert der Befehl MouseX() auch nur 100 mal pro Sekunde einen neuen Wert, auch wenn er 1000 mal pro Sekunde ausgeführt wird. |
||
![]() |
StepTiger |
![]() Antworten mit Zitat ![]() |
---|---|---|
WaitTimer ist eine der sinnlosesten Funktionen von Blitz.
Im Codearchiv gibt es einige CPU-sparendere Routinen. Bestenfalls mal suchen. |
||
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer: AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t Gewinner: BP Code Compo #2 Π=3.141592653589793238...<--- und das aus dem kopf ![]() Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser. |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke für den Tip, aber das hat leider nichts mit meinem Problem zutun. Ich habe keine Performanceprobleme ^^' | ||
![]() |
StepTiger |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich kann nicht verstehen, wieso MouseXSpeed solche Werte zurückgibt, denn genau diesen Wert müsste es auch auf dem Monitor zurücklegen.
Sonst immer die Maus auf die Mitte setzen, das klappt bei mir hervorragend und du benötigst keine Umwege. |
||
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer: AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t Gewinner: BP Code Compo #2 Π=3.141592653589793238...<--- und das aus dem kopf ![]() Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser. |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
Genau diese Werte legte der Mauszeiger ja auch zurück^^, das war mein anfängliches Problem, dass ich durch den "mouse movement restriction" Code gelöst habe.
Wenn ich meinen Mauszeiger unter Windows schnell hin und herbwege, dann kann ich ihn kaum noch sehen.. Werte von 500 Pixeln in 1/100 Sekunde sind also durchaus nachvollziehbar imo. Und warum sollte ich die Maus immer auf die Mitte setzen? Wie soll das mein Problem lösen bzw. hast du meine Frage überhaupt verstanden? Im Prinzip möchte ich ja "nur" ein Objekt im Spiel (den Schläger) mit meiner Maus bei tausend Mausabfragen pro Sekunde mit einem Pixel Genauigkeit bewegen, sodass sich dieses Objekt genauso schnell bewegt, als ob ich es mit Tastaturabfragen bewegen würde. Nur leider funktioniert das wie gesagt nicht so recht.. Oo |
||
- Zuletzt bearbeitet von Ryo Saeba am Do, Mai 03, 2007 21:04, insgesamt einmal bearbeitet
![]() |
StepTiger |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich denke, du solltest die Mausempfindlichkeit mal etwas runterstellen.
Außerdem lässt sich das trotzdem über Mouse(?)Speed lösen. Du speicherst die Werte einfach in Variablen und setzt sie auf maximal 10 ![]() Dann setzt du die Maus wieder auf den Mittelpunkt, um das Entfliehen aus dem Fenster zu verhindern. |
||
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer: AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t Gewinner: BP Code Compo #2 Π=3.141592653589793238...<--- und das aus dem kopf ![]() Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser. |
![]() |
FireballFlame |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hm, ich seh das Problem nicht ganz.
Du willst eine Kollision zwischen Schläger und Ball prüfen (nehmen wir einfach mal an, mit ImagesCollide) und wenn der Schläger zu schnell ist, fliegt der Ball durch? Dann prüfe in jedem Hauptschleifendurchlauf, ob das Schlägertempo zu hoch ist (sodass die Kollision nicht mehr zuverlässig ist) und wenn ja, dann mach mehrere Kollisionsprüfungen... also nicht mehr nur eine für die aktuelle Schlägerposition, sondern auch noch eine für die Mitte zwischen der aktuellen und der vorigen Position... oder evtl. nochmehr Unterteilungen... ich hoffe du verstehst, was ich meine ^^ |
||
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
@StepTiger:
Nunja, genau das habe ich prinzipiell getan, nur eben anstatt MouseX/YSpeed zu verwenden habe ich es etwas umständlicher mit MouseX/Y umgesetzt und die vorherige Position mit der aktuellen verglichen. Ich setzte ebenfalls den Mauszeiger wieder neu (nicht in der Mitte, zugebenermaßen), um das Entfliehen zu verhindern. Ich habe nicht bezweifelt, dass man die Maus auch genausogut mit dem MouseX/YSpeed Befehl verlangsamen kann, darum geht es mir auch gar nicht. Das mit der Mausempfindichkeit ist eine heikle Sache, man sollte lieber seine eigene Mausbeschleunigung "coden", man stelle sich zB. vor das Spiel stürzt ab oder hängt den Computer auf.. die Navigation mit einer extrem langsamen Mausbeschleunigung ist die Hölle ^_- Außerdem dürfte das mein Problem auch nicht lösen, denn soweit ich das ausgetestet habe, ändert das nichts an der Anzahl der Mausabfragen pro Sekunde in Blitz. @FireballFlame: Das wollte ich nun gerade vermeiden, denn im Gegensatz zur Flugbahn des Balles (die ich ohne Probleme bis zum übersprungenen Kollisionszeitpunkt "zurückverfolgen" könnte, das stimmt), ist die Bewegung der Maus, leider für die Zeiträume zwischen zwei Abfragen, nicht genau berechenbar. Es steht nähmlich nicht fest, dass sich die Maus geradlinig bewegt hat, sie könnte ja auch in einem Bogen bewegt worden sein. Hinzukommt natürlich auch der Mehraufwand, denn abgesehen davon, dass ich den Kollisionszeitpunkt und Ort berechnen (oder besser "gut schätzen") müsste, müsste ich danach auch noch die Position des Balls korrigieren, da der ja nun schon vor "einiger Zeit" kollidiert ist, ohne es eigentlich zu merken xD und deshalb eigentlich schon ganz woanders sein müsste. Es ist zweifelsfrei möglich, nur eben sehr umständlich und ungenau und es würde mir immens viel Arbeit abnehmen, wenn ich die Position des Schläger bei der Maussteuerung so pixelgenau abfragen und so schnell bewegen könnte, wie mit der Tastatur. |
||
![]() |
FireballFlame |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich denke nicht, dass es ein Problem wegen Bogenbewegungen der Maus gibt. Ein nicht so leistungsfressendes Spiel wie Pong läuft normalerweise mit mindestens 60fps. Du kannst doch in einer 60stel Sekunde keine Bögen mit der Maus malen... so ein Bogen dauert dann schon mehrere Schleifendurchläufe und wird dann halt aus geraden Linien zusammengesetzt - da dürfte die Genauigkeit vollkommen ausreichend sein. Wenns nicht reicht (unwahrscheinlich), dann musst du halt die fps höher kriegen, anders gehts einfach nicht.
Die Flugbahn des Balles ist meiner Meinung nach ebenfalls mit 60fps genau genug beschrieben, es sei denn, er bewegt sich sehr schnell - mein Gott, dann mach das Ganze halt nochmal für den Ball ^^ |
||
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn ich die Maus verlangsame und die Kollision errechne/schätze, ist es machbar und auch noch ausreichend genau.. aber wie gesagt für mich umständlicher.
Nunja, schade, dass mir keiner helfen kann (und auch keiner eine Antort auf die Frage im Threadtitel weiß).. werde ich wohl in den sauren Apfel beißen müssen, esseidenn es fällt noch jemandem etwas gutes ein. |
||
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Abtastrate der Maus wird vom Maustreiber festgelegt. Es ergibt kein Sinn eine schnellere Abtastrate zu machen, da die meisten Bildschirme eh nicht mehr anzeigen können. Für deine Probleme kannst du allerdings deine Abfrage etwas anders gestalten.
Hier mal ein Beispiel Code: [AUSKLAPPEN] Graphics 640,200,0,2
SetBuffer BackBuffer() While Not KeyHit(1) mxa=mx mx=MouseX() If mx>540 mx=540 If mx>mxa Rect mxa,50,100+(mx-mxa),10,1 Else Rect mx,50,100+(mxa-mx),10,1 End If Rect mx,150,100,10,1 Flip Cls Delay 100 Wend End Der obere Schläger sollte das 'durchbrechen' bei zu schneller Bewegung verhindern. Der untere wurde konventionell erstellt. Um es besser zu visualisieren, habe ich ein Delay von 100 eingelegt. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Dass die Maus Sprünge macht ist nicht ungewöhnlich, da das nichts mit Blitzbasic, sondern einfach mit der Übertragung der Daten zwischen Maus und PC zusammenhängt. Normalerweise kann man im Maustreiber die Abtastrate auch einstellen, wobei diese bei "Pro-Gaming-Mäusen" wesentlich höher ist.
Korrekterweise müsstest Du also tatsächlich alle Pixelwerte zwischen alter und neuer Mausposition interpolieren und jeweils eine Kollisionsprüfung durchführen um eine 100%-Genauigkeit zu erreichen. edit: zu langsam ![]() |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke hectic, das ist wirklich ne nette Idee, die Abfrage so zu gestalten. ^^
@Big Bug: Ah, sehr interessant, thx.. dann bleibt mir wirklich nichts anderes übrig. Durch das Interpolieren erreicht man zwar keine 100% Genauigkeit, aber naja, wenn man nah drankommt, wird es eh kaum auffallen ^_- |
||
![]() |
StepTiger |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich wollte jetzt nochmal dazu kommen:
Es ist nicht die Anzahl an Mausabfragen in Blitz. Window fragt auch nur so viele mal ab, wie es "Schleifendurchläufe" hat. Blitz holt sich die Informationen nur über die API. Mit Linien abfragen ist übrigens dabei wirklich die sinnvollste Möglichkeit. |
||
Noch gestern standen wir am Abgrund, doch heute sind wir schon einen Schritt weiter.
Computer: AMD Sempron 3000+; ATI Radeon 9800 Pro; 512 MB DDR RAM 400Mhz; Asus E7N8X-E Deluxe; Samsung 200GB HD 5.4ns acces t Gewinner: BP Code Compo #2 Π=3.141592653589793238...<--- und das aus dem kopf ![]() Seit der Earthlings-Diskussion überzeugter Fleisch(fr)esser. |
![]() |
Ryo Saeba |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe mal noch etwas weiter nachgeforscht, und habe mal ein paar genauere Daten ausgegraben.
Die meisten herkömmlichen Mäuse werden unter Windows mit 120Hz abgefragt, es gibt allerdings ein paar USB Mäuse, die mehr bieten (500 oder gar 1000Hz). Mit diesem kleinen Programm, könnt ihr btw sehen, mit wieviel Hz eure Maus läuft. Es ist allerdings möglich, die eigene Maus zu übertakten, wobei das mit einer USB Maus einfacher ist, als bei einer PS/2 Maus. Falls es jemanden interessiert, hier gibt es eine Anleitung dazu. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group