Blitz3D schließt sich einfach

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

Meik

Betreff: Blitz3D schließt sich einfach

BeitragDo, Jul 30, 2009 21:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey hey Smile

Bin neu hier also bitte zerfleischt mich nicht wegen meinem Programmiererstil Embarassed

Ich hab versucht, bzw. bin noch dabei es weiter zu basteln, ein kleines Denkspiel zu basteln. Und zwar verschwinden Steine, wenn man vorher auf einem geklickt hat mit der Maus, wenn mehr als 3 der gleichen Sorte sich berühren. Denke jedem ist das Spielprinzip bekannt aus diversen Spielchen Smile.

Nun tut sich bei mir ein merkwüdiges Problem auf. Blitz3D beendet sich einfach wenn ich auf einen Stein klicke Sad. Mir wird auch kein Fehler angezeigt wenn ich den Debug-modus anhabe. (Habe ich standardmäßg an solange ein Projekt noch nicht fertig ist). Hier mal mein Code

Code: [AUSKLAPPEN]
Global SW% = 800, SH% = 640, PW% = 640
Graphics SW%, SH%, 32, 2
SetBuffer( BackBuffer() )
SeedRnd( MilliSecs() )
Global frametimer = CreateTimer( 60 )

Dim Playground( 20, 20 )

Global DEBUG% = True
Global MaxColors% = 5
Global mx% = 0
Global my% = 0

Global NumHits% = 0

Init()
While Not KeyHit( 1 )
   Cls
   
   mx% = MouseX()
   my% = MouseY()
   
   UpdateGame()
   DrawGame()
   
   If( DEBUG% )
      Color 0, 0, 0
      For x% = 0 To 19
         For y% = 0 To 19
            Text( x% * 32 + 16, y% * 32 + 16, Playground( x%, y% ), True, True )
         Next
      Next
      
      Color 255, 255, 255
      Text( PW%, 0, "MouseX: " + mx% )
      Text( PW%, 12, "MouseY: " + my% )
      Text( PW%, 24, "MFX: " + mx% / 32 )
      Text( PW%, 36, "MFY: " + my% / 32)
      Text( PW%, 48, "FieldID: " + Playground( mx% / 32, my% / 32 ) )
      Text( PW%, 60, "NumHits: " + NumHits% )
   EndIf
   
   WaitTimer( frametimer )
   Flip 0
Wend
End

Function Init()
   For x% = 0 To 19
      For y% = 0 To 19
         Playground( x%, y% ) = Rand( MaxColors% ) ;1 bis 5
      Next
   Next
End Function

Function DrawGame()
   For x% = 0 To 19
      For y% = 0 To 19
         Select Playground( x%, y% )
         Case 0
            Color 0, 0, 0
            Rect( x% * 32, y% * 32, 32, 32 )
         Case 1
            Color 200, 0, 0
            Rect( x% * 32, y% * 32, 32, 32 )
            Color 255, 0, 0
            Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
         Case 2
            Color 0, 200, 0
            Rect( x% * 32, y% * 32, 32, 32 )
            Color 0, 255, 0
            Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
         Case 3
            Color 0, 0, 200
            Rect( x% * 32, y% * 32, 32, 32 )
            Color 0, 0, 255
            Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
         Case 4
            Color 200, 200, 0
            Rect( x% * 32, y% * 32, 32, 32 )
            Color 255, 255, 0
            Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
         Case 5
            Color 200, 0, 200
            Rect( x% * 32, y% * 32, 32, 32 )
            Color 255, 0, 255
            Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
         End Select
      Next
   Next
End Function

Function UpdateGame()
   If( MouseHit( 1 ) )
      Local mfx% = mx% / 32
      Local mfy% = my% / 32
      Local id% = Playground( mfx%, mfy% )
      NumHits% = 0
      
      DeleteField( id%, mfx%, mfy% )
   EndIf
End Function

Function DeleteField( fieldid%, x%, y% )
   NumHits% = NumHits% + 1
   Playground( x%, y% ) = 0
   
   If( y% > 0 )
      If( Playground( x%, y% - 1 ) = fieldid% ) Then DeleteField( fieldid%, x%, y% - 1 )
   EndIf
   If( y% < 19 )
      If( Playground( x%, y% + 1 ) = fieldid% ) Then DeleteField( fieldid%, x%, y% + 1 )
   EndIf
   If( x% > 0 )
      If( Playground( x% - 1, y% ) = fieldid% ) Then DeleteField( fieldid%, x% - 1, y% )
   EndIf
   If( x% < 19 )
      If( Playground( x% + 1, y% ) = fieldid% ) Then DeleteField( fieldid%, x% + 1, y% )
   EndIf
   
   ;If( NumHits% >= 3 )
   ;   Playground( x%, y% ) = 0
   ;EndIf
