Probleme mit Kollision

Anfängerfragen zum Programmieren mit PureBasic.
obar
Beiträge: 111
Registriert: 22.11.2007 19:47

Probleme mit Kollision

Beitrag von obar »

Hallo zusammen,

ich habe mir mal erlaubt einen Code zu verlinken. Ich wäre froh, wenn sich jemand mal den Code anschauen könnte. Ich finde das Problem einfach nicht. Ich habe eine Figur die sich auf einer Tilemap bewegt. Natürlich darf er nicht durchs Wasser laufen. Nach unten, links und rechts funzt es aber nach oben läufts nicht. Ich versteh nicht wieso.
Bitte kein Gelächter wegen des Code, ich bin immer noch ein riesen Anfänger.

http://uploaded.to/?id=vzsrtm
Benutzeravatar
Franky
Beiträge: 1132
Registriert: 29.08.2004 16:31
Wohnort: Münsterland
Kontaktdaten:

Beitrag von Franky »

Hi obar. Soweit ich das überblicke liegt dein Problem einfach im

Code: Alles auswählen

        If FineY < 0 
          FineY = 30
          MapY-1 
          If MapY < 0 
            MapY = 0 
            FineY = 0 
          EndIf 
Du weißt MapY vorher keinen Wert zu, es ist also 0, somit kannst du nach oben laufen, wie du willst, es wird immer genau an der Stelle hängen bleiben ;)

Geh mal ein Stück nach unten und du wirst sehen, dass die Steuerung nach oben serwohl funktioniert, aber eben nur bis zu diesem Punkt.

Für nen Tipp der Abhilfe ist es mir jetzt zu spät, aber du kriegst das schon hin.


mfg Franky

Edit:

Mit

Code: Alles auswählen

        FineY=FineY-2
        If FineY < 0 
          FineY = 30
          MapY-1 
          If MapY < 0 
            MapY = mapHeight -19
            FineY = 0 
          EndIf 
        EndIf
bewirkst du z.B, dass dein Mänchen automatisch am unteren Ende der Map wieder anfängt. Ich hoffe, so kann man besser verstehen, was ich meine
Falsch zugeordnetes Zitat des Tages: "O'zapft is" - Edward Snowden :)
obar
Beiträge: 111
Registriert: 22.11.2007 19:47

Beitrag von obar »

Nein, das ist schon richtig so. Dies ist die Grenze der Map. Ist ein bisschen verwirrend weils auch Wiese ist. Aber wenn du jetzt nach unten läufst kommst du zum Wasser. Dort müsst ihr mal die Koll prüfen, dann wirst du sehen dass, wenn du von unten her ans Wasser läufst, läuft er etwa einen halben cm ins Wasser. Ich hab nun schon diverses probiert. Aber kriegs nicht hin.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

das liegt an deinem #playerHeight

