Problem mit SpriteCollision

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Problem mit SpriteCollision

Beitrag von Scarabol »

Hallo Leute,
ich habe versucht ein kleines Spiel zu programmieren, ähnlich wie Pokemon auf dem Gameboy, nun habe ich eine Spielfigur die sich immer in der Mitte des Bildschirms befindet und durch die Pfeiltasten schiebt man den Hintergrund bzw. die Objekte hin und her dazu noch eine kleine Gang Animation und man denkt die Figur würde tatsächlich laufen, aber nun mein Problem das Spielfeld ist in 32X32 große Felder aufgeteilt nun wollte ich eine Wand einfügen in form eines einfachen 32X32 Sprites doch die Spielfigur läuft einfach drüber hinweg. Ich habe schon einiges mit SpriteCollision() versucht aber leider ohne Erfolg, die Fígur sollte also mehr oder weniger selbstständig Hindernisse erkennen, damit ich nicht jedes überprüfen muss wenn die Figur einen Schritt gemacht hat.

Code: Alles auswählen

PlayerImage = 1
Repeat
  FlipBuffers()
  ClearScreen(0,0,0)
  ExamineKeyboard()
  
  ;Allgemeinerhintergrund erstellen ist immer vorhanden also "unter" den Objekten
  ScreenWidth = #SW
  ScreenHeight = #SH
  For x=0 To ScreenWidth Step 32
  For y=0 To ScreenHeight Step 32
  DisplayTransparentSprite(1001, x, y) ;1001=Sandhintergrund
  Next
  Next
  
    ;Objekte darstellen
  Gosub Objekte
  ;Spieler darstellen und bewegen
  Gosub MovePlayer
  
