Aktuelles Listenelement?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Milchshake
Beiträge: 166
Registriert: 30.01.2006 17:47
Wohnort: Zwischen dem Sessel und dem Computer

Aktuelles Listenelement?

Beitrag von Milchshake »

In dem Code unten gibt es ein Problem, das ich nicht beheben kann.
Es sollte das Kästchen runterfallen, und erst auf dem einen , und nachher auf den anderen Balken fliegen.
Doch nur der linke Balken wird als Collisionselement anerkannt.
Ich denke, es liegt daran, dass das letzt Erstellte Listenelement das Aktuelle ist. Wie kann ich dies Beheben, bzw. umgehen?

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitSound()
InitMouse()

OpenScreen(1024,768,32,"Engine-Testing")

Structure Show
  x.w
  y.w
  Width.w
  Height.w
  Image.w
  SpeedX.w
  SpeedY.w
  Durchgehbar.w
EndStructure
Global NewList Show.Show()
Procedure AddShow(Sprite, x, y, SpeedX, SpeedY,Durchgehbar) 
  AddElement(Show())           
  Show()\x      = x
  Show()\y      = y
  Show()\Width  = SpriteWidth(Sprite)
  Show()\Height = SpriteHeight(Sprite)
  Show()\Image  = Sprite
  Show()\SpeedX = SpeedX
  Show()\SpeedY = SpeedY
  Show()\Durchgehbar = Durchgehbar
  
EndProcedure


CreateSprite(0,40,40)
 StartDrawing(SpriteOutput(0))       ;PLATZHALTE
 Box(0,0,40,40,#White)
 StopDrawing()

CreateSprite(5,1,40)              ;COLLISIONSABFRAGE1
 StartDrawing(SpriteOutput(5))
 Box(0,0,1,40,#Green)
 StopDrawing()
 
 CreateSprite(6,40,1)
 StartDrawing(SpriteOutput(6))    ;COLLISIONSABFRAGE2
 Box(0,0,40,1,#Green)
 StopDrawing()
 
   ; Image 1 (Testimage)
   CreateSprite(1,100,20)
    StartDrawing(SpriteOutput(1))
     Box(0,0,100,20,#Green)
    StopDrawing()
    
    
PlayerY = 200
PlayerX = 500
Gravity = 2
Repeat 
ExamineKeyboard()
ExamineMouse()
FlipBuffers()
ClearScreen(0)
If Loading = 0
AddShow(1,500,500,0,0,1)
AddShow(1,600,520,0,0,1)
Loading = 1
EndIf 

DisplayTransparentSprite(0,PlayerX,PlayerY)  ;PLAYER-PLATZHALTEr
DisplayTransparentSprite(5,PlayerX-1,PlayerY) ;LINKS_COLLISIONSABFRAGE
DisplayTransparentSprite(5,PlayerX+41,PlayerY);RECHTS_COLLISIONSABFRAGE
DisplayTransparentSprite(6,PlayerX,PlayerY-1) ;OBEN_COLLISIONSABFRAGE
DisplayTransparentSprite(6,PlayerX,PlayerY+41);UNTEN_COLLISIONSABFRAGE
Gosub Adding
Gosub Colli

    
    StartDrawing(ScreenOutput())
     DrawingMode(1)
     DrawText(0,0,"Gravity: " + Str(Gravity),#White)
     DrawText(0,15,"PlayerY: " + Str(PlayerY),#White)
     DrawText(0,30,"List-Elemente: " + Str(CountList(Show())),#White)
     StopDrawing()
    
    
;FORTBEWEGUNG
If KeyboardPushed(#PB_Key_Left)
PlayerX - 2
EndIf

If KeyboardPushed(#PB_Key_Right) 
PlayerX + 2
EndIf

Until KeyboardPushed(#PB_Key_Escape)
End 



Adding:

ResetList(Show())
While NextElement(Show())

;DARSTELLUNG--------------------------
 
  DisplayTransparentSprite(Show()\Image, Show()\x, Show()\y)   ; Display the bullet


Wend


Return 

Colli: 
    ResetList(Show())
    While NextElement(Show())
     If Show()\Durchgehbar = 1
      If SpritePixelCollision(Show()\Image, Show()\x, Show()\y,6,PlayerX,PlayerY+41) = 0
        fallen = 1
        
      EndIf
         If SpritePixelCollision(Show()\Image, Show()\x, Show()\y,6,PlayerX,PlayerY+41) = 1
        fallen = 0
        
      EndIf
      EndIf 
  
    Wend
     
     If fallen = 1
       
       PlayerY + Gravity
       
     EndIf
Return 
Hab jetzt PB 4.02
Muhahaha!!!!
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Du musst deine Kollisionsprocedure anpassen:

Code: Alles auswählen

Colli:
  fallen = 1
  ForEach Show()
    If Show()\Durchgehbar = 1
      If SpritePixelCollision(Show()\Image, Show()\x, Show()\y,6,PlayerX,PlayerY+41) = 1
        fallen = 0
      EndIf
    EndIf
  Next
  
  If fallen = 1
    PlayerY + Gravity
  EndIf
Return
Das Geheimnis: Falls einmal eine Kollision auftritt, muss 'fallen' auf Null
gesetzt werden. Bei deiner alten Version war es so, dass 'fallen' auch
wieder auf Eins gesetzt wurde, wenn irgendwo danach keine Kollision mehr
war.
Benutzeravatar
Milchshake
Beiträge: 166
Registriert: 30.01.2006 17:47
Wohnort: Zwischen dem Sessel und dem Computer

Beitrag von Milchshake »

Ok, das funktioniert jetzt...Danke :)

Aber noch eine Frage, was ist der Unterschied zwischen While...Wend
und (das was du verwendet hast) For Each...Next?
Ich habe es mit beide Ausprobiert, kann aber keinen Unterschied erkennen...
Hab jetzt PB 4.02
Muhahaha!!!!
Benutzeravatar
Sebastian
Beiträge: 322
Registriert: 14.06.2006 16:46
Wohnort: Kiel

Beitrag von Sebastian »

Code: Alles auswählen

While <Aussage> = True
...
Wend
Solange die Aussage zutrifft werden die Befehle abgearbeitet. Diese Schleife wird auch ohne LinkedLists verwendet.

Code: Alles auswählen

ForEach
...
Next
Diese Schleife ist ein Pendant zu der normalen For... Next -Schleife. Hier werden jedoch ALLE ELEMENTE der Liste abgearbeitet, schließlich kann ja nicht vorher gesagt werden, wie oft die Schleife durchlaufen werden soll, da man vorher die Anzahl der einzelnen Elemente nicht kennt.
(Win 11 64-bit, PB 6.04 und 6.10)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@Milchshake:
Was soll das eigentlich hier mit den doppelten Threads?
Siehe Collisions-Abfrage Fehler
Antworten