Wenn du dort n bisschen rumspielst (#playerHeight/2, -#playerHeight, ...)
verändert sich der haltepunkt.

Dies solltest du auch bei links/rechst überprüfen, denn da will er auch nicht immer gehen obwohl genug platz ist.

EDIT:

Diese Zeile kommt mir komisch vor: 164

Code: Alles auswählen

...(playerY+((#playerHeight/2)))...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
obar
Beiträge: 111
Registriert: 22.11.2007 19:47

Beitrag von obar »

Danke für den Tipp. Werde es mal probieren.
obar
Beiträge: 111
Registriert: 22.11.2007 19:47

Beitrag von obar »

Ich krieg das einfach nicht hin. :(
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

ich würde ja gerne mehr helfen aber bei den Tastenabfragen sind eindeutig zu viele Klammern ^^, sry

TIP: Schreibe den Bewegungsteil einfach noch mal komplett von 0, oder 0,1 ^^ neu (speicher das alte als BACKUP)

Das hat bis jetzt immer bei mir geholfen, weil ich dnan besser drüber nachgedacht habe und nicht gestückelt habe
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
obar
Beiträge: 111
Registriert: 22.11.2007 19:47

Beitrag von obar »

Ich komm nicht drauf. Ich versteh nicht wieso das es in 3 Richtungen läuft und wenn ich hochlaufe nicht. :cry:
Benutzeravatar
#NULL
Beiträge: 2238
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

ich habe mal ein bisschen umgebaut damit deine kollision funktioniert. mapX/Y ist jetzt aber was anderes ( =pixel-wert für den map-offset). außerdem wird die ganze map gezeichnet, musst du also noch start- und end-punkte für die map-loop variabel machen und immmer berechnen.
vielleicht nützt dir's was.
(sind noch ein paar test/debug sachen drin, musste noch rauhauen)

Code: Alles auswählen

; http://www.purebasic.fr/german/viewtopic.php?t=15363

;
;       Test-Animation 
;   mit Umgebungs-Kollision
;
;*****************************
;** Konstanten
;*****************************
#ResX                   = 800
#ResY                   = 600
#BPP                    = 32
#TileSize               = 32
#playerWidth            = 27
#playerHeight           = 41 

;*****************************
;** Define variablen
;*****************************
Global playerX.l    = 400 ;- #playerWidth/2
Global playerY.l    = 300 ;- #playerHeight/2
Global AnimFrame.l  = 111
Global counter.l    = 0
Global MapX.l       = 0
Global MapY.l       = 0
Global uPath.s
Global FineX.l
Global FineY.l

Global frametimer.l = 0
Global framedelay.l = 60

;*****************************
;** Enumuration
;*****************************
Enumeration
  #Test00     = 0
  #Test01  
  #Test02  
  #Test03  
  #Test04  
  #Test05  
  #Test06  
  #Test07  
  #Test08  
  #Test09  
  #Test10  
  #Test11  
  #Maus   = 500
  EndEnumeration
  
  Enumeration
  #Test12     = 12
  #Test13
  #Test14
EndEnumeration
;*****************************
;** Daten Laden
;*****************************
UsePNGImageDecoder()

;*****************************
;** Struktur & Arrays
;*****************************
Structure _Object
  TileID.b
  objID.b
  objWalk.b
  objAction.b
  objSound.b
EndStructure




;*****************************
;** Proceduren
;*****************************
Procedure check(value.l, text.s) 
   If Value = 0 
      MessageRequester("error", text, 0) 
      End 
   EndIf 
EndProcedure

Procedure Init()
  check(InitSound(),    "InitSound() failed")
  check(InitKeyboard(), "InitKeyboard() failed")
  check(InitMouse(),    "InitMouse() failed")
  check(InitSprite(),   "InitSprite() failed")
  SetRefreshRate(60)
  win1Nr.l = OpenScreen(#ResX, #ResY, #BPP, "")
  check( win1Nr, "OpenScreen() failed")
EndProcedure

Procedure initmap()
      Global mapWidth.l  
      Global mapHeight.l   
      Global Dim map._Object(mapWidth, mapHeight)     
EndProcedure

Procedure ShowLand(x.l, y.l)
  Static grid.l = 0
  If grid = 0
    grid = CreateSprite(#PB_Any,32,32)
    StartDrawing(SpriteOutput(grid))
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(0,0,#TileSize,#TileSize,$444444)
    StopDrawing()
  EndIf
  
  Protected t.l, n.l, k.l, i.l 
    ;
    ; Zeigt den Mapauschnitt an
    ;
    For t=0 To mapHeight
        For n=0 To mapWidth
        DisplaySprite(map(n,t)\TileID, (mapX + #TileSize*n),(mapY + #TileSize*t) )
        If map(n,t)\objID > 0
          DisplayTransparentSprite(map(n,t)\objID, 8+(mapX + #TileSize*n),8+(mapY + #TileSize*t) )
        EndIf
        
        DisplayTransparentSprite(grid, (mapX + #TileSize*n),(mapY + #TileSize*t) )
;         StartDrawing(ScreenOutput())
;           DrawingMode(#PB_2DDrawing_Transparent)
;           DrawText( (#TileSize * n) - FineX, (#TileSize * t) - FineY, Str(map(MapX+n,MapY+t)\TileID) +","+ Str(map(MapX+n,MapY+t)\ObjID) +","+ Str(map(MapX+n,MapY+t)\ObjWalk) )
;         StopDrawing()
      Next 
    Next    
EndProcedure

Procedure displayAnimation(startAnim.b, stopAnim.b)
  While ElapsedMilliseconds() - frametimer > framedelay
    frametimer = ElapsedMilliseconds()
    AnimFrame + 1
    If AnimFrame > stopAnim 
      AnimFrame = startAnim 
    EndIf  
  Wend 
EndProcedure 


Procedure isAccessible(x.l, y.l)
  Static i.l, k.l
  i = ((playerX-mapX+x)/#TileSize)
  k = ((playerY-mapY+y)/#TileSize)
  If i>=0  And  i<=mapWidth  And k>=0  And  k<=mapHeight  And  map(i,k)\TileID < 10
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

Procedure Steuerung() 
  Static speed.l = 2
  
  
  If KeyboardPushed(#PB_Key_Left) ;{
    If AnimFrame > 114 And AnimFrame <= 118
      If isAccessible(-speed-8,-6) And isAccessible(-speed+8,-6) And isAccessible(-speed-8,4) And isAccessible(-speed+8,4)
        mapX+speed
      EndIf
      displayAnimation(115, 118)
    Else 
      AnimFrame = 115 
    EndIf    ;}
  EndIf 
  
  If KeyboardPushed(#PB_Key_Right) ;{
    If AnimFrame > 118 And AnimFrame <= 122
      If isAccessible( speed-8,-6) And isAccessible( speed+8,-6) And isAccessible( speed-8,4) And isAccessible( speed+8,4)
        mapX-speed
      EndIf
      displayAnimation(119, 122) 
    Else 
      AnimFrame = 119 
    EndIf ;}
  EndIf    
  
  If KeyboardPushed(#PB_Key_Up) ;{
    If AnimFrame > 122 And AnimFrame <= 126   
      If isAccessible(-8,-speed-6) And isAccessible(8,-speed-6) And isAccessible(-8,-speed+4) And isAccessible(8,-speed+4)
        mapY+speed
      EndIf
      displayAnimation(123, 126)
    Else 
      AnimFrame = 123 
    EndIf ;}
  EndIf   
     
  If KeyboardPushed(#PB_Key_Down) ;{
    If AnimFrame > 110 And AnimFrame <= 114
      If isAccessible(-8, speed-6) And isAccessible(8, speed-6) And isAccessible(-8, speed+4) And isAccessible(8, speed+4)
        mapY-speed
      EndIf
      displayAnimation(111, 114)
    Else 
      AnimFrame = 111 
    EndIf   ;}
  EndIf 
  
  If KeyboardPushed(#PB_Key_LeftControl) 
  ; #PB_Key_LeftControl 
  EndIf 
  
    
  If KeyboardPushed(#PB_Key_Escape) 
    End ;ProgrammAbbruch 
  EndIf  

EndProcedure 

Procedure.l mapLoad(mapName.s)
  Protected t.l, n.l
  ;
  ; Level Laden
  ;
  If OpenFile(0,mapName+".map")
    mapWidth = ReadLong(0)
    mapHeight = ReadLong(0)
    objAnzahl = ReadLong(0)
    initmap()
    For t = 0 To mapHeight 
      For n = 0 To mapWidth 
        map(n,t)\tileID = ReadLong(0)
        
        If Random(10) ::: map(n,t)\tileID = 1
        Else          ::: map(n,t)\tileID = 11
        EndIf
        
        map(n,t)\objID = ReadLong(0) 
        map(n,t)\objWalk = ReadLong(0)
      Next 
    Next 
    CloseFile(0)
  EndIf
EndProcedure





;*****************************
;** Sprites Laden
;*****************************
Init()


For i = 111 To 126
  LoadSprite(i, ".\Grafik\" + Str(i) + ".png")
  TransparentSpriteColor(i, RGB(0,255,255))  
Next


uPath = GetCurrentDirectory()
LoadSprite(#Test00,  uPath+"Grafik\000.png") ;{
LoadSprite(#Test01,  uPath+"Grafik\001.png")
LoadSprite(#Test02,  uPath+"Grafik\002.png")
LoadSprite(#Test03,  uPath+"Grafik\003.png")
LoadSprite(#Test04,  uPath+"Grafik\004.png")
LoadSprite(#Test05,  uPath+"Grafik\005.png")
LoadSprite(#Test06,  uPath+"Grafik\006.png")
LoadSprite(#Test07,  uPath+"Grafik\007.png")
LoadSprite(#Test08,  uPath+"Grafik\008.png")
LoadSprite(#Test09,  uPath+"Grafik\009.png")
LoadSprite(#Test10,  uPath+"Grafik\010.png")
LoadSprite(#Test11,  uPath+"Grafik\011.png")

LoadSprite(#Test12,  upath+"Grafik\Hag.png")
LoadSprite(#Test13,  upath+"Grafik\Hag2.png")
LoadSprite(#Test14,  upath+"Grafik\Schild.png")

TransparentSpriteColor(#Test12, RGB(255,103,139))
TransparentSpriteColor(#Test13, RGB(255,103,139)) ;}
TransparentSpriteColor(#Test14, RGB(255,103,139))
;*****************************
;** Loop
;*****************************

mapload("oli10")


Repeat 
  ClearScreen(0)
  ExamineKeyboard()
  Steuerung()
  ShowLand(0,0)   
  
  DisplayTransparentSprite(AnimFrame,playerX-#playerWidth/2, playerY-#playerHeight+5)
  StartDrawing(ScreenOutput())
    Circle(playerX   , playerY   , 2,$ffffff)
    Circle(playerX-8, playerY-6, 2,$0000ff)
    Circle(playerX+8, playerY-6, 2,$0000ff)
    Circle(playerX-8, playerY+4, 2,$0000ff)
    Circle(playerX+8, playerY+4, 2,$0000ff)
  StopDrawing()
  
  FlipBuffers() 
Until KeyboardPushed(#PB_Key_Escape)

End
ich weiß ja auch nicht, wie du deine kollision haben wilsst. nur also punkt, oder über das ganze player-tile, oder nur eine kleine fläche wie in meinem code?
my pb stuff..
Bild..jedenfalls war das mal so.
obar
Beiträge: 111
Registriert: 22.11.2007 19:47

Beitrag von obar »

:o Dank vielmal. Sieht sehr gut aus.

Werde nun mal deinen Lösungsansatz studieren.

Danke, dass du dir die Zeit genommen hast mir zu Helfen. <) :allright:
Antworten