End Function


Wenn ich in der DeleteField(..) Funktion die Zeile
Code: [AUSKLAPPEN]
Playground( x%, y% ) = 0
auskommentiere, also ein ; davor setze stürzt Blitz einfach ab ohne was zu sagen. So wie es jetzt ist wird jedes Feld die id 0 zugewiesen. Egal wieviele Steine sich berühren. Was aber ziemlich blöd das es nur die id 0 bekommen soll wenn mehr als 3 Steinchen der gleichen Sorte sich berühren.

Woran kann das liegen? Hoffe ich hab verständlich erklärt wo mein Problem liegt und ihr mir vielleicht einen Tipp geben könntet wie ich es beheben kann Smile

MFG Meik

Holzchopf

Meisterpacker

BeitragDo, Jul 30, 2009 22:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Also der Code ist, finde ich, sehr sauber! =)

Bei mir geht's, wenn ich auf einen Stein klicke, problemlos. Klicke ich aber irgendwo, wo schon mehrere Steine weg sind, kommt's zu einem Stack Overflow, weil DeleteField sich immer und immer und immer wieder selbst aufruft (*klick* auf Feld a, Feld a löscht das benachbarte Feld b, Feld b löscht das benachbarte Feld a, Feld a löscht das benachbarte Feld b... usw)
Das könntest du schon mal beheben, in dem du in UpdateGame() DeleteField nur dann aufrufst, wenn id% > 0 ist.

Zum anderen - dass sich Steine auch bei kleineren als 3er Päckchen wegklicken lassen - überleg ich mir grad noch was...

MfG
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

Meik

BeitragDo, Jul 30, 2009 22:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Schonmal vielen Dank für die schnelle Antwort Very Happy

Hab noch garnicht probiert gehabt auf ein leeres Feld zu klicken da die leeren Felder ja *eigendlich* mit neues Steinchen gefüllt werden. Hab ich nur noch nicht eingebastelt Laughing Faulheit und Zeitmangel lassen grüßen *g*.

MFG Meik

Noobody

BeitragDo, Jul 30, 2009 22:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Grund, warum es einfach so abstürzt, liegt am Stack Overflow - benachbarte Felder rufen immer gegenseitig die Delete - Funktion auf.

Die Lösung dazu liegt darin, die Feld - ID kurzzeitig auf 0 zu setzen, um eine Endlosrekursion zu vermeiden Code: [AUSKLAPPEN]
Local Temp% = Playground( x%, y% )
Playground( x%, y% ) = 0

If( y% > 0 )
   If( Playground( x%, y% - 1 ) = fieldid% ) Then DeleteField( fieldid%, x%, y% - 1 )
EndIf
If( y% < 19 )
   If( Playground( x%, y% + 1 ) = fieldid% ) Then DeleteField( fieldid%, x%, y% + 1 )
EndIf
If( x% > 0 )
   If( Playground( x% - 1, y% ) = fieldid% ) Then DeleteField( fieldid%, x% - 1, y% )
EndIf
If( x% < 19 )
   If( Playground( x% + 1, y% ) = fieldid% ) Then DeleteField( fieldid%, x% + 1, y% )
EndIf

Playground( x%, y% ) = Temp%


Damit sollte es funktionieren. Einziges Problem mit deiner jetzigen Funktion ist halt, dass je nach dem nicht alle zusammenhängenden Steine verschwinden, da NumHits am Ende der Rekursion zwar korrekt gezählt ist, aber während der Zählung bei einem Funktionsaufruf von DeleteField noch unter 3 ist. Daher müsstest du die Löschung und die Zählung voneinander trennen.

Ansonsten muss ich mich HC anschliessen und den sauberen Codingstil loben Razz
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun

Holzchopf

Meisterpacker

BeitragDo, Jul 30, 2009 22:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Damit das mit dem "lösche erst, wenn drei oder mehr Steine benachbart sind", lässt sich so verwirklichen, dass man die Felder nicht direkt nullt, sondern markiert. Erst danach löscht man die Steine entweder oder hebt die Markierung auf.

Ich hab mir grad mal erlaubt, das so einzubauen Razz

BlitzBasic: [AUSKLAPPEN]
Global SW% = 800, SH% = 640, PW% = 640
Graphics SW%, SH%, 32, 2
SetBuffer( BackBuffer() )
SeedRnd( MilliSecs() )
Global frametimer = CreateTimer( 60 )

Dim Playground( 20, 20 )

Global DEBUG% = False
Global MaxColors% = 5
Global mx% = 0
Global my% = 0

Global NumHits% = 0

Init()
While Not KeyHit( 1 )
Cls

mx% = MouseX()
my% = MouseY()

UpdateGame()
DrawGame()

