Funktion macht nicht das was sie machen sollte

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Brotenkopf

Betreff: Funktion macht nicht das was sie machen sollte

BeitragDi, Mai 01, 2012 23:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Leute,

Ich habe versucht einen Code zu schreiben mit welchem man eine Tür nach vorne öffnen und schließen und nach hinten öffnen und schließen kann. Es klappt auch alles echt gut aber wenn ich versuche den Teil in der Main Schleife in eine Funktion zB Update_Door(Pivot) zu packen passiert nicht das selbe wie vorher. Was muss ich verändern damit alles korrekt läuft?
Hier der Code

Code: [AUSKLAPPEN]

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

c=CreateCamera()

pivot=CreatePivot()
door=CreateCube()
ScaleEntity door,1,2,.1
PositionEntity door,0,0,4
PositionEntity pivot,EntityX(door)+(GetMeshWidth#(door)/2),EntityY(door),EntityZ(door)
EntityParent door,pivot

While Not KeyHit(1)

If MouseHit(1) And i=0 And i2=0 And open_behind=0
   i=1
   yaw=EntityYaw(pivot)
End If

If MouseHit(2) And i2=0 And i=0 And open_front=0
   i2=1
   yaw=EntityYaw(pivot)
End If

If i=1
   If Int yaw<-88 And Int yaw>-92
      If Int EntityYaw(pivot)<-1
         TurnEntity pivot,0,1,0
      Else
         i=0
         open_front=0
      EndIf
   EndIf
EndIf

If i=1 ;öffne frontal
   If Int yaw>-2 And Int yaw<2
      If Int EntityYaw(pivot)>-90
         TurnEntity pivot,0,-1,0
      Else
         i=0
         open_front=1
      End If
   EndIf 
EndIf

If i2=1 ;schließe hinten
   If Int yaw>88 And Int yaw<92
      If Int EntityYaw(pivot)>0
         TurnEntity pivot,0,-1,0
      Else
         i2=0
         open_behind=0
      End If
   EndIf
End If

If i2=1 ;öffne hinten
   If Int yaw>-2 And Int yaw<2
      If Int EntityYaw(pivot)<90
         TurnEntity pivot,0,1,0
      Else
         i2=0
         open_behind=1
      End If
   EndIf
End If


UpdateWorld()
RenderWorld()
Text 0,0,"Maustaste 1 nach vorne öffnen"
Text 0,15,"Maustaste 2 nach hinten öffnen"
Flip
Wend


die Funktion GetMeshWidth#() habe ich von hier https://www.blitzforum.de/foru...ite+h%F6he

Den Pivot habe ich erstellt um eine Art "Gelenkpunkt" für die Tür zu erstellen.
mfG Brotenkopf

Xeres

Moderator

BeitragDi, Mai 01, 2012 23:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Wozu GetMeshWidth wenn du das kennst...?
Code: [AUSKLAPPEN]
ScaleEntity door,1,2,.1
PositionEntity pivot,EntityX(door)+1,EntityY(door),EntityZ(door)


Aber zum Problem: Du benutzt jede menge Variablen - die sind lokal und werden in einer Funktion nicht gespeichert.

Benutzte einen Type um alle Daten zur Tür zu speichern & verarbeiten.
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Brotenkopf

BeitragDi, Mai 01, 2012 23:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Also den Befehl finde ich praktisch falls ich später verschiedene Models mit unterschiedlichen Größen verwende.

Ok, aber woher weiß ich denn welche Variablen Lokal gespeichert bleiben können?
Ich werde erstmal versuchen einen Type dafür zu erstellen.
dankeschön erstmal

Xeres

Moderator

BeitragDi, Mai 01, 2012 23:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Alles, was du später nicht wieder mit exakt diesem Wert brauchst, bleibt eine Lokale Variable. Bessere Bezeichnungen als i und i2 wären dafür auch sehr zu empfehlen Wink
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Brotenkopf

BeitragMi, Mai 02, 2012 10:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ich die Variablen die ich benutze vorher als Global setze dann funktioniert alles. Ich glaube aber,dass ich dann die Funktion nur für eine Tür verwenden kann.
Wenn ich einen Type erstelle mit Mesh,Pivot und Variablen dann passiert genau das selbe wie vorher. Anstatt die Tür komplett zu öffnen "zuckt" sie nur kurz und das wars.

Code: [AUSKLAPPEN]
Type Door
   Field Mesh
   Field Pivot
   Field Yaw%
   Field Yaw2%
   Field opening_front%
   Field opening_behind%
   Field open_front%
   Field open_behind%
End Type


Graphics3D 800,600,32,2
SetBuffer BackBuffer()

c=CreateCamera()




Door1.Door=New Door
Door1\Pivot=CreatePivot()
Door1\Mesh=CreateCube()

ScaleEntity Door1\Mesh,1,2,.1
PositionEntity Door1\Mesh,0,0,4
PositionEntity Door1\Pivot,EntityX(Door1\Mesh)+(GetMeshWidth#(Door1\Mesh)/2),EntityY(Door1\Mesh),EntityZ(Door1\Mesh)
EntityParent Door1\Mesh,Door1\Pivot
a=CreateCube()
PositionEntity a,EntityX(Door1\pivot),EntityY(Door1\pivot),EntityZ(Door1\pivot)
ScaleEntity a,.1,.1,.1
EntityColor a,255,0,0

While Not KeyHit(1)
UpdateDoor(Door1\Pivot,Door1\Yaw,Door1\Opening_front,Door1\opening_behind,Door1\open_front,Door1\open_behind)

UpdateWorld()
RenderWorld()
Flip
Wend

Function UpdateDoor(Pivot,Yaw,Opening_front,opening_behind,open_front,open_behind)

If MouseHit(1) And Opening_front=0 And opening_behind=0 And open_behind=0
   Opening_front=1
   yaw=EntityYaw(pivot)
End If

If MouseHit(2) And Opening_front=0 And opening_behind=0 And open_front=0
   opening_behind=1
   yaw=EntityYaw(pivot)
End If

If Opening_front=1
   If Int yaw<-88 And Int yaw>-92
      If Int EntityYaw(pivot)=<-1
         TurnEntity pivot,0,1,0
      Else
         Opening_front=0
         open_front=0
      EndIf
   EndIf
EndIf

If Opening_front=1 ;öffne frontal
   If Int yaw>-2 And Int yaw<2
      If Int EntityYaw(pivot)>-90
         TurnEntity pivot,0,-1,0
      Else
         Opening_front=0
         open_front=1
      End If
   EndIf
EndIf

If opening_behind=1 ;schließe hinten
   If Int yaw>88 And Int yaw<92
      If Int EntityYaw(pivot)>0
         TurnEntity pivot,0,-1,0
      Else
         opening_behind=0
         open_behind=0
      End If
   EndIf
End If

If opening_behind=1 ;öffne hinten
   If Int yaw>-2 And Int yaw<2
      If Int EntityYaw(pivot)<90
         TurnEntity pivot,0,1,0
      Else
         opening_behind=0
         open_behind=1
      End If
   EndIf
End If
Return yaw
End Function


irgendwie bin ich grade überfragt^^

BladeRunner

Moderator

BeitragMi, Mai 02, 2012 10:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Du fragst Mousehit in der Funktion ab- das liefert exakt einmal True, dann wird der Hitcounter auf Null zurückgesetzt.
Der korrekte Weg wäre es die Funktion nur dann aufzurufen wenn mit Mousehit eine Startvariable gesetzt wurde und diese dann am Ende wieder zu löschen (Oder aber mittels Mousehit ein Feld in deinem Type zu setzen was einer imer aufgerufenen Funktion mitteilt dass diese Typeinstanz grade aktiv ist).
Siehe dazu auch hier:
https://www.blitzforum.de/foru...180#253180
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

Brotenkopf

BeitragMi, Mai 02, 2012 10:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Also Mousehit() habe ich bewusst genommen da ich den EntityYaw() des Pivots in dem Moment wenn man klickt mit yaw=Entityyaw(pivot) speicher. d.h. wenn ich klicke und die Tür ist zu dann gibts es ja die möglichkeit die tür nach hinten/vorne zu öffnen.. wenn dann Entityaw()=90 bzw -90 ist dann wird per Mousehit() wieder ein anderer Wert für Yaw gespeichert (90 oder -90) um zu unterscheiden in welcher Phase sich die tür befindet.

Wie gesagt wenn ich den Code ohne Function() End Function in die Mainschleife kopiert funktioniert auch alles wunderbar

Xeres

Moderator

BeitragMi, Mai 02, 2012 11:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Speicher Mousehit einfach zwischen, so wie es in BladeRunners Link steht und wie es alle hier in jedem Programm machen...
Dann verwendest du immer noch lokale Variablen - genau wie vorher - und keinen Type. Was du suchst ist:
BlitzBasic: [AUSKLAPPEN]
Function UpdateDoor(D.Door)

If mh1 And D\Opening_front=0 And D\opening_behind=0 And D\open_behind=0
D\Opening_front=1
D\yaw=EntityYaw(D\pivot)
End If

;[...]

End Function
Anstatt 4 Variablen für open_wasauchimmer könntest du eine verwenden. "Zustand = OPEN_FRONT" Konstanten helfen der Lesbarkeit. Aber das nur nebenbei.
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Brotenkopf

BeitragMi, Mai 02, 2012 19:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab das mit dem Zwischenspeichern von Mousehit() schon verstanden aber 1. verwende ich ja nur einmal Mousehit(1) und Mousehit(2) und 2. selbst wenn ich sie als mh und mh2 definiere passiert wieder das selbe... anstatt eine vollstände bewegung durchzuführen bis entityYaw()=90 oder -90 ist, bewegt sich die tür nur einmal kurz. Das bedeutet ja schonmal das der Befehl Mousehit() funktioniert. Wie gesagt in der Mainschleife funktioniert ja alles oder wenn ich alle Variablen die ich in der Funktion benutze als Global setze. Das ist aber nicht sehr praktisch, da ich ja die Funktion noch für andere Türen benutzen möchte.

Xeres

Moderator

BeitragMi, Mai 02, 2012 19:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn du Mousehit mehr als einmal (für andere Türen) verwendest, musst du sie in Globalen Variablen speichern...
Wenn es noch nicht funktioniert, hast du etwas übersehen - wie sieht dein aktueller Code aus?
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Brotenkopf

BeitragMi, Mai 02, 2012 20:39
Antworten mit Zitat
Benutzer-Profile anzeigen
naja ich verwende sie ja nur einmal und es passiert ja auch etwas.. nur nicht das was ich mir vorstelle Very Happy

Code: [AUSKLAPPEN]
Type Door
   Field Mesh
   Field Pivot
End Type

Global mh1%
Global mh2%
Graphics3D 800,600,32,2
SetBuffer BackBuffer()

c=CreateCamera()


d1.Door=New Door
d1\pivot=CreatePivot()
d1\Mesh=CreateCube()
ScaleEntity d1\Mesh,1,2,.1
PositionEntity d1\Mesh,0,0,4
PositionEntity d1\pivot,EntityX(d1\Mesh)+(GetMeshWidth#(d1\Mesh)/2),EntityY(d1\Mesh),EntityZ(d1\Mesh)
EntityParent d1\Mesh,d1\pivot

While Not KeyHit(1)

mh1=MouseHit(1)
mh2=MouseHit(2)

Update_Door(d1\pivot)


UpdateWorld()
RenderWorld()
Text 0,0,"Maustaste 1 nach vorne öffnen"
Text 0,15,"Maustaste 2 nach hinten öffnen"
Flip
Wend

Function Update_Door(Pivot)
If mh1 And i=0 And i2=0 And open_behind=0
   i=1
   yaw=EntityYaw(pivot)
End If

If mh2 And i2=0 And i=0 And open_front=0
   i2=1
   yaw=EntityYaw(pivot)
End If

If i=1
   If Int yaw<-88 And Int yaw>-92
      If Int EntityYaw(pivot)<-1
         TurnEntity pivot,0,1,0
      Else
         i=0
         open_front=0
      EndIf
   EndIf
EndIf

If i=1 ;öffne frontal
   If Int yaw>-2 And Int yaw<2
      If Int EntityYaw(pivot)>-90
         TurnEntity pivot,0,-1,0
      Else
         i=0
         open_front=1
      End If
   EndIf
EndIf

If i2=1 ;schließe hinten
   If Int yaw>88 And Int yaw<92
      If Int EntityYaw(pivot)>0
         TurnEntity pivot,0,-1,0
      Else
         i2=0
         open_behind=0
      End If
   EndIf
End If

If i2=1 ;öffne hinten
   If Int yaw>-2 And Int yaw<2
      If Int EntityYaw(pivot)<90
         TurnEntity pivot,0,1,0
      Else
         i2=0
         open_behind=1
      End If
   EndIf
End If
End Function


ich denke nicht das es am Mousehit() liegt.

ZEVS

BeitragMi, Mai 02, 2012 20:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Komisch, ich schon. Du rufst MouseHit mit jedem Frame auf und speicherst die Werte ordentlich in den Variablen. Nur im nächsten Frame werden diese wieder 0 sein. Ein Ausweg: Du speicherst die Information zum Drehen direkt in den door-Objekten. Dieses Feld wird auf Mausklick geändert und erst wieder zurückgesetzt, wenn die Tür offen ist. Nun brauchst du in jedem Frame nur noch alle Türen zu prüfen und ggf. den Pivot zu drehen.

ZEVS

Brotenkopf

BeitragMi, Mai 02, 2012 21:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmmm. Ich weiß grad leider nicht wie du das meinst mit " Du speicherst die Informationen zum Drehen in den Door-objekten". Also wenn du meinst ich erstelle für die Variablen die ich benutze extra Felder und übergebe sie das wenn dann so Code: [AUSKLAPPEN]
Type Door
   Field Mesh
   Field Pivot
   Field i
   Field i2
   Field open_behind
   Field open_front
   Field yaw
End Type

und dann in der Main Schleife:

Code: [AUSKLAPPEN]
Update_Door(d1\pivot,d1\i,d1\i2,d1\open_front,d1\open_behind)


--> funktioniert auch nicht.

ZEVS

BeitragMi, Mai 02, 2012 21:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Wundervoll. Nun speicherst du am besten noch die relevanten Informationen, nämlich, in welche Richtung die Tür gedreht werden soll (alles andere kannst du rauswerfen). Ich dachte an folgendes Konzept:
BlitzBasic: [AUSKLAPPEN]
Type Door
Field Mesh
Field Pivot
Field movement
End Type

;...

;MAINLOOP

If mh1 Then d1\movement = 1
If mh2 Then d1\movement = -1

UpdateDoors

;/MAINLOOP

;...

Function UpdateDoors()

For Local d.door = Each door
If d\movement Then
TurnEntity d\mesh, 0, d\movement, 0
If ... Then d\movement = 0 ;Drehung vollständig (EntityYaw ist 90 bzw. -90)
EndIf
Next

End Function

Brotenkopf

BeitragMi, Mai 02, 2012 21:29
Antworten mit Zitat
Benutzer-Profile anzeigen
ok den ansatz versteh ich Smile
eine Frage hab ich noch:
wenn ich mehrere Türen erstelle mit
Code: [AUSKLAPPEN]
d1.Door=New Door
d2.Door=New Door
d3.Door=New Door

werden diese dann mit Code: [AUSKLAPPEN]
For Local d.door = Each door
alle einzeln angesprochen?

ZEVS

BeitragMi, Mai 02, 2012 21:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja. Sehr gut!

ZEVS

Brotenkopf

BeitragMi, Mai 02, 2012 22:19
Antworten mit Zitat
Benutzer-Profile anzeigen
vielen vielen Dank an ZEVS! es klappt sogar mit meiner alten Funktion jetzt wunderbar Smile

Code: [AUSKLAPPEN]
Type Door
      Field Mesh
      Field Pivot
   Field yaw
   Field i
   Field i2
   Field open_front
   Field open_behind
End Type

Global mh1%
Global mh2%

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

c=CreateCamera()


d1.Door=New Door
d1\pivot=CreatePivot()
d1\Mesh=CreateCube()
ScaleEntity d1\Mesh,1,2,.1
PositionEntity d1\Mesh,0,0,4
PositionEntity d1\pivot,1,EntityY(d1\Mesh),EntityZ(d1\Mesh)
EntityParent d1\Mesh,d1\pivot


While Not KeyHit(1)

mh1=MouseHit(1)
mh2=MouseHit(2)



UpdateDoors()


UpdateWorld()
RenderWorld()

Flip
Wend



Function UpdateDoors()

For  d.door = Each door

If mh1 And d\i=0 And d\i2=0 And d\open_behind=0
   d\i=1
   d\yaw=EntityYaw(d\pivot)
End If
If mh2 And d\i=0 And d\i2=0 And d\open_front=0
   d\i2=1
   d\yaw=EntityYaw(d\pivot)
End If

If d\i=1
   If Int d\yaw<-88 And Int d\yaw>-92
      If Int EntityYaw(d\pivot)<-1
         TurnEntity d\pivot,0,1,0
      Else
         d\i=0
         d\open_front=0
      EndIf
   EndIf
EndIf

If d\i=1 ;öffne frontal
   If Int d\yaw>-2 And Int d\yaw<2
      If Int EntityYaw(d\pivot)>-90
         TurnEntity d\pivot,0,-1,0
      Else
         d\i=0
         d\open_front=1
      End If
   EndIf
EndIf

If d\i2=1 ;schließe hinten
   If Int d\yaw>88 And Int d\yaw<92
      If Int EntityYaw(d\pivot)>0
         TurnEntity d\pivot,0,-1,0
      Else
         d\i2=0
         d\open_behind=0
      End If
   EndIf
End If

If d\i2=1 ;öffne hinten
   If Int d\yaw>-2 And Int d\yaw<2
      If Int EntityYaw(d\pivot)<90
         TurnEntity d\pivot,0,1,0
      Else
         d\i2=0
         d\open_behind=1
      End If
   EndIf
End If

Next

End Function


gut ich könnte den code bestimmt irgendwie leserlicher machen aber für mich erfüllt es seinen zweck jetzt sehr gut.
auch vielen Dank an Xeres und BladeRunner Smile

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group