Until QuitGame = 1 Or KeyboardReleased(#PB_Key_Escape)
End

Objekte:
DisplayTransparentSprite(1002, PlayerX+32*5+16, PlayerY+32);1002 = kleine Felswand bzw. Mauer
Return

MovePlayer:
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Down)
  If PlayerImage = 1
  PlayerImage = 2
  Else
  PlayerImage = 1
  EndIf
  Delay(MovePlayerDelay)
  ExamineKeyboard();nochmalige Überprüfung zum unterscheiden zwischen gehen und drehen
  If KeyboardPushed(#PB_Key_Down)
  PlayerY-32
  EndIf

ElseIf KeyboardPushed(#PB_Key_Up)
  If PlayerImage = 6
  PlayerImage = 7
  Else
  PlayerImage = 6
  EndIf
  Delay(MovePlayerDelay)
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Up)
  PlayerY+32
  EndIf
  
ElseIf KeyboardPushed(#PB_Key_Left)
  If PlayerImage = 11
  PlayerImage = 12
  Else
  PlayerImage = 11
  EndIf
  Delay(MovePlayerDelay)
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Left)
  PlayerX+32
  EndIf
  
ElseIf KeyboardPushed(#PB_Key_Right)
  If PlayerImage = 14
  PlayerImage = 15
  Else
  PlayerImage = 14
  EndIf
  Delay(MovePlayerDelay)
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Right)
  PlayerX-32
  EndIf
EndIf

DisplayTransparentSprite(PlayerImage+100, (#SW-32)/2, (#SH-32)/2);stellt Spielerimage dar immer in der Mitte vom Screen

;ab hier kommen nur noch die Sachen für die Animation
If PlayerImage = 5
PlayerImage = 1
ElseIf PlayerImage = 4
PlayerImage = 3
Delay(MovePlayerDelay)
ElseIf PlayerImage = 2
PlayerImage = 4
ElseIf PlayerImage = 3
PlayerImage = 5
EndIf

If PlayerImage = 9
PlayerImage = 6
ElseIf PlayerImage = 8
PlayerImage = 7
Delay(MovePlayerDelay)
ElseIf PlayerImage = 2
PlayerImage = 8
ElseIf PlayerImage = 7
PlayerImage = 9
EndIf

If PlayerImage = 13
PlayerImage = 11
Delay(MovePlayerDelay)
ElseIf PlayerImage = 12
PlayerImage = 13
EndIf

If PlayerImage = 16
PlayerImage = 14
Delay(MovePlayerDelay)
ElseIf PlayerImage = 15
PlayerImage = 16
EndIf

Return
Gruß Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Dafür brauchst du keine SpriteCollision usw. Das geht viel einfacher. ;)
Mach dir ein Array vom Typ Long, meinetwegen 200 x 200 Felder (Also Zweidimensional)
Wenn du jetzt irgendwo Felder hast, die nicht begehbar sind, dann setzt du genau dieses Feld = einen vorbestimmten Wert. Etwa 0 = begehbar, 1 = Wand. Also setzt du dann im Array die Position der Wand = 1.

Jetzt musst du vor dem Bewegen der Spielfigur (bzw des Hintergrundes) nur prüfen, ob die Spielfigur mit der nächsten Bewegung auf einem solchen Feld = 1 stehen würde oder nicht. Wenn es dort stehen würde bewegst du einfach nicht, denn da soll ja ein nicht begehbares Feld sein.

Das war jetzt grob die Theorie, wenn es da noch spezielle Fragen gibt dann frag einfach nochmal nach. :wink:
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

die idee ist nicht schlecht mit dem Array, aber gehen wir mal davon aus ich hab nachher eine etwas größere Spielwelt die Sagen wir 10000*10000 32-Blöcke groß ist.
Kann man das noch in einem Array speichern?
Jetzt musst du vor dem Bewegen der Spielfigur (bzw des Hintergrundes) nur prüfen, ob die Spielfigur mit der nächsten Bewegung auf einem solchen Feld = 1 stehen würde oder nicht. Wenn es dort stehen würde bewegst du einfach nicht, denn da soll ja ein nicht begehbares Feld sein.
Genau das war meine Frage WIE? kann ich abfragen was das nächste Feld für einen Status hat?
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Also 10000 x 10000 wäre eine Spielwelt von 320000 x 320000 Pixeln. Glaubst du wirklich, eine Karte wird so groß werden? Dann musst du eben Zwischendurch Levelwechsel oder sowas machen. Bei Pokemon (weil du das oben als Beispiel nanntest) gibt's auch immer wieder Zwischenpunkte wo ein anderes Level geladen wird.

Zur Frage, wie man die Position abfragt:

Pseudocode:
Die X-Koordintate des Arrays: Abrunden(Held_pixelposition_x / 32)
Die Y-Koordintate des Arrays: Abrunden(Held_pixelposition_y / 32)

Also wenn die Karte oben links beginnt und der Held auf 500 x 400 Pixel steht, dann ist das umgerechnet in Weltkoordinaten abgerundet(500 / 32) = 15 und (400 / 32) = 12. Demnach steht er auf dem Feld 15, 12 in deinem Array. ;)
Jetzt wenn er nachlinks gehen will, prüfst du also Feld 14, 12 auf den Wert 0 oder 1. Bei rechts eben 16, 12 usw...
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

könnte man das denn nicht mit spritecollision machen?
das erscheint mir irgendwie flexiebler und ein wenig einfacher weil soll ich etwa auch bei einer 1000*1000 Spielwelt dann über 1.000.000 mal 0 oder 1 eingeben?
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Eigentlich brauch ich ja nur eine Funktion die überprüft ob auf dem Zielfeld schon ein Objekt/Sprite ist.
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

das prinzip, das Ynnus hier meinte, ist das einer Tile-Map

normalerweise speichert man nicht 0 oder eins, sondern einfach die nummer des grafikblocks, der an der stelle erscheinen soll.
auch ein freies feld ist also ein grafikblock, eben gras oder sand oder so.

davon kann man auch ganz einfach ableiten, ob der durchgängig ist oder nicht.

letztendlich wirst du so oder so die komplette karte vorher erstellen müssen,
oder du schreibst dir einen algorythmus, der dir ein labyrinth erstellt.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten