Kolision bei tileengine?

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

insaneronny

Betreff: Kolision bei tileengine?

BeitragSa, Jan 15, 2005 22:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Nach langem überlegn, habe ich mich für eine tileengine entschieden.
Ich möchte meinen Charakter aber nicht nur von tile zu tile bewegen, sondern pixelgenau seine x un y Werte verändern.

Hier der komplette Code ohne Kollision:

Code: [AUSKLAPPEN]


;| Voreinstellungen |

Graphics breite,hoehe, 16,1
SetBuffer BackBuffer()
ClsColor 0,0,0
frametimer = CreateTimer(30)
Const breite = 1024, hoehe = 768

;| Tastatur |

Const  oben = 200, unten = 208, rechts = 205, links = 203

;| Grafiken laden |

Global bg1 = LoadImage ("bg1.bmp"), bg2 = LoadImage ("bg2.bmp"), bg3 = LoadImage ("bg3.bmp"), bg4 = LoadImage ("bg4.bmp")

Global hero =LoadImage ("hero.bmp")
   MaskImage hero, 0,255,0

Global hero_x = 400, hero_y = 300



;| Map lesen / einstellen |

Global map_breite = 20, map_hoehe = 20

Dim map (map_breite,map_hoehe)

Restore mapdata
For y=0 To map_hoehe
   For x=0 To map_breite
      Read map(x,y)
   Next
Next

;| Haupschleife |

Repeat
Cls

WaitTimer (frametimer)

drawmap()
DrawImage hero,hero_x,hero_y
move_hero()

Flip

Until KeyHit (1)
End

;| Die MAP |

.mapdata
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,1,1,0,2,2,0,3,3,0,4,4,0,0,0,0,0,0,1
Data 1,0,0,1,1,0,2,2,0,3,3,0,4,4,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


Function DrawMap()
   For y = 0 To map_hoehe
      For x = 0 To map_breite
         
             If map(x,y) = 1 Then
               DrawImage bg1, x*32, y*32
         ElseIf map(x,y) = 2 Then
               DrawImage bg2, x*32, y*32
         ElseIf map(x,y) = 3 Then
               DrawImage bg3, x*32, y*32
         ElseIf map(x,y) = 4 Then
               DrawImage bg4, x*32, y*32

         EndIf
      Next
   Next
End Function

;| Die Figur bewegen |

Function move_hero()

If KeyDown(unten)  Then hero_y = hero_y + 4
If KeyDown(oben)   Then hero_y = hero_y - 4
If KeyDown(rechts) Then hero_x = hero_x + 4
If KeyDown(links)   Then hero_x = hero_x - 4


Dann habe ich versuch folgendes einzubauen:

Code: [AUSKLAPPEN]

If KeyDown(unten)  Then
   If map(hero_x, hero_y - 1) = 2 Then
       hero_y = hero_y -4 Else hero_y = hero_y + 4
   End If
End If


Das habe ich mir aber nur irgendwo abgeschaut und versteh nicht wirklich, was es überhaubt bedeutet. Jedenfalls klappt das nicht.
Sagt mir mal bitte was ich da machen soll. Aber bitte versucht es ein wenig einleuchtend zu erklären.

Danke schon mal im vorraus.

PS.:

X = "Das ist mein erster Post"

if X = "Das ist mein erster Post" then
Print " Bitte nicht als Noob beschimpfen"

Hubsi

BeitragSa, Jan 15, 2005 22:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine immer wieder (jedenfalls bei mir Very Happy ) beliebte Methode:Code: [AUSKLAPPEN]
u=map((sx(i)+16)/32,(sy(i)-2)/32,0)  ; Oben / Up
r=map((sx(i)+32)/32,(sy(i)+16)/32,0) ; Rechts / Right
d=map((sx(i)+16)/32,(sy(i)+32)/32,0) ; Unten / Down
l=map(sx(i)/32,(sy(i)+16)/32,0)      ; Links / Left
m=map((sx(i)+16)/32,(sy(i)+16)/32,0) ; Mitte / Middle
sx() bzw. sy() ist die Spielerposition, die Tiles sind 32*32 Pixel und ich geh jetzt einen trinken Very Happy
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...
 

insaneronny

BeitragSa, Jan 15, 2005 22:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Daraus werde ich nicht wirklich schlau.
Was ist denn bitteschön "i"?
Und wofür braucht man die "Mitte"?

DivineDominion

BeitragSo, Jan 16, 2005 0:43
Antworten mit Zitat
Benutzer-Profile anzeigen
https://www.blitzforum.de/viewtopic.php?t=5286

Willst aber mit den Tiles kollidieren, nicht mit ImagesOverlap oder sowas? Dann geht mein Link oben auch! Smile
christian.tietze@gmail.com - https://christiantietze.de
macOS
 

insaneronny

BeitragSo, Jan 16, 2005 1:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Crying or Very sad
Ich sitze nun schon seit Stunden an diesem Problem.
Ich habe auch schon versucht die hier aufgelisteten Lösungen in mein Programm zu integrieren. Aber ich komme einfach nicht weiter. Nichts funktioniert. Vieleicht könnte mir mal jemand seinen Lösungsvorschlag in meinen Code einbinden?
Ich hab schon mit dem Game Maker Pro (DIV2) gecoded und da ging das irgendwie einfacher.
Also wenn das hier noch einer liest. helft mir.

Crying or Very sad Embarassed Crying or Very sad

Hubsi

BeitragSo, Jan 16, 2005 10:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist auch ein kleiner Unterschied: Gamemaker und Programmiersprache Very Happy

Diese ganzen sx(i) und sy(i) musst Du schlicht und ergreifend durch Deine Variablen austauschen, also durch hero_x und hero_y. In den Variablen u, d, usw. wird dann die Nummer des Tiles gespeichert das sich rund um bzw. unter dem Spieler befindet. Du hast bleistiftsweise für Boden eine 1 und stehst gerade drauf bekommst Du in m eine 1 zurück. Rechts von Dir ist ein Felsen mit Nummer 10? Diese 10 wird in r gespeichert usw. Diese Variablen kannst Du dann auswerten. Ist rechts von mir ein Felsen (r=10) kann ich nicht weiter nach rechts laufen. Mitte brauchst Du z.B. wenn Du Powerups einbindest, oder läufst durch Wasser und willst einen Sound dazuspielen, oder oder oder... Wink

Du hast übrigens einen durchaus schönen Codestil, hab mich gleich zurechtgefunden. Wenn man das nur bei allen Anfängern sehen würde Mr. Green
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...
 

insaneronny

BeitragSo, Jan 16, 2005 12:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Shocked
Das klingt ja alles sehr logisch, nur ich schaffe es nicht das auf meinen Code umzusetzen. Entweder er kollidiert überhaupt nicht oder er stürzt ab.

Ich verstehe nicht, was ich falsch mache?!?
Über eine Ausfürlich Problemlösung (am besten in meinen Code integriert und gut erklärt) würde ich mich Tierisch freuen.

@ Hubsi:
Danke für das Kompliment mit dem Codestil.
Game Maker Pro ist übrigenz kein wirklicher maker sondern ähnlich wie BB eine auf Spiel ausgelegte Programmiersprache, mit nützlichen Tools (zB. Explosionsgenerator etc.).
Leider komplett auf Dos basierend. D.h. probleme mit win XP und mir rätzelhafte Soundprobleme.

DivineDominion

BeitragSo, Jan 16, 2005 12:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit dem Codestil stimmt allerdings Smile Davon abgesehen, dass du deine Bilder in einem animImage speichern und laden solltest - aber das kann man ja immer noch mal ändern.

Problem ist folgendes: Du hast eine Welt aus Kacheln (Tiles). Ein 3x3 Feld mit dem Helden in der Mitte ist für die Kollision interessant, also alles um ihn herum.

Nun schaust du dir ja hoffentlich mein Tutorial an und siehst wie es mit Tile-zu-Tile-Bewegung klappt. Wichtig ist für dich auch erstmal die Konstante TILESIZE. Die muss bei dir scheinbar 32 sein, weil deine tiles 32x32 sind.

Zurück zum angefangenen Problem. Dein Held steht in der Mitte von 9 Feldern und du musst alle 4 Himmelsrichtungen prüfen. Wichtig hierbei ist, dass du eben auf tile-Ebene schaltest, also nur diese Kacheln siehst, keine einzelnen Pixel. Den Helden von seiner Pixelposition wieder runterzuholen ist dabei eben ganz einfach:
HeldTileX = HeldX / TILESIZE
HeldTileY = HeldY / TILESIZE

Pixelposition 320,320 wäre dabei das Tile an der Position 10,10 in der Map. Leuchtet doch wohl ein Smile Und bei Werten wie z.b. zwischen 0 und 32 rundet BB sowieso ab, weil wir mit Integer-Werten (Ganzzahlen) rechnen und ein Integer in der Mathematik als nächstkleinere Zahl zur angegebenen Zahl definiert ist - 1.9 wäre als int eben auch 1. Aber das ist eigentlich nicht so wichtig - wichtig ist nur, dass du damit jede Pixelposition auf dem Bildschirm (oder der Map, später beim scrolling eben) wieder zurückrechnen kannst und dann sagen kannst: Aha, da, auf DEM Tile steht die Figur also!

Dann müsste es eigentlich ein Klacks sein, meinen Code (oder Hubsis eben) zu übertragen:

Code: [AUSKLAPPEN]
KollisionOben = map( PlayerY - 1, PlayerX, 2 )
KollisionRechts = map( PlayerY, PlayerX + 1, 2 )
KollisionUnten = map( PlayerY + 1, PlayerX, 2 )
KollisionLinks = map( PlayerY, PlayerX - 1, 2 )


Unser "Trick" hierbei ist, dass wir mehrere Ebenen nutzen (3. Wert im map-Array). Ebene 0 ist für Boden und so zeug, Ebene 1 um was drüber zu malen und Ebene 2 enthält nur 0 oder 1 bzw false oder true. Da steht nämlich, ob man mit dem Tile kollidiert.
Das hast du jetzt noch nicht. Das heißt du musst es umbauen.
Code: [AUSKLAPPEN]

;Kollision rechts?
If map( HeldTileX + 1, HeldTileY ) = 2 Then KollisionRechts = true
;...


Und dann fragst du beim Bewegen kurzum einfach ob KollisionRechts false ist. Wenn ja, Position verändern. Wenn nicht tust du einfach nichts. Der Weg ist im Übrigen auch schöner als wenn du einfach blind die Position veränderst und danach zurück-korrigierst wenn ne Kollision stattfindet.


Viel Spaß Smile


EDIT:
Habs in mein tutorial auch mal reingeschrieben!
christian.tietze@gmail.com - https://christiantietze.de
macOS
  • Zuletzt bearbeitet von DivineDominion am So, Jan 16, 2005 12:57, insgesamt einmal bearbeitet

Hubsi

BeitragSo, Jan 16, 2005 12:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Geht ganz einfach (so wird das Prinzip sicher auch schnell klar):Code: [AUSKLAPPEN]
Function move_hero()

u=map((sx(i)+16)/32,(sy(i)-2)/32,0)  ; Oben / Up
r=map((sx(i)+32)/32,(sy(i)+16)/32,0) ; Rechts / Right
d=map((sx(i)+16)/32,(sy(i)+32)/32,0) ; Unten / Down
l=map(sx(i)/32,(sy(i)+16)/32,0)      ; Links / Left
m=map((sx(i)+16)/32,(sy(i)+16)/32,0) ; Mitte / Middle

If KeyDown(unten) and d=0 Then hero_y = hero_y + 4
If KeyDown(oben) and u=0  Then hero_y = hero_y - 4
If KeyDown(rechts) and r=0 Then hero_x = hero_x + 4
If KeyDown(links) and l=0  Then hero_x = hero_x - 4
Statt diesem =0 würd ich Bereiche festlegen, also z.B. Tilenummern 1-50 sind Bodentiles, 51-99 Powerups und Waffen etc. und größer 100 sind nicht begehbar. So ist eine gewisse Abwechslung sehr viel leichter zu erhalten Wink

Edit: Mal wieder zu lahm Razz
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...
 

insaneronny

BeitragSo, Jan 16, 2005 14:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Och menno!

1. es ist wirklich sehr langsam
2. es ist auch sehr ungenau!

Kann mir mal bitte jemand einen Link geben, wo man das richtig gut erklärt bekommt?
Alle die einen Link kennen, sollen ihn bitte Posten.

Der wunsch meinen Code so umzuschreiben, dass es funktionirt besteht imernoch.

Hubsi

BeitragSo, Jan 16, 2005 15:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Was bitte ist daran langsam? Die Ungenauigkeit läßt sich auch recht einfach beheben:Code: [AUSKLAPPEN]
if kolli
 temp=hero_x/32
 hero_x=temp*32
endif
if kolli and not sprung
 temp=hero_y/32
 hero_y=temp*32
endif
Wenn Dein Game zu langsam ist liegts bestimmt nicht an den paar Berechnungen. Einbinden kannst du das ja selbst, Windows unterstützt Copy&Paste. Wenn Du den Code aber nicht verstehst hilft das freilich auch nicht Very Happy
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...

DivineDominion

BeitragSo, Jan 16, 2005 18:38
Antworten mit Zitat
Benutzer-Profile anzeigen
poste mal den ganzen code o_O
christian.tietze@gmail.com - https://christiantietze.de
macOS

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group