|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
ALWIM
Anmeldungsdatum: 08.08.2006 Beiträge: 1037 Wohnort: Niederbayern
|
Verfasst am: 13.06.2020, 22:52 Titel: Kollisionserkennung bei Sprites bzw geladenen Bitmaps |
|
|
Ich suche irgendwie eine Möglichkeit, wenn eine Bitmap-Datei geladen ist, eine Kollisionserkennung zu realisieren. Das heißt: Meine Figur wird geladen und kann sich auf dem geladenen Hintergrundbild (Haus, Zimmer, Wohnung, …)frei bewegen. Wenn auf dem Bild ein Stuhl oder ein Tisch oder eine Wand kommt, soll die Figur stoppen bzw. nicht weiterlaufen können. Kann man die Gegenstände als Bitmap-Datei nicht irgendwie über Data zum anzeigen bringen? Quasi über Data wird das Level gezeichnet bzw. definiert und an der entsprechenden Position die Bitmap auf dem Bildschirm angezeigt.
Ich stehe da etwas auf dem Schlauch. Keine Ahnung wie ich so etwas mache? _________________ SHELL SHUTDOWN -s -t 05 |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 14.06.2020, 02:19 Titel: |
|
|
Du brauchst dafür 2 Images in Bildschirmgröße: Eins mit dem Hintergrundbild und ein zweites mit den Hindernissen, in dem alles, was nicht Hindernis ist, Transparentfarbe (RGB(255,0,255)) hat. Diese schreibst du (in dieser Reihenfolge) mit Code: | PUT (0, 0), <Hintergrund>, PSET
PUT (0, 0), <Hindernisse>, TRANS
| auf den Bildschirm.
Zur Kollisionsprüfung vergleichst du den Ausschnitt des Hindernisimages, den das Sprite bedeckt, Pixel für Pixel mit dem Sprite. Wenn keines der beiden Pixel die Transparenzfarbe hat, liegt eine Kollision vor.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 14.06.2020, 05:26 Titel: |
|
|
Für das pixelweise Testen bietet sich die CUSTOM - Funktion von PUT an. Ich hab da mal was zusammengebastelt: Code: | #Include "fbgfx.bi"
Const As Integer spriteGroesse = 42
Const As ULong colorTrans = RGB(255,0,255), _
colorSprite = RGB(250,200,200), _
colorHindernis = RGB(120,120,180)
Dim As String datum
Dim As ULong breite, hoehe, spriteX, spriteY
Dim As Boolean kollision
Declare Function checkKollision(src As UInteger, dst As UInteger, parameter As Any Ptr) As UInteger
ScreenRes 760,720,32,2
ScreenSet 1,0
ScreenInfo breite, hoehe
Dim As FB.Image Ptr sprite = ImageCreate(spriteGroesse, spriteGroesse, colorTrans), _
hindernis = ImageCreate(breite, breite, colorTrans)
For y As Integer = 0 To 41 'for each row
Read datum
For x As Integer = 0 To 41 'for each column
Select Case datum[x]
Case Asc(".") 'transparent
PSet sprite,(x,y),colorTrans
Case Asc("#") 'black
PSet sprite,(x,y),RGB(0,0,0)
Case Asc("*") 'piece's colour
PSet sprite, (x,y), colorSprite
End Select
Next x
Next y
Line hindernis, (100, 100) - (200, 200), colorHindernis, BF
Line hindernis, (400, 100) - (500, 500), colorHindernis, BF
Circle hindernis, (300, 300), 50, colorHindernis,,,, F
spriteX = 280
spriteY = 150
Do
Cls
Select Case InKey
Case Chr(255, 72) 'pfeil nach oben
If spriteY > 0 Then
spriteY -= 1
EndIf
Case Chr(255, 80) 'pfeil nach unten
If spriteY < hoehe - spriteGroesse Then
spriteY += 1
EndIf
Case Chr(255, 75) 'pfeil nach links
If spriteX > 0 Then
spriteX -= 1
EndIf
Case Chr(255, 77) 'pfeil nach rechts
If spriteX < breite - spriteGroesse Then
spriteX += 1
EndIf
Case Chr(27), " " 'esc
Exit Do
End Select
Print "x = "; spriteX, "y = "; spriteY
Put (0, 0), hindernis, Trans 'hindernis(se) auf Bildschirm schreiben
'Put (spriteX, spriteY), sprite, Trans 'sprite auf bildschirm schreiben
Put (spriteX, spriteY), sprite 'zur veranschaulichung mit sichtbarer transparenzfarbe
kollision = false
Put sprite, (0, 0), _
hindernis, (spriteX, spriteY) - (spriteX + spriteGroesse - 1, spriteY + spriteGroesse - 1), _
custom, @checkKollision, @kollision 'auf kollision testen
Print
Print "Kollision = "; kollision
ScreenCopy
Sleep 1
Loop
ImageDestroy sprite
ImageDestroy hindernis
Function checkKollision(src As UInteger, dst As UInteger, parameter As Any Ptr) As UInteger
If src <> colorTrans AndAlso dst <> colorTrans Then
*Cast(boolean Ptr, parameter) = *Cast(boolean Ptr, parameter) Or TRUE 'kollision
EndIf
Return dst
End Function
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data "....................####.................."
Data "...................#****#................."
Data "..................#******#................"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "..................#******#................"
Data "...................#****#................."
Data "...................######................."
Data "..................#******#................"
Data "................##********##.............."
Data "...............#************#............."
Data "..............#**************#............"
Data "..............################............"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "................#**********#.............."
Data "................#**********#.............."
Data "...............#************#............."
Data "..............#**************#............"
Data ".............#****************#..........."
Data "............#******************#.........."
Data "............#******************#.........."
Data "............####################.........."
Data "...........#********************#........."
Data "...........#********************#........."
Data "...........######################........."
Data ".........................................."
Data ".........................................."
Data ".........................................."
|
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 14.06.2020, 10:27 Titel: |
|
|
Oha - das ist eine Art des Einsatzes von CUSTOM, an den ich bisher noch gar nie gedacht habe. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
ALWIM
Anmeldungsdatum: 08.08.2006 Beiträge: 1037 Wohnort: Niederbayern
|
Verfasst am: 14.06.2020, 11:07 Titel: |
|
|
Wofür sind die beiden Variablen "src" und "dst" in der Funktion CheckKollision? _________________ SHELL SHUTDOWN -s -t 05 |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 14.06.2020, 13:47 Titel: |
|
|
src ist der Pixelwert in der Quelle (also dem Bild, das du PUTten willst) und dest der Pixelwert des Zieles (also das, was zuvor an der Stelle schon auf dem Bildschirm war). Diese Werte werden Pixel für Pixel automatisch bestimmt. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
ALWIM
Anmeldungsdatum: 08.08.2006 Beiträge: 1037 Wohnort: Niederbayern
|
Verfasst am: 14.06.2020, 15:13 Titel: |
|
|
nemored hat Folgendes geschrieben: | src ist der Pixelwert in der Quelle (also dem Bild, das du PUTten willst) und dest der Pixelwert des Zieles (also das, was zuvor an der Stelle schon auf dem Bildschirm war). Diese Werte werden Pixel für Pixel automatisch bestimmt. | Vielen herzlichen Dank für die Hilfe! Klappt super!!! Gerade mit einer eigener Bilddatei getestet... Bin Begeistert.
Kollisionserkennung funktioniert!
Edit: Die Lösung von grindstone, kannte ich auch noch nicht. _________________ SHELL SHUTDOWN -s -t 05 |
|
Nach oben |
|
|
ALWIM
Anmeldungsdatum: 08.08.2006 Beiträge: 1037 Wohnort: Niederbayern
|
Verfasst am: 14.06.2020, 17:19 Titel: |
|
|
Wie schaffe ich es, dass die Figur genau vorm Hindernis stehen bleibt und ich wieder weg komme?
Wenn ich den Wert Kollision mit abfrage, komme ich von dem Punkt nicht mehr weg, weil der immer noch auf dem Hindernis drauf ist bzw. Kollision erkennt! Wenn ich die Position in X um +2 mache, dann zeichnet der mir das Hindernis einfach in X um ein paar Werte nach links oder rechts. _________________ SHELL SHUTDOWN -s -t 05 |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 14.06.2020, 20:31 Titel: |
|
|
Wenn du dich bewegst, überprüfst du anschließend die Kollision. Ist sie TRUE, dann musst du die Bewegung wieder rückgängig machen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
ALWIM
Anmeldungsdatum: 08.08.2006 Beiträge: 1037 Wohnort: Niederbayern
|
Verfasst am: 14.06.2020, 20:59 Titel: |
|
|
nemored hat Folgendes geschrieben: | Wenn du dich bewegst, überprüfst du anschließend die Kollision. Ist sie TRUE, dann musst du die Bewegung wieder rückgängig machen. | Genau das funktioniert nicht! Der geht auf einmal in die falsche Richtung bei einem Tastendruck oder zeigt die Grafik da an, wo sie nicht sein soll. Probiers mal mit dem geposteten Code aus:
Code: | #Include "fbgfx.bi"
Const As Integer spriteGroesse = 42
Const As ULong colorTrans = RGB(255,0,255), _
colorSprite = RGB(250,200,200), _
colorHindernis = RGB(120,120,180)
Dim As String datum
Dim As ULong breite, hoehe, spriteX, spriteY
Dim SHARED AS Boolean kollision
Declare Function checkKollision(src As UInteger, dst As UInteger, parameter As Any Ptr) As UInteger
ScreenRes 760,720,32,2
ScreenSet 1,0
ScreenInfo breite, hoehe
Dim As FB.Image Ptr sprite = ImageCreate(spriteGroesse, spriteGroesse, colorTrans), _
hindernis = ImageCreate(breite, breite, colorTrans)
For y As Integer = 0 To 41 'for each row
Read datum
For x As Integer = 0 To 41 'for each column
Select Case datum[x]
Case Asc(".") 'transparent
PSet sprite,(x,y),colorTrans
Case Asc("#") 'black
PSet sprite,(x,y),RGB(0,0,0)
Case Asc("*") 'piece's colour
PSet sprite, (x,y), colorSprite
End Select
Next x
Next y
Line hindernis, (100, 100) - (200, 200), colorHindernis, BF
Line hindernis, (400, 100) - (500, 500), colorHindernis, BF
Circle hindernis, (300, 300), 50, colorHindernis,,,, F
spriteX = 280
spriteY = 150
Do
Cls
Select Case InKey
Case Chr(255, 72) 'pfeil nach oben
If spriteY > 0 THEN
IF kollision = 0 THEN spriteY -= 2
IF kollision THEN
spriteY += 2
END IF
EndIf
Case Chr(255, 80) 'pfeil nach unten
If spriteY < hoehe - spriteGroesse THEN
IF kollision = 0 THEN spriteY += 2
IF kollision THEN
spriteY -= 2
END IF
ENDIF
Case Chr(255, 75) 'pfeil nach links
If spriteX > 0 THEN
IF kollision = 0 THEN spriteX -= 2
IF kollision THEN
spriteX += 2
END IF
ENDIF
Case Chr(255, 77) 'pfeil nach rechts
If spriteX < breite - spriteGroesse THEN
IF kollision = 0 THEN spriteX += 2
IF kollision THEN
spriteX -= 2
END IF
ENDIF
Case Chr(27), " " 'esc
Exit Do
End Select
Print "x = "; spriteX, "y = "; spriteY
Put (0, 0), hindernis, Trans 'hindernis(se) auf Bildschirm schreiben
PUT (spriteX, spriteY), sprite, Trans 'sprite auf bildschirm schreiben
' PUT (spriteX, spriteY), sprite 'zur veranschaulichung mit sichtbarer transparenzfarbe
kollision = false
Put sprite, (0, 0), hindernis, (spriteX, spriteY) - (spriteX + spriteGroesse - 1, spriteY + spriteGroesse - 1), custom, @checkKollision, @kollision 'auf kollision testen
Print
Print "Kollision = "; kollision
ScreenCopy
Sleep 1
Loop
ImageDestroy sprite
ImageDestroy hindernis
Function checkKollision(src As UInteger, dst As UInteger, parameter As Any Ptr) As UInteger
If src <> colorTrans AndAlso dst <> colorTrans Then
*Cast(boolean Ptr, parameter) = *Cast(boolean Ptr, parameter) Or TRUE 'kollision
EndIf
Return dst
End Function
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data "....................####.................."
Data "...................#****#................."
Data "..................#******#................"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "..................#******#................"
Data "...................#****#................."
Data "...................######................."
Data "..................#******#................"
Data "................##********##.............."
Data "...............#************#............."
Data "..............#**************#............"
Data "..............################............"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "................#**********#.............."
Data "................#**********#.............."
Data "...............#************#............."
Data "..............#**************#............"
Data ".............#****************#..........."
Data "............#******************#.........."
Data "............#******************#.........."
Data "............####################.........."
Data "...........#********************#........."
Data "...........#********************#........."
Data "...........######################........."
Data ".........................................."
Data ".........................................."
Data ".........................................."
|
_________________ SHELL SHUTDOWN -s -t 05 |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 14.06.2020, 21:30 Titel: |
|
|
ALWIM hat Folgendes geschrieben: | Wie schaffe ich es, dass die Figur genau vorm Hindernis stehen bleibt und ich wieder weg komme? |
Ganz einfach: Auf Kollision testen, bevor du das Sprite an die neue Position setzt. Und im Falle einer Kollision (die ja eigentlich eine Überlagerung ist) die Neupositionierung unterlassen.
Ich habe den Programmschnippsel mal entsprechend erweitert und noch einen grünen Kreis als symbolisches Hintergrundbild hinzugefügt: Code: | #Include "fbgfx.bi"
Const As Integer spriteGroesse = 42
Const As ULong colorTrans = RGB(255,0,255), _
colorSprite = RGB(250,200,200), _
colorHintergrund = RGB(0,200,0), _
colorHindernis = RGB(120,120,180)
Dim As String datum
Dim As ULong breite, hoehe, spriteX, spriteY, spriteXneu, spriteYneu
Dim As Boolean kollision
Declare Function checkKollision(src As UInteger, dst As UInteger, parameter As Any Ptr) As UInteger
ScreenRes 760,720,32,2
ScreenSet 1,0
ScreenInfo breite, hoehe
Dim As FB.Image Ptr sprite = ImageCreate(spriteGroesse, spriteGroesse, colorTrans), _
hindernis = ImageCreate(breite, hoehe, colorTrans), _
hintergrund = ImageCreate(breite, hoehe, colorTrans)
For y As Integer = 0 To 41 'for each row
Read datum
For x As Integer = 0 To 41 'for each column
Select Case datum[x]
Case Asc(".") 'transparent
PSet sprite,(x,y),colorTrans
Case Asc("#") 'black
PSet sprite,(x,y),RGB(0,0,0)
Case Asc("*") 'piece's colour
PSet sprite, (x,y), colorSprite
End Select
Next x
Next y
Circle hintergrund, (350, 400), 200, colorHintergrund,,,, F
Line hindernis, (100, 100) - (200, 200), colorHindernis, BF
Line hindernis, (400, 100) - (500, 500), colorHindernis, BF
Circle hindernis, (300, 300), 50, colorHindernis,,,, F
spriteX = 280
spriteY = 150
spriteXneu = spriteX
spriteYneu = spriteY
Do
Cls
If MultiKey(72) Then 'pfeil nach oben
If spriteYneu > 0 Then
spriteYneu -= 1
EndIf
ElseIf MultiKey(80) Then 'pfeil nach unten
If spriteYneu < hoehe - spriteGroesse Then
spriteYneu += 1
EndIf
ElseIf MultiKey(75) Then 'pfeil nach links
If spriteXneu > 0 Then
spriteXneu -= 1
EndIf
ElseIf MultiKey(77) Then 'pfeil nach rechts
If spriteXneu < breite - spriteGroesse Then
spriteXneu += 1
EndIf
ElseIf MultiKey(1) Or MultiKey(57) Then'esc oder space
Exit Do
EndIf
Print "x = "; spriteX, "y = "; spriteY
Put (0, 0), hintergrund, Trans 'hintergrund auf Bildschirm schreiben
Put (0, 0), hindernis, Trans 'hindernis(se) auf Bildschirm schreiben
kollision = false
Put sprite, (0, 0), _
hindernis, (spriteXneu, spriteYneu) - (spriteXneu + spriteGroesse - 1, spriteYneu + spriteGroesse - 1), _
custom, @checkKollision, @kollision 'auf kollision testen
Print
Print "Kollision = "; kollision
If kollision Then 'alte positionswerte beibehalten
spriteXneu = spriteX
spriteYneu = spriteY
Else 'sprite auf neue position setzen
spriteX = spriteXneu
spriteY = spriteYneu
EndIf
'Put (spriteX, spriteY), sprite, Trans 'sprite auf bildschirm schreiben
Put (spriteX, spriteY), sprite 'zur veranschaulichung mit sichtbarer transparenzfarbe
ScreenCopy
Sleep 15
Loop
ImageDestroy sprite
ImageDestroy hindernis
ImageDestroy hintergrund
Function checkKollision(src As UInteger, dst As UInteger, parameter As Any Ptr) As UInteger
If src <> colorTrans AndAlso dst <> colorTrans Then
*Cast(boolean Ptr, parameter) = TRUE 'kollision
EndIf
Return dst
End Function
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data ".........................................."
Data "....................####.................."
Data "...................#****#................."
Data "..................#******#................"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "..................#******#................"
Data "...................#****#................."
Data "...................######................."
Data "..................#******#................"
Data "................##********##.............."
Data "...............#************#............."
Data "..............#**************#............"
Data "..............################............"
Data ".................#********#..............."
Data ".................#********#..............."
Data ".................#********#..............."
Data "................#**********#.............."
Data "................#**********#.............."
Data "...............#************#............."
Data "..............#**************#............"
Data ".............#****************#..........."
Data "............#******************#.........."
Data "............#******************#.........."
Data "............####################.........."
Data "...........#********************#........."
Data "...........#********************#........."
Data "...........######################........."
Data ".........................................."
Data ".........................................."
Data ".........................................."
|
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
ALWIM
Anmeldungsdatum: 08.08.2006 Beiträge: 1037 Wohnort: Niederbayern
|
Verfasst am: 15.06.2020, 21:39 Titel: |
|
|
Vielen herzlichen Dank für die Hilfe! Funktioniert bei dem geposteten Quellcode. Bei meinem Quellcode funktioniert es zwar auch, aber der Hintergrund wird noch nicht richtig angezeigt. Da muss ich noch nach der Ursache suchen. Habe das noch nicht richtig drin in meinem Programm. Aber das werde ich alleine hinkriegen... _________________ SHELL SHUTDOWN -s -t 05 |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 15.06.2020, 22:52 Titel: |
|
|
Als kleine Denkhilfe: Die Kollisionsprüfung erfolgt nur mit dem Inhalt der Bildpuffer (Images) für Hindernisse und Sprite. Was dann schließlich (danach) als sichtbares Bild auf den Bildschirm kommt, ist eine ganz andere Geschichte.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|