Bei einer Kollision setzte ich momentan das Objekt das kollidiert an die ursprüngliche Position zurück.
Das geht zwar ist aber nicht sauber.
Ich hätte gerne das sich die Kollisionen im inneren der Welt genauso wie an den Rändern verhalten.
Perfekte Kollision am Punkt + nicht kollidierte Achse wird nicht blockiert.
Hier mal der Code zum rumspielen:
Code: Alles auswählen
Structure VECTOR_STRUCT
X.f
Y.f
EndStructure
Structure WORLD_POSITION_STRUCT
X.f
Y.f
Id.b
EndStructure
Structure WORLD_STRUCT
Array Offset.WORLD_POSITION_STRUCT(255,255)
EndStructure
Global Exit.b
Global Event.i
Global DeltaTime.f = 1;DUMMY!
Global WorldX.i
Global WorldY.i
Global Level.WORLD_STRUCT
Global Player.VECTOR_STRUCT
Global Move.VECTOR_STRUCT
Global *TileId.Ascii
Procedure.b RectIntersect(*V1.VECTOR_STRUCT,*V2.VECTOR_STRUCT)
If *V1\X < *V2\X + 16 And *V1\X + 16 > *V2\X
If *V1\Y < *V2\Y + 16 And *V1\Y + 16 > *V2\Y
ProcedureReturn #True
EndIf
EndIf
EndProcedure
Procedure.i WorldCollision()
Protected X.i,Y.i
If Move\X < 0:Move\X = 0:ElseIf Move\X > 304:Move\X = 304:EndIf;MAP BOUNDARIES
If Move\Y < 0:Move\Y = 0:ElseIf Move\Y > 304:Move\Y = 304:EndIf
For Y = 0 To 19
For X = 0 To 19
If Level\Offset(X,Y)\Id
If RectIntersect(@Move,@Level\Offset(X,Y))
Move = Player;IF ANY COLLISION -> RESET PLAYER POS
EndIf
EndIf
Next
Next
EndProcedure
If InitSprite() And InitKeyboard()
If OpenWindow(0,#Null,#Null,600,400,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0),#Null,#Null,800,600,#False,#Null,#Null);V-SYNC DOES NOT WORK ON MY PC!
;------------------------------------------------ GEN TILE LOOKUP TABLE
For WorldY = 0 To 19
For WorldX = 0 To 19
*TileId = ?level + (WorldY * 20) + WorldX
Level\Offset(WorldX,WorldY)\Id = *TileId\a
Level\Offset(WorldX,WorldY)\X = WorldX * 16
Level\Offset(WorldX,WorldY)\Y = WorldY * 16
Next
Next
;------------------------------------------------ INIT PLAYER POS
Player\X = Level\Offset(12,10)\X
Player\Y = Level\Offset(12,10)\Y
Repeat
Repeat
Event = WindowEvent()
If Event = #PB_Event_CloseWindow:Exit = #True:EndIf
Until Event = #Null
Move = Player
ExamineKeyboard()
If KeyboardPushed(#PB_Key_A):Move\X - 3 * DeltaTime:EndIf
If KeyboardPushed(#PB_Key_D):Move\X + 3 * DeltaTime:EndIf
If KeyboardPushed(#PB_Key_W):Move\Y - 3 * DeltaTime:EndIf
If KeyboardPushed(#PB_Key_S):Move\Y + 3 * DeltaTime:EndIf
WorldCollision();CHECK FOR COLLISION
Player = Move
ClearScreen($0)
If StartDrawing(ScreenOutput())
For WorldY = 0 To 19
For WorldX = 0 To 19
If Level\Offset(WorldX,WorldY)\Id
DrawingMode(#PB_2DDrawing_Default)
Box(Level\Offset(WorldX,WorldY)\X + 140,Level\Offset(WorldX,WorldY)\Y + 40,16,16,$FFFFFF)
Else
DrawingMode(#PB_2DDrawing_Outlined)
Box(Level\Offset(WorldX,WorldY)\X + 140,Level\Offset(WorldX,WorldY)\Y + 40,16,16,$3E071B)
EndIf
Next
Next
Box(Player\X + 140,Player\Y + 40,16,16,$43FF43)
DrawingMode(#PB_2DDrawing_Outlined)
Box(140,40,320,320,$FF5FB0);MAP OUTLINE
StopDrawing()
EndIf
FlipBuffers()
Until Exit
EndIf
CloseWindow(0)
EndIf
EndIf
DataSection
level:
!db 1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1
!db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0
!db 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0
!db 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0
!db 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0
!db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1
!db 1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1
!db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,1,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0
!db 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,1,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0
!db 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
!db 1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1
EndDataSection
Code: Alles auswählen
;-> einfügen anstelle von: Move = Player
If Move\X < Level\Offset(X,Y)\X
Move\X = Level\Offset(X,Y)\X - 16
ElseIf Move\X > Level\Offset(X,Y)\X
Move\X = Level\Offset(X,Y)\X + 16
EndIf
; If Move\Y < Level\Offset(X,Y)\Y
; Move\Y = Level\Offset(X,Y)\Y - 16
; ElseIf Move\Y > Level\Offset(X,Y)\Y
; Move\Y = Level\Offset(X,Y)\Y + 16
; EndIf
Wie kann ich das sauber lösen ?