Seite 1 von 1
Aufbau so in Ordnung?
Verfasst: 08.04.2008 10:24
von gnasen
Ich arbeite seit längerem an einem Projekt und habe mir diesmal von vornherein viel Mühe beim Aufbau gegeben. Allerdings hat sich mir ein kleins Problem gestellt, zu dem ich eine Frage hätte. Da der Quellcode vieeel zu lang ist, hier mal die Hauptschleife:
Code: Alles auswählen
Repeat
While WindowEvent() : Wend
Delay(1)
DoCurrentActions()
DoCheckNetwork()
DoCheckInput()
DoSpecialInput()
DoCoorBerechnen()
DoRenderCurrentScreen()
Until quitscreen = 1
Nun habe ich das Problem, dass es Situationen gibt, in denen ich diese Struktur verlassen muss. In diesem Fall baue ich
die selbe Schleife zB an einer bestimmten Stelle in DoCurrentActions() ein, nur ebend mit einer anderen Abbruchbedingung.
Es funktioniert einwandfrei, aber ist das ganze in Ordnung? Darf man das so in Hinsicht auf die Eventverarbeitung machen? Könnte man es mit einem Makro eleganter lösen?
Noch eine kleine Bonusfrage
Ich durchsuche meine LinkedLists zurzeit immer so:
Code: Alles auswählen
Structure infos
info1.l
info2.l
info3.l
EndStructure
NewList Search.infos()
ForEach Search()
If Search()\info1 = gesuchteInfo1
If Search()\info2 = gesuchteInfo2
If Search()\info3 = gesuchteInfo3
;mach was
Break
EndIf
EndIf
EndIf
Next
kann man diese Foreach-Schleife schneller gestalten ?
vielen Dank schon mal
Verfasst: 08.04.2008 12:45
von ZeHa
Nun habe ich das Problem, dass es Situationen gibt, in denen ich diese Struktur verlassen muss.
Schilder doch mal eine solche Situation, dann kann man sicher mehr sagen.
Noch was, handelt es sich bei Deinem Projekt um ein Spiel (bzw. was vergleichbares)?
Verfasst: 08.04.2008 13:13
von gnasen
Ja es handelt sich um ein Spiel.
Wenn jetzt bestimmte Events verarbeitet werden, werden verschiedenste Prozeduren aufgerufen, welche sehr verschachtelt in einander sind.
Jetzt kann es passieren, dass ich in einer dieser Prozeduren bestimmte Dinge ausführen muss, die mehrere Frames brauchen (Objekte bewegen etc.) Die Prozedur darf allerdings in dieser Zeit nicht verlassen werden, da sonst der gesamte Aufbau in sich zusammenbrechen würde.
In DoCurrentActions() ist zB soetwas, wäre aber viel zu kompliziert das jetzt alles irgendwie zu beschreiben.
Sagen wir die Proc a() ruft b() auf, welche c() aufruft, in jeder passiert etwas, aber das geschehen in b() sorgt dafür, dass etwas passiert, was durch die normale Schleife getan werden muss (zB eine bestimmte Bewegung). Es muss aber anschließend der Rest von b() und auch c() aufgerufen werden.
Ich hoffe das ist halbwegs verständlich
Verfasst: 08.04.2008 13:42
von #NULL
kann man auch mit flags machen:
du läufst deine hauptschleife prinzipiell immer durch, aber machst nur sachen die zum aktuelle 'status' passen und läßt anderer aus. den staus kannst du dann im programm-fluss verändern.
hier ein beispiel:
Code: Alles auswählen
OpenWindow(0,0,0,0,0,"")
#state_render = %001
#state_rechne = %010
#state_nurkurz = %100
Global state.l = #state_render | #state_rechne
Repeat
;mach immer
event = WindowEvent()
If (state & #state_nurkurz)
Debug "nur kurz"
kurz-1
If kurz=0
state = #state_render | #state_rechne
EndIf
EndIf
If (state & #state_rechne)
Debug "rechne"
;rechne()
If Random(5)=0 ; irgendwas passiert
state = #state_nurkurz ; mach das 'nur kurz' flag an
kurz = 4 ; für 4 frames
EndIf
EndIf
If (state & #state_render)
Debug "render"
;display()
;flip()
EndIf
Debug ""
Delay(500)
Until quit
falls dir das zu kryptisch aussieht. das geht auch einfacher, mit simplen werten statt flags und bitwise operatoren.
Verfasst: 08.04.2008 13:44
von Kaeru Gaman
umfangreiche berechnungen kannst du auch splitten...
mal angenommen, du willst auf einer sehr großen tilemap alle minute die bäume um eine stufe wachsen lassen.
anstatt jetzt die gesamte map auf einmal durchzurechnen, und für zig frames einzufrieren,
kannst du, wenn der vorgang aktuell ist, in jedem frame eine zeile der map durcharbeiten,
dann bekommst du keine lags.
Verfasst: 08.04.2008 13:50
von ZeHa
Naja es ist schade daß man mit PB nicht so toll OOP programmieren kann, denn da läßt sich das sehr einfach und übersichtlich lösen. Aber ist auch prozedural möglich.
Und zwar habe ich quasi mehrere "Abschnitte", z.B. Menü, Spiel, Highscoreliste, Intro, Outro, wasweißich, und ein Abschnitt ist immer aktiv. Die Hauptschleife sendet alle Events immer an diesen einen aktiven Abschnitt. Ihr ist also egal, wer grad dran ist, und der Abschnitt muß sich halt drum kümmern, die Events ordnungsgemäß zu verarbeiten.
Jeder dieser Abschnitte hat auch eine update()- und eine render()-Funktion, und diese werden ebenfalls von der Hauptschleife aufgerufen. Ist OOPmäßig sehr simpel, ansonsten muß man halt erstmal eine allgemeine update()- und render()-Funktion aufrufen, die ihrerseits dann einfach kurz überprüft, welcher Abschnitt gerade aktiv ist, und ruft dann dessen update()- bzw. render()-Funktion auf.
Somit gibt es kein Verschachtelungsproblem, und es ist auch jederzeit möglich, das Programm wieder "sauber" zu verlassen, da alles von einer einzigen Hauptschleife ausgeht.
Ich hoffe das war einigermaßen verständlich

wenn nicht müßte ich das evtl. nochmal anders formulieren... wenn Du OOP verstehst wirst Du es aber leichter haben mit dem Verständnis

Verfasst: 08.04.2008 14:34
von gnasen
Das mit den Flags ist mir klar, benutze ich sogar teilweise in der "echten" Hauptschleife (oben ist ja nur gekürzt). Gegen Missverständnisse: Das ist ein WindowedScreen, deswegen "While WindowEvent() : Wend" da ich die Fenster Events noch nicht auswerte, bzw. brauche.
Leider wurde das Problem noch nicht ganz verstanden, aber dazu später nochmal, ich versuche mich nochmal an einer besseren Erklärung.
Kann denn wer was zur zweiten Frage sagen? Weil von den Aufrufen habe ich ziemlich viele und da wäre mir eine möglichst schnelle Variante wichtig (falls es etwas schnelleres gibt). Wichtig dabei: Es gibt immer nur ein Element in der Liste, welches passt, deswegen auch der Break Befehl !!!
Verfasst: 08.04.2008 14:45
von Kaeru Gaman
also du hast drei suchkriterien, die alle stimmen müssen...
so wie ich das sehe ist das die effizienteste methode für ne Liste.
wenn das erste stimmt, das zweite prüfen, wenn das zweite auch stimmt das dritte prüfen, und wenn das auch stimmt hast dus....
du wechselst ja nicht mal das element, also gehst du die liste eh so schnell wie möglich mit meistens nur einer prüfung durch.
du bekommst es ein wenig optimiert, wenn du zuerst auf das kriterium prüfst,
bei dem es am wenigsten treffer geben kann.
dann werden die anderen prüfungen so selten wie möglich durchgeführt.
das ließe sich nur verbessern, indem du die organisation dieser objekte komplett änderst,
also zum beispiel in "regionen" aufteilst, dass du immer nur teillisten durchsuchen musst,
oder nach einem der kriterien vorsortieren, damit du indiziert suchen kannst.
Verfasst: 08.04.2008 14:54
von ZeHa
Das mit den Regionen wäre auch mein Vorschlag gewesen, Stichwort: Binärbaum statt Liste.