If( DEBUG% )
Color 0, 0, 0
For x% = 0 To 19
For y% = 0 To 19
Text( x% * 32 + 16, y% * 32 + 16, Playground( x%, y% ), True, True )
Next
Next

Color 255, 255, 255
Text( PW%, 0, "MouseX: " + mx% )
Text( PW%, 12, "MouseY: " + my% )
Text( PW%, 24, "MFX: " + mx% / 32 )
Text( PW%, 36, "MFY: " + my% / 32)
Text( PW%, 48, "FieldID: " + Playground( mx% / 32, my% / 32 ) )
Text( PW%, 60, "NumHits: " + NumHits% )
EndIf

WaitTimer( frametimer )
Flip 0
Wend
End

Function Init()
Local x%, y%
For x% = 0 To 19
For y% = 0 To 19
; Spielfeld mit zufälligen Werten von 1 bis MaxColors% füllen
Playground( x%, y% ) = Rand( MaxColors% )
Next
Next
End Function

Function DrawGame()
Local x%, y%
For x% = 0 To 19
For y% = 0 To 19
Select Playground( x%, y% )
Case 0
Color 0, 0, 0
Rect( x% * 32, y% * 32, 32, 32 )
Case 1
Color 200, 0, 0
Rect( x% * 32, y% * 32, 32, 32 )
Color 255, 0, 0
Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
Case 2
Color 0, 200, 0
Rect( x% * 32, y% * 32, 32, 32 )
Color 0, 255, 0
Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
Case 3
Color 0, 0, 200
Rect( x% * 32, y% * 32, 32, 32 )
Color 0, 0, 255
Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
Case 4
Color 200, 200, 0
Rect( x% * 32, y% * 32, 32, 32 )
Color 255, 255, 0
Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
Case 5
Color 200, 0, 200
Rect( x% * 32, y% * 32, 32, 32 )
Color 255, 0, 255
Rect( x% * 32 + 2, y% * 32 + 2, 32 - 4, 32 - 4 )
End Select
Next
Next
End Function

Function UpdateGame()
If( MouseHit( 1 ) )
Local mfx% = mx% / 32
Local mfy% = my% / 32
Local id% = Playground( mfx%, mfy% )
NumHits% = 0

; Wenn ein Stein vorhanden ist, zum Löschen markieren
If id% > 0 Then DeleteField( id%, mfx%, mfy% )
; Markierte Steine löschen oder Markierung aufheben
CleanUpPlayGround()
EndIf
End Function

Function DeleteField( fieldid%, x%, y% )
; Stein zählen
NumHits% = NumHits% + 1
; Stein markieren
Playground( x%, y% ) = -Playground( x%, y% )

If( y% > 0 )
If( Playground( x%, y% - 1 ) = fieldid% ) Then DeleteField( fieldid%, x%, y% - 1 )
EndIf
If( y% < 19 )
If( Playground( x%, y% + 1 ) = fieldid% ) Then DeleteField( fieldid%, x%, y% + 1 )
EndIf
If( x% > 0 )
If( Playground( x% - 1, y% ) = fieldid% ) Then DeleteField( fieldid%, x% - 1, y% )
EndIf
If( x% < 19 )
If( Playground( x% + 1, y% ) = fieldid% ) Then DeleteField( fieldid%, x% + 1, y% )
EndIf
End Function

; Spielfeld aufräumen.
; Löscht Steine, wenn drei oder mehr markiert werden,
; sonst wird die Markierung aufgehoben.
Function CleanUpPlayGround()
Local x, y
For x = 0 To 19
For y = 0 To 19
; Markierter Stein
If Playground(x, y) < 0
; 3 oder mehr Steine -> Löschen
If NumHits => 3
Playground(x, y) = 0
; sonst zurücksetzen
Else
Playground(x, y) = -Playground(x, y)
EndIf
EndIf
Next
Next
End Function


MfG
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

Meik

BeitragDo, Jul 30, 2009 22:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Ah genau jetzt hab ich es verstanden Very Happy

Blitz hat sich einfach geschlossen weil es sich sonst abgeschossen hätte.
*rechts ruft links auf und links wieder rechts [...]*

Und danke für die ?Löbe? (mehrzahl von Lob ^^) für meinen Stil Smile

Vielen dank Very Happy

EDIT:
Man, nochmal ein großes Danke an dich Holzchopf Very Happy. Mit dem Code könnt ihr machen was ihr wollt da braucht man mich nicht um erlaubnis fragen ^^.

Ich hab eh nur so begrenzt Zeit das ich mir nicht erlauben kann ein großes Projekt zu basteln leider. Daher bastel pro Tag nur ein Klitzekleines In-Weniger-Als-10-Stunden-entstanden Spiel. Da ist mir der Code, und was damit passiert, egal Smile

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group