Timer innerhalb for-Schleife
Übersicht

Eyes_OnlyBetreff: Timer innerhalb for-Schleife |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo Community,
ich habe eine Frage. Ich habe eine for-Schleife, in der durchgehend 10 Spielobjekte auf Veränderungen überprüft werden. Wenn eines der Objekte angeklickt wird, soll 1 Sekunde gewartet werden und anschließend das Objekt zur Spielfeldmitte fliegen. Die Zeitabfrage mache ich mit Millisecs(), indem ich nach dem Mausklick eine Variable auf Millisecs() setze und dann später frage, ob Millisecs()-1000 > Zeitvariable ist. Mein Problem ist nun, dass wenn ich den Timer einbaue, die Bewegung des angeklickten Objekts sich nach dem Timer richtet, das heißt, das Objekt sich nur alle 1 Sekunde richtung Mitte bewegt, nicht aber eine Sekunde wartet, und dann erst fliegt. Hat jmd. eine Idee, wie ich den Timer einbauen kann, sodass er unabhängig von der Schleife läuft? Ich hoffe das ist jetzt nicht zu abstrakt... ![]() Danke! Pseudocode: Code: [AUSKLAPPEN] Repeat
... ;durchlaufe alle 10 Objekte und überprüfe Änderungen For I=0 To 9 ;wenn Zustand normal, dann zeichne Bild1 ... ;Wenn Objekt angeklickt und sichtbar, dann zeiche Bild2, warte 1 Sekunde und lass das Objekt zur Mitte fliegen If Objekt angeklickt And Objekt sichtbar Then DrawImage bild2... ;Timer abgelaufen, Flugbahnberechnung und Objekte zur Mitte fliegen If --- hier muss irgendwie der Timer rein --- ... Then ... EndIf EndIf Next ;Rechtsklickroutine; ... ;Zeichenroutine; ... ;Maus ... Flip Until KeyHit(1) |
||
![]() |
Addi |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du erstellst eine neue Variable (z.B. moveObj), setzt diese nach ablauf der Sekunde auf True
und überprüfst außerhalb deiner Timer-Routine, ob sie auf True ist. Wenn ja, dann bewegst du. ![]() |
||
BP/B3D/BMax : Lerne Java : Früher mal Lite-C : Gewinner BCC 62 |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Addi hat recht.
Im zuge dessen solltest du dir - grade bei BlitzBasic - eine kleine updateroutine schreiben. Diese update routine kann deine maus interaktionen übernehmen (Beispiel funktion Update() -> ruft CheckMouse() etc auf)), sofern dies noch möglich ist. Glaub mir, ist einfacher da hinterher durchzusteigen ![]() Ungeachtet des stils, hier meine version, wie ich es lösen würde: - 2 Globale oder locale variablen. Eine für das objekt, eine als int für Millisecs(). Nennen wir sie moveObj und moveTime - In der prüfung wird, falls eine änderung stattgefunden hat, gefragt, ob moveObj = null ist (im moment ist nichts am "in die mitte fliegen"). Wenn ja: moveObj = objekt_der_begierde und moveTime = millisecs()+1000 - zwischen "next" und ";Rechtsklickroutine; " kommt dann eine abfrage: Wenn moveObj <> null (bzw <> 0) AND moveTime < Millisecs() DANN *bewegen, löschen, kitzeln* - was auch immer du machen möchtest ![]() - Vorgang abgeschlossen, ist in die mitte geflogen, wollen wir es nichtmehr bewegen oder haben wir bock auf ne änderung? alles klar ! moveObj = 0 bzw moveObj = null (tut mir leid, das ich null schreibe.. keine ahnung, ob das in blitzbasic existiert!) |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Da du Informationen pro Objekt speichern und verarbeiten willst, wäre ein Type![]() Objekte erstellen, jeden Schleifendurchlauf die aktuelle Zeit vergleichen und entsprechende Zustände setzen, die das Objekt steuern. BlitzBasic: [AUSKLAPPEN] Select obj\Zustand |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
also hier mal eine Lösung mit nur 1 Variaben:
BlitzBasic: [AUSKLAPPEN] Graphics 800,600 |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Auch wenn es Korinthenkackerei ist, aber dieser Code ist zumindest minimal buggy. Wenn der Timer intern umschlägt und zufällig genau eine Sekunde vorher geklickt wird wird das Objet nie bewegt, da der Timer da schon auf 0 gesetzt wird. Da ist eine Lösung mit zwei Variablen sauberer.
Ich weiss dass die Wahrscheinlichkeit das der Bug auftritt gegen null tendiert, aber solche Kleinigkeiten können großen Projekten das Genick brechen. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Eyes_Only |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also irgendwie bekomme ich es nicht so richtig unter, habe schon ne Menge durchprobiert.
Ich vermute, dass mir die for-Schleife das Leben schwer macht. Ich muss wahrscheinlich doch auf Types umsteigen, so wie Xeres gesagt hat. Ich hänge mal das bisherige Programm dran, dann könnt ihr euch vielleicht besser vorstellen, worum es mir geht. [EDIT: Link siehe unten] Es soll später ein Wimmelbild werden. Jetzt für das Grundgerüst habe ich alle abstrahiert. Die Grafiken werden später entsprechend ersetzt. Nach dem eine Fliege angeklickt ist, soll eine Sekunde vergehen und sie erst dann zur Mitte fliegen... |
||
- Zuletzt bearbeitet von Eyes_Only am Fr, Jan 18, 2013 23:36, insgesamt 2-mal bearbeitet
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Benutze doch bitte unser eigenes Archiv - Gratis-upload Seiten mit Werbung, lahmer Verbindung und Trojanern mag doch keiner. | ||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
Eyes_Only |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ah ok, mein Fehler, hier der neue Link:
https://www.blitzforum.de/upload/file.php?id=12196 Danke Xeres. |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
also es sind nur 3 Änderungen an deinem Code nötig und es ist genauso wie in meinem Bispiel beschrieben:
1. Den Timer gleich bei Mausklick auf die Zukunft setzen: BlitzBasic: [AUSKLAPPEN] ..... 2. Das alte Bild zeichnen solange Timer=0 oder größer als "JETZT" ist BlitzBasic: [AUSKLAPPEN] .... 3. Das fliegende Bild zeichen wenn timer nicht 0, aber kleiner als "JETZT" BlitzBasic: [AUSKLAPPEN] .... Der Vorschlag von Xeres wäre gold wert. Damit wird die Lesbarkeit deutlich erhöht. Du müsstest noch nicht einmal auf deine Array verzichten, sondern kannst TYPES und ARRAYS kombinieren: siehe mein Tutorial Types in Array https://www.blitzforum.de/foru...245#356245 Das Beispiel dort mit den Karten passt genau zu deinem Problem: BlitzBasic: [AUSKLAPPEN] Type ObjektTyp Du würdest die 2.Dimension los und statt der zweiten Ziffer stünde da immer eine sinnvolle Bezeichnung Ausblick: Wenn Du das oben noch verstanden hast, ist es nur noch ein kleiner Schritt auf Array völlig zu verzichten. Es ist nämlich so, dass in BB selbst erstellte Objekt automatisch in eine Objektliste wandern, die man bequem bei Aktionen nutzen kann, wo man alle Objekte ansprechen möchte. Ich bleibe beim obigen Beispiel: BlitzBasic: [AUSKLAPPEN] Type ObjektTyp Tatsächlich kannst du jetzt alle 10 Fliegen unter dem gleichen Namen obj ansprechen. |
||
Eyes_Only |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wow!!!
Vielen vielen Dank für die ganzen tollen Antworten, insbesondere an Midimaster. ![]() Ich habe immer Probleme mir das mit den Timern bzw. mit Millisecs() richtig vorzustellen. Das braucht wohl einfach ein bisschen mehr Übung... Types sind für mich absolutes Neuland, aber ich habe mir schon die Type-Tutorials hier im Forum angeschaut und versuche daraus zu lernen. Ich werde mein Spiel erstmal ohne Types versuchen fertig zu stellen um den Spielablauf und alles zu erlernen und möchte dann später versuchen, das Spiel mit Types umzuschreiben. Danke für die Hilfestellung mit den Types, eure Ausführungen werden mir sicher sehr helfen. ![]() |
||
![]() |
PSY |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Midimaster
In Deinem verlinkten Typetutorial sind noch n paar Fehler (zumindest in Lektion VI, da hab ich grad reingeschaut): Bei Schachbrett Code: [AUSKLAPPEN] Feld(i) = New FeldTyp ist nur 1-dimensional, muss aber laut Deiner Deklaration 2-dimensional sein
Bei Monopoly 1. Code: [AUSKLAPPEN] Dim Strasse.StrassenTyp(40) 'n' zuviel
2. Code: [AUSKLAPPEN] For i=1 To 40
Strasse(i).Name = "Schloßallee" Strasse(i).KaufPreis = 40000 Strasse(i).InGruppe = SUPER_TEUER Next funzt so nicht, die '.' muessen durch nen '\' ersetzt werden. Neulinge koennten sich da die Zaehne dran ausbeissen bei der Fehlersuche, besser erst immer die Codes testen ![]() PSY |
||
PSY LABS Games
Coders don't die, they just gosub without return |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@PSY
lieben Dank, dass Du dir die Mühe gemacht hast, die Fehler zu melden. Du hast Recht: Anfänger Tutorials müssen fehlerfrei sein. Daher bin ich jetzt sehr froh, dass Du sie gefunden hast. Ich habe es gleich in Ordnung gebracht. an alle: Wenn ihr weitere Fehler findet, gibt es extra schon einen Kritik-Thread zu meinen Tutorials. Da sind Fehlemeldungen und Vorschläge sehr gern gesehen: https://www.blitzforum.de/foru...hp?t=33457 |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
PSY |
![]() Antworten mit Zitat ![]() |
---|---|---|
@Midimaster
Kein Ding. Wenn ich ein wenig Zeit hab, schau ich mir den Rest mal an. Und ups, stimmt, an den Kritik-Thread kann ich mich erinnern, is lange her. Hab ewig nix gemacht und erst wieder angefangen ![]() @EYES_ONLY Um Dir zu zeigen, wie einfach das Ganze mit Types aussehen kann (ohne Menue + Scrollen): Code: [AUSKLAPPEN] AppTitle "WW"
SeedRnd MilliSecs() ; zufallsgenerator fuettern Const SCREENWIDTH = 1024 Const SCREENHEIGHT = 768 Graphics SCREENWIDTH,SCREENHEIGHT,32,2 SetBuffer BackBuffer() ; Bilder, Sound laden Local lev01% = LoadImage("Lev01.jpg") Local bild1% = LoadImage("alien.bmp") : MidHandle bild1 Local bild2% = LoadImage("alien2.bmp") : MidHandle bild2 Local sound% = LoadSound("soundfx20.wav") Local mx%, my%, mh%, i%, score%=0, deltaX%, deltaY%, counter% Type TObj Field x#, y# Field time% Field state% End Type Global obj.TObj For i=0 To 9 obj.TObj = New TObj obj\x = 95*(i+1) ; X-Pos obj\y = Rnd(745) ; Y-Pos obj\time = 0 ; warp-timer obj\state = 0 ; zustand (0 = nicht gefunden 1 = gefunden/fliegt zum mittelpunkt 2 = warped aus screen) Next Repeat mx = MouseX() my = MouseY() mh = MouseHit(1) DrawBlock lev01, 0, 0 ; background zeichnen counter = 0 ; alle types durchgehn For obj.TObj = Each TObj counter = counter + 1 ; types zaehlen If obj\state = 0 Then DrawImage bild1, obj\x, obj\y Else DrawImage bild2, obj\x, obj\y ; je nach zustand bild1 oder bild2 If Abs(obj\x - mx) + Abs(obj\y - my) < 25 And mh And obj\state = 0 ; object gerade geklickt? obj\state = 1 PlaySound sound score = score + 10 EndIf If obj\state = 1 ; object fliegt zum mittelpunkt deltaX = obj\x - SCREENWIDTH/2.0 deltaY = obj\y - SCREENHEIGHT/2.0 obj\x = obj\x - deltaX * 0.03 obj\y = obj\y - deltaY * 0.03 If Abs(deltaX)<1 And Abs(deltaY)<1 Then obj\state = 2 : obj\time = MilliSecs() EndIf If obj\state = 2 ; aus bildschirm warpen? If MilliSecs() - obj\time > 500 Then obj\y = obj\y - 4 If obj\y < -20 Then Delete obj.TObj ; wenn object aus bildschirm geflogen, loesch es EndIf Next If counter=0 Then RuntimeError "LEVEL SOLVED!" ; keine types mehr? dann level geschafft ^^ Text 0,0,score Flip Until KeyHit(1) End Konstruktive Kritik an Deinem Code: 1. Unsaubere bzw. ueberhaupt keine Variablendeklarationen. Wenn Du IDEal benutzt, schalte STRICT ein (unter Compile). Wenn Du IDEal nicht benutzt, mach es ![]() 2. CLS brauchste nicht, wenn Du sowieso mit DRAWBLOCK bildschirmfuellend zeichnest 3. Zufallsgenerator vergessen zu initialisieren 4. Wenn Du nen eigenen Mauszeiger benutzt, versteck den internen mit Hidepointer 5. Die Font wird nur 1x geladen, und vor allem AUSSERHALB der Hauptschleife ![]() l8er, PSY |
||
PSY LABS Games
Coders don't die, they just gosub without return |
Eyes_Only |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Oh Mann, wie geil ist das denn... ![]() Types sind ja echt ne tolle Sache... Der ganze Code ist viel aufgeräumter und übersichtlicher - und kürzer! Vielen Dank PSY und Midimaster und Xeres für die Hilfe mit den Types, da kann ich eine Menge draus lernen. Und danke für die Anmerkungen zu meinem Code, ich werde die Fehler gleich ausmerzen. ![]() @PSY: Ja, ich benutze IDEal. War gleich mit das erste was ich mir zugelegt habe. Strict hatte ich von vornherein an. Aber diese rote Farbe war eigentlich ganz schön, um seine Variablen wiederzufinden. ![]() Eine Sache verstehe ich noch nicht ganz: BlitzBasic: [AUSKLAPPEN] If Abs(obj\x - mx) + Abs(obj\y - my) < 25 And mh And obj\state = 0 ; object gerade geklickt? Hier machst du ja die Kollisionsabfrage Bild-Maus. Wie funktioniert das mit den Absoluten Zahlen und wo kommt die Zahl 25 her? |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Abs - Absolut - sagt simpel aus, das das vorzeichen entfernt wird.
-25 wird zu 25 25 wird zu 25 -1337 wird zu 1337 ![]() In der abfrage werden 2 differenzen errechnet. von Obj X zu MX und von Obj Y zu MY. Hier wird gerne Abs verwendet, um die reihenfolge der zahlen zu missachten. Egal ob ObjX oder MX größer ist, das ergebnis ist positiv und gibt die "absolute" differenz zwischen beiden an. In kombination mit der abfrage "<25" ergibt das eine ziemlich simple distanz bestimmung. Um genau zu sein wird da die "Manhatten distanz" genutzt. Eine grobe schätzung ohne viel aufwand. Die 25 ist hier ein beliebiger wert, der zb einem Radius entsprechen kann. In diesem fall nehme ich an, des es Bild2 - breite / 2 entspricht (wahlweise auch höhe, je nachdem, welches der kleinere wert ist) |
||
![]() |
PSY |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi Eyes_Only,
kein Ding ![]() Die Farben in der IDEal kannste auch so einstellen, wie Du sie haben willst. Ansonsten zu der Distanz: Genau wie PhilipK schon geschrieben hat. Die 25 hab ich grob geschaetzt (~Radius Bild). Alternativ kannste natuerlich auch den Pythagoras nehmen (wenn die Bilder rund bzw. ungefaehr quadratisch sind, so wie bei Deinen hier): a^2 + b^2 = c^2 (Abstand BildX - MausX) ^2 + (Abstand BildY - MausY) ^2 sollte <= (Radius Bild)^2 sein Code: [AUSKLAPPEN] If (obj\x - mx)^2 + (obj\y - my)^2 < 625 And mh And obj\state = 0
PSY |
||
PSY LABS Games
Coders don't die, they just gosub without return |
Eyes_Only |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Cool, diese Art der "Kollisionserkennung" kannte ich noch nicht. ![]() Aber die macht doch so richtig eigentlich nur Sinn, wenn die Spielobjekte rund oder quadratisch sind, oder? Bei ungleichmäßig großen Objekten, die vielleicht noch irgendwelche "Auswüchse" haben, bietet sich das doch eher nicht an. Hab ich das richtig verstanden? |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
So in etwa, ja ![]() Das ist in dem sinne keine kollisionserkennung sondern simples vergleichen von abständen. Das ganze kann man grob unterteilen: - Quadrate, oder nur grobe schätzung: Abs method (Manhatten distanz bzw Metrik genannt) - Kreise: Pythagoras - Alle arten Rechtecke, ohne drehung: "Punkt in rechteck" prüfung: "Wenn testX >= zielX und testX <= zielX + ZielBreite und testY >= zielY und testY <= zielY + ZielHöhe Dann" Mit diesen drei simplen abfrage kann man so ziemlich alles testen, was man will. Ausser man extrem genaue erwartungen, zb bei einem Shooter ![]() Und wenn du irgendwelche abstrakten figuren hast, kannst du immernoch Flächeninhalte vergleichen. Aber das bedarf ein wenig Geometrie, das kriege ich mit meinem fieber grade nicht hin ,sorry ![]() |
||
Eyes_Only |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das musst du auch nicht. ![]() Vielen Dank für deine guten Ausführungen, das muss ich mir mal in Ruhe zu Gemüte führen und dann anwenden. Und wenn ich mal eine Frage zu den Flächeninhalten habe weiß ich ja, an wen ich mich wenden kann. ![]() Gute Besserung! |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group