SpritePixelCollision?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: SpritePixelCollision?

Beitrag von HeX0R »

Mach einfach mal den Debugger an, er sagt Dir dann was falsch ist.
Benutzeravatar
jojo1541
Beiträge: 431
Registriert: 15.09.2007 17:12
Wohnort: Irgendwo im Nirgendwo

Re: SpritePixelCollision?

Beitrag von jojo1541 »

Du willst in deiner Kollisionsabfrage die Araystelle 501 abfragen. Dein Array ist allerdings in dieser Dimension nur bis 90 definiert.

Der Rest sollte kein Problem sein. :wink:
Ich verkaufe Rechtschreibfehler und jede menge GROßBUCHSTABEN. Alles unbegrenzt zu haben.
TheNewOne
Beiträge: 60
Registriert: 06.04.2011 14:33

Re: SpritePixelCollision?

Beitrag von TheNewOne »

Ah stimmt ja. :lol:
Win7, 64bit, PB 4.60
TheNewOne
Beiträge: 60
Registriert: 06.04.2011 14:33

Re: SpritePixelCollision?

Beitrag von TheNewOne »

Habe meinen Code nun überarbeitet, und bin nun auf ein kleines Problem gestoßen. Egal was ich probiere der "Spieler" kollidiert nicht richtig. Man kann teilweise durch den Halben Block durch.

Code: Alles auswählen

;----------- Variablen ---------------;
Global ende.i = 0                    ; Beendet das Spiel
Global pX.i = Random(1600)            ; X-Position des Spielers
Global pY.i = Random(200)             ; Y-Position des Spielers
Global fg.i                          ; Schwerkraft
Global hoehe.i
Global richtung.i                    ; besagt ob bei der nächsten X-Koordinate der Block höher oder tiefer liegt
Global nHoehe.i                      ; die Höhe der nächsten X-Koordinate

;----------- Structuren --------------;

Structure BlockEigenschaften
  id.i                                ; 0 für Luft, 1 für Erde
  maxHoehe.i                          ; Höchster Block (0 für Nein, 1 für Ja)
EndStructure

;----------- Arrays ------------------;

Global Dim Block.BlockEigenschaften(90,45)

;--------- Generate World ------------;

Procedure Generate()
  
  hoehe = Random(20) + 20
  
  For x = 0 To 90
    
    richtung = Random(1)
    nHoehe = Random(2)
    
    If richtung = 0
      nHoehe * -1
    EndIf
    
    hoehe + nHoehe                          ; nächste Hoehe festegelgt
    
    If hoehe < 0
      hoehe = 0
    ElseIf hoehe > 45
      hoehe = 45
    EndIf
    
    For y = 45 To hoehe Step -1            ; Block = Erde
      Block(x,y)\id = 1
      Block(x,y)\maxHoehe = 0
      If m = hoehe                          ; Höhe der X-Koordinate
        Block(n,m)\maxHoehe = 1
      EndIf
    Next
    
    For y = hoehe To 0 Step -1             ; Block = Luft
      Block(x,y)\id = 0
    Next
  Next
  
EndProcedure  

;---------- Draw ---------------------;

Procedure CreateSprites()
  
  CreateSprite(0, 20, 20)            ; Spieler erstellen
  StartDrawing(SpriteOutput(0))
  Circle(10, 10, 10, RGB(225, 255,0))
  StopDrawing()
  
  CreateSprite(1, 20, 20)              ; Erde erstellen
  StartDrawing(SpriteOutput(1))
  Box(0, 0, 20, 20, RGB(0, 150, 0))
  StopDrawing()
  
EndProcedure

Procedure DrawSprites()
  
  For x = 0 To 90
    For y = 0 To 45    
      If Block(x,y)\id = 1
        DisplaySprite(1,x*20,y*20) 
      EndIf
    Next
  Next
  
  DisplayTransparentSprite(0, pX, pY)
  TransparentSpriteColor(0,0)
  
EndProcedure

;---------- Movement -----------------;

Procedure MovePlayer()
  
  ExamineKeyboard()
  
  If Block(px/20,(py+20)/20)\maxHoehe = 0
    pY + fg                                ; Schwerkraft
  EndIf
  
  If Block(pX/20,(pY+20)/20)\id = 0
    fg + 1
  ElseIf Block(pX/20,(pY+20)/20)\id = 1
    fg = 0
  EndIf

  
  If KeyboardReleased(#PB_Key_Escape)    ; Beenden
    ende = #True
  EndIf
  
  If KeyboardPushed(#PB_Key_W)           ; Hüpfen
    fg = -5
  EndIf
  
  If KeyboardPushed(#PB_Key_A)           ; Links
    If Block(px/20, (py)/20)\id  = 0 Or Block(px/20, (py+20)/20)\id = 0
      pX - 5
    EndIf
  EndIf
  
  If KeyboardPushed(#PB_Key_D)           ; Rechts
    If Block((px+20)/20, py/20)\id = 0 Or Block((px+20)/20, (py+20)/20)
      pX + 5
    EndIf
  EndIf
  
EndProcedure

;---------- Screen öffnen ------------;

InitSprite()
InitKeyboard()
OpenScreen(1600, 900, 32, "FullScreen")

Generate()
CreateSprites()

Repeat
  ClearScreen(RGB(0,0,0))
  ExamineKeyboard()
  MovePlayer()
  DrawSprites()
  FlipBuffers()
Until ende = #True
Win7, 64bit, PB 4.60
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: SpritePixelCollision?

Beitrag von man-in-black »

If KeyboardPushed(#PB_Key_D) ; Rechts
If Block((px+20)/20, py/20)\id = 0 Or Block((px+20)/20, (py+20)/20)
pX + 5
EndIf
EndIf
da fehlt ein "\id = 0" :mrgreen:
(hab alles, kann alles, weiß alles!!^^)

Bild
Benutzeravatar
jojo1541
Beiträge: 431
Registriert: 15.09.2007 17:12
Wohnort: Irgendwo im Nirgendwo

Re: SpritePixelCollision?

Beitrag von jojo1541 »

Ach ja, das Problem kenn ich. :lol:

Da müsstest du aber leider wen anders fragen, da ich mich mit diesem Problem bis jetzt noch nie richtig beschäftigt habe.
Ich verkaufe Rechtschreibfehler und jede menge GROßBUCHSTABEN. Alles unbegrenzt zu haben.
TheNewOne
Beiträge: 60
Registriert: 06.04.2011 14:33

Re: SpritePixelCollision?

Beitrag von TheNewOne »

Hmm, kann es sein dass ich hier:

Code: Alles auswählen

 If Block(px/20, (py)/20)\id  = 0 Or Block(px/20, (py+20)/20)\id = 0
für jeden einzelnen Punkt des "Spielers" die id abfragen muss? Also py+1,py+2 usw. ?
Win7, 64bit, PB 4.60
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: SpritePixelCollision?

Beitrag von man-in-black »

1. Mir ist aufgefallen, dass du "TransparentSpriteColor(0,0)" in der Repeat schleife stehen hast (durch die Procedure DrawSprites()). Den Befehl brauchst aber eigt nur einmal aufrufen, weil du das Sprite damit nachhaltig modifizierst.

2. Du brauchst nur die Boxen links und rechts neben der Box, auf der du aktuell bist, abfragen. Die Aktuelle zu prüfen is unnötig, da man davon ausgehen kann, dass der Spieler durch einen geprüften Schritt dorthin gekommen ist.

Code: Alles auswählen

;für links:
if px=>20   ;ganz wichtig, da du sonst das Array überfordern könntest ;)
  spieler_raster_x = Round(px/20,1)-1        ;geht auch, wenn du das Round weg lässt. Wollte es nur sauber schreiben.
  spieler_raster_y = (py)/20
  If Block(spieler_raster_x, spieler_raster_y)\id  = 0 
...

;für rechts:
if px< "___Anzahl_Boxen____"-20
  spieler_raster_x = Round(px/20,1)+1
  spieler_raster_y = (py)/20
  If Block(spieler_raster_x, spieler_raster_y)\id  = 0 
...
Wenn deine Schritte weiterhin deutlich unter der Blockbreite bleiben, reicht es, nur eine Box neben dem Spieler zu überprüfen. Man kann dann nämlich davon ausgehen, dass du niemals ausversehen eine Box "tunneln" und dadurch einen Bug erzeugen wirst.
(hab alles, kann alles, weiß alles!!^^)

Bild
TheNewOne
Beiträge: 60
Registriert: 06.04.2011 14:33

Re: SpritePixelCollision?

Beitrag von TheNewOne »

Danke euch zwei erst mal für die geduldigen Antworten :lol: .
Ich habe nur noch ein Problem, dass ich einfach nicht zu beheben schaffe:
Die Kollision vom "Spieler" und dem Boden. Egal was ich rumprobiere, ich schaffe es nicht dass der "Spieler" sauber AUF den Blöcken landet, und beim hin- und herbewegen nicht andauernd durch halbe Blöcke rutscht /:-> .
Bitte um Hilfe :(
Win7, 64bit, PB 4.60
Benutzeravatar
jojo1541
Beiträge: 431
Registriert: 15.09.2007 17:12
Wohnort: Irgendwo im Nirgendwo

Re: SpritePixelCollision?

Beitrag von jojo1541 »

Füg mal ein

Code: Alles auswählen

pY = py/20 * 20
nach

Code: Alles auswählen

 ElseIf Block(pX/20,(pY+20)/20)\id = 1
    fg = 0
ein.

Das gleiche für pX.

Code: Alles auswählen

 If KeyboardPushed(#PB_Key_A)           ; Links
    If Block((px - 5)/20, (py)/20)\id  = 0
      pX - 5
    Else
      pX = pX/20 * 20
    EndIf
  EndIf
 
  If KeyboardPushed(#PB_Key_D)           ; Rechts
    If Block((px+20)/20, py/20)\id = 0
      pX + 5
    Else
      pX = pX/20 * 20
    EndIf
  EndIf
Wichtig ist hier das pX - 5 in der Abfrage, damit du auch wirklich die Arraystelle links von dir abfragst.

Ich weiß nicht, ob es ideal ist, aber es sollte (zumindest bei den Symptomen) helfen.
Zuletzt geändert von jojo1541 am 09.01.2013 23:38, insgesamt 1-mal geändert.
Ich verkaufe Rechtschreibfehler und jede menge GROßBUCHSTABEN. Alles unbegrenzt zu haben.
Antworten