Kollissionen Labyrinth

Übersicht BlitzBasic Beginners-Corner

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

jörg111

Betreff: Kollissionen Labyrinth

BeitragFr, Jan 07, 2011 19:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo, ich finde den Fehler nicht,

ich hab ein Labyrinth ähnlich Pacman in dem sich eine Spielfigur bewegt.

Wenn die Figur gegen eine Wand läuft, setze ich x bzw. y um einen Zähler zurück.
Beispiel: Taste rechts: x=x+1 . Figur läuft nach rechts.
Dann Kollision mit Wand: x=x-1. Figur wird um eine Position nach links = vorherige Position vor Kollission zurückgesetzt.
Funktioniert nur am Anfang. Aber plötzlich läuft Figur bei Taste rechts nach links und andersrum. Das gleiche oben und unten.
Zudem flackert die Figur bei Kollission, bei normaler Bewegung nicht.

Die Werte x und y hab ich nur zum Testen ausgegeben, nicht beachten
Genau so die Texte pfeil rechts und kollission


Code: [AUSKLAPPEN]


Graphics 800,600
SetBuffer BackBuffer()

Labyrinth = LoadImage("Labyrinth.bmp")
Held = LoadImage("Held.bmp")

x=220
y=100

While Not KeyHit(1)

Cls



MaskImage Labyrinth, 11,41,255
MaskImage Held,11,41,255

DrawBlock Labyrinth,0,0:DrawBlock Held,x,y



If KeyDown(205) And  ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False  Then
Text 0,0,"pfeil rechts":x=x+1


ElseIf KeyDown(203) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
Text 0,0,"pfeil links" :x=x-1


ElseIf KeyDown(200) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
Text 0,0,"pfeil hoch" : y=y-1


ElseIf KeyDown(208) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
Text 0,0,"pfeil runter" : y=y+1




ElseIf KeyDown(205) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil rechts kollission":x=x-1


ElseIf KeyDown(203) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil links kollission" :x=x+1


ElseIf KeyDown(200) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil hoch kollission" : y=y+1


ElseIf KeyDown(208) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil runter kollission" : y=y-1




EndIf

Text 200,0,x
Text 400,0,y




Flip

Wend


End



 

Toasty

BeitragFr, Jan 07, 2011 19:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich benutze immer ImagesOverlap

EDIT: Statt ImagesCollide
@AMD Phenom BE X4 2,5Ghz(Overclocked 2,61Ghz); 4GB DDR2; 512MB nVidia GeForce 8400gs; Win7 Home Premium 64bit
Lua for President!
 

Lapiz

BeitragFr, Jan 07, 2011 20:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum benutzt du MaskImage und dannach DrawBlock statt DrawImage?
Außerdem kannst du meines Wissens MaskImage schon vor der Mainloop verwenden.
 

jörg111

BeitragFr, Jan 07, 2011 21:20
Antworten mit Zitat
Benutzer-Profile anzeigen
MaskImage hab ich vor den While Befehl verschoben. -> keine Wirkung

DrawImage Held statt Drawblock -> gleicher Fehler

Drawimage Labyrinth --> Die blauen Gänge werden nicht mitgezeichnet, weil die transparente Farbe blau ist also nicht sichtbar ist.
Ansonsten auch gleicher Fehler.

Fehler tritt erst auf, wenn Kollission stattfindet, ab da kommt alles durcheinander : links statt rechts und oben statt unten und so weiter

Xeres

Moderator

BeitragFr, Jan 07, 2011 21:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Block mit der Tastensteuerung ist zwei mal vorhanden, wobei der zweite die Richtungen umkehrt - das ist unsauber und wenig verwunderlich das es verbuggt ist.
Die Kollisionsprüfung für zukünftige Positionen ausführen, und nur dann weiterbewegen, wenn dort keine Kollision stattfinden wird.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

exastion

BeitragFr, Jan 07, 2011 21:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

Wenn du die Kollision prüfst, dann prüfst du das ganze Bild.
Weil du DrawBlock benutzt, wird keine Transparenz eingezeichnet, und sobald du dich im Labyrinzh befindest, hast du eine Kollision.

Benutze DrawImage, und setze die Löschfarbe auf Lila(255,0,255)(Die Farbe wird fast nicht benutzt)
MfG exastion

Bitte verbessert mich, wenn ich was falsches schreibe.
 

primero

BeitragSa, Jan 08, 2011 0:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi

im Grund ist der Fehler recht simpel. aber zuerst mal, die befehle "Maskimage" sollten wirklich vor der schleife stehen, nicht weil sie den Fehler verursachen, sondern weil sie nur einmal benötigt werden und du sie endlos oft aufrufst.

Ok, nun zum fehler. Xeres hat es ja schon genannt.
du fragst zwei mal ab ob eine Taste gedrückt wird. beim erstenmal soll die Figur in die richtige Richtung laufen, bei der zweiten Prüfung in die falsche richtung (klar, im Falle einer Collision von der Wand weg).

eins der Probleme ist, dass du nicht genau weißt wo, also auf welcher Seite, sich die Wand befindet. d.h. du berührst die Wand links, um weg zu kommen läufst du rechts. da du derzeit aber noch mit der wand kollidierst bewegt sich der held entgegengesetzt, und zwar so lange bis du auf der anderen Seite heraus gelaufen bist.

zweites Problem ist dass der Held bei einer collision zuerst zurück läuft (ein schritt), dann aber soffort wieder einen schritt nach vorne macht und schon wieder an der Wand steht, außer man läßt im exakt richtigen Moment los, eine 50-50 Chance.

Der Ansatz war schon richtig, hochlaufen wenn nix ist, collisionsprüfung, wenn erfollgreich dann lauf einen schritt zurück. Nur startet es ja sofort wieder von Anfang an.


Lösung:
es gibt verschiedene Wege.
zum einen die Prüfung nicht in einer extra schleife abfragen also so:
Code: [AUSKLAPPEN]

If KeyDown(205) and ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
   Text 0,0,"pfeil rechts"
   x=x+1
   if ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
      Text 0,0,"pfeil rechts kollission"
      x=x-1
   endif
endif

Hier wirst du noch im selben Moment zurück gesetzt, und kannst nie an einer Position stehen bleiben auf der du collidierst.

Dann gibt es noch die möglichkeit (ist auch schneller) anstelle zwei Bilder zu prüfen einfach das Spielfeld in ein Raster zu teilen und dann auf bestimmte Felder ein kleines Bild zu zeichnen. wenn der Held nun auf die koordinaten des Bildes läuft collidiert er.


als Abschluss noch ein paar kleine Hinweise:
>> um die blaue Farbe als Hintergrund beizubehalten (oder einen Grasshintergrund oder sonstwas) zeichne doch erst ein Bild das den Hintergrund sein soll, dann das Labyrint und den Held mit drawimage. dann verschwindet auch das kleine blaue kästchen um den Helden bei einer beinahcollision.

>> Schreib jeden Befehl in eine extrazeile. wird übersichtlicher wenn du später mal was überprüfen musst.

hoffe das hilft weiter

Hubsi

BeitragSa, Jan 08, 2011 9:00
Antworten mit Zitat
Benutzer-Profile anzeigen
exastion hat Folgendes geschrieben:
Wenn du die Kollision prüfst, dann prüfst du das ganze Bild.
Weil du DrawBlock benutzt, wird keine Transparenz eingezeichnet, und sobald du dich im Labyrinzh befindest, hast du eine Kollision.

Da liegst Du einem Irrtum auf. Das Programm "kuckt" nicht auf den Bildschirm was da los ist, es wird alles errechnet. Konsequenz ist also das es völlig egal ist wie, wo oder ob überhaupt das Bild gemalt oder nicht gemalt wird. Ein Ketzer? Auf den Scheiterhaufen mit ihm? Bitte: Mr. Green
BlitzBasic: [AUSKLAPPEN]
Graphics 400,300,16,2
SetBuffer BackBuffer()
Local img,img2,timer


img=LoadImage("star.bmp")
img2=LoadImage("star.bmp")
MaskImage img,255,0,255
MaskImage img2,255,0,255

timer=CreateTimer(60)

Repeat
Cls
DrawBlock img,200,150
DrawBlock img2,MouseX(),MouseY()
If ImagesCollide(img,200,150,0,img2,MouseX(),MouseY(),0) Then
Text 10,10,"Kollision!"
EndIf
Flip 0
WaitTimer(timer)
Until KeyHit(1)
End


Die Grafik zum Code: https://www.blitzforum.de/upload/file.php?id=10124

Zudem sei angemerkt das ImagesCollide mit einigen Grafikkarten Schwierigkeiten macht, von der Benutzung würde ich also eher abraten wenn das Programm auf die Öffentlichkeit losgelassen werden soll.
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...
 

jörg111

BeitragSa, Jan 08, 2011 16:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hoffe ich hab das jetzt so richtig verstanden, wie ich es im Programm vermerkt habe.

Hätte ich else statt if (bei Tastaturabfrage) genommen, dann würde auf kollission geprüft, auch wenn die erste Bedingung nicht erfüllt wäre (wenn Taste rechts gedrückt wird und Held kollidiert nicht mit Wand). Hab ich das richtig verstanden?





Code: [AUSKLAPPEN]
;Setzen des Grafikmodus und des Buffers
Graphics 800,600
SetBuffer BackBuffer()


;Laden der Bilder
Labyrinth = LoadImage("Labyrinth.bmp")
Held = LoadImage("Held.bmp")


;Startposition des Helden
x=220   
y=100


;Setzen der Transparentfarbe blau (Gänge des Labyrinths sind blau, Wände sind schwarz)
MaskImage Labyrinth, 11,41,255
MaskImage Held,11,41,255



;Start der Hauptschleife (Programm läuft bis ESC gedrückt wird)
While Not KeyHit(1)


;Löschen des Bildschirms
Cls


;Zeichnen des Labyrinths und des Helden
DrawBlock Labyrinth,0,0:DrawImage Held,x,y


;Tastaturabfrage und Kollissionsabfrage
;Wenn Taste rechts gedrückt wird und Held kollidiert nicht mit Wand, dann geht Held 1 weiter nach rechts
;Nur wenn obige Bedingung erfüllt ist, wird folgende Abfrage getätigt: Wenn Held mit Wand kollidiert, dann geht Held wieder 1 nach links
;Das gleiche mit den anderen Richtungen
If KeyDown(205) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
Text 0,0,"pfeil rechts"
x=x+1
If ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil rechts kollission"
x=x-1
EndIf
EndIf


;Taste links
If KeyDown(203) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
Text 0,0,"pfeil links"
x=x-1
If ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil links kollission"
x=x+1
EndIf
EndIf


;Taste hoch
If KeyDown(200) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
Text 0,0,"pfeil hoch"
y=y-1
If ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil hoch kollission"
y=y+1
EndIf
EndIf


;Taste runter
If KeyDown(208) And ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = False Then
Text 0,0,"pfeil runter"
y=y+1
If ImagesCollide (Held,x,y,0,Labyrinth,0,0,0) = True Then
Text 0,0,"pfeil runter kollission"
y=y-1
EndIf
EndIf


;Textausgabe zum Testen
Text 200,0,x
Text 400,0,y


;Austauschen der Buffer zum Sichtbarmachen des Bildes
Flip


;Ende der Hauptschleife
Wend


End
 

jörg111

BeitragSa, Jan 08, 2011 22:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube hier stimmt etwas nicht. Roboter geht immer links und rechts, weil er in dem einem Moment kollidiert und in dem anderen Moment wenn er 1 nach links geht nicht mehr kollidiert, geht also immer hin und her.
Hab schon versucht wie mit dem Held IF in nur einer Schleife abfragen statt in zwei, klappte aber auch nicht. Wer weiß Hilfe? Danke im voraus.


Code: [AUSKLAPPEN]

;Zeichnen des Labyrinths und des Helden und des Roboters
DrawBlock Labyrinth,0,0:DrawImage Held,x,y:DrawImage Roboter,RoboterX,RoboterY

If ImagesCollide (Roboter,RoboterX,RoboterY,0,Labyrinth,0,0,0) = False Then
RoboterX=RoboterX+1:Text 100,100,"Roboter kollidiert nicht"


Else
RoboterX=RoboterX-1:Text 200,200,"Roboter kollidiert"
EndIf]

Xeres

Moderator

BeitragSa, Jan 08, 2011 22:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist genau das, was du eingetippt hast... was soll denn anderes passieren? Willst du den Roboter immer wenden lassen, wenn er auf eine Wand stößt? Dann brauchst du eine Variable, die du umschaltest, wenn er kollidiert, die die Bewegungsrichtung angibt.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

jörg111

BeitragSo, Jan 09, 2011 13:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie frage ich ab, in welche Richtung der Roboter gerade geht?
Wenn er nach rechts geht (RoboterX=RoboterX+1) dann müsste er bei Kollission dann ja nach links gehen, obwohl eigentlich lieber per Zufallsgenerator nach oben, unten, rechts oder links bis er wieder auf eine Wand trifft.

Bei dem Helden ist einfacher weil dort ja die Bewegungsrichtung vorgegeben ist (je nach Taste die man drückt lässt sich ja leicht abfragen in welche Richtung Held geht) Aber wie ist das beim Roboter, der sich ja von allein bewegt?

Xeres

Moderator

BeitragSo, Jan 09, 2011 13:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie gesagt: Du gibst ihm eine Variable, die seine Richtung bestimmt. Die kannst du zufällig neu setzen
a) wenn er eine Wand erreicht (Kollision) oder b) wenn eine bestimmte (zufällige) Zeitspanne um ist, siehe dazu Millisecs.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Hubsi

BeitragSo, Jan 09, 2011 13:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit einer speed-Variable. Etwa so:
BlitzBasic: [AUSKLAPPEN]
If irgendwas_trifft_ein Then
speed=speed*-1 ; Bewegungsrichtung ändern
EndIf

If speed<0 Then der_Robbi_rennt_nach_links=True
If speed>0 Then der_Robbi_rennt_nach_rechts=True
If speed=0 Then der_Robbi_rennt_garnicht


Sinngemäß auch für rauf und runter.
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...
 

jörg111

BeitragSo, Jan 09, 2011 14:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Was heisst speed=speed*-1
Ist das was anderes als ohne das * zeichen?
 

Lapiz

BeitragSo, Jan 09, 2011 14:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Das * ist nichts anderes als mal.
Also speed=speed mal -1.
 

jörg111

BeitragSo, Jan 09, 2011 14:47
Antworten mit Zitat
Benutzer-Profile anzeigen
schon klar, aber kommt da was anderes raus bei speed =speed*-1 oder speed = speed-1

wieso nicht mit rand zufallsgenerator

blitzbasic kriegt immer 0 raus (hab mir zum test variable anzeigen lassen)
 

Lapiz

BeitragSo, Jan 09, 2011 15:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn der Roboter die Wand berührt:
Code: [AUSKLAPPEN]

Roboter_x=Roboter_x+speed
If Roboter_berührt_die_Wand
speed=speed*-1;Bewegungsrichtung des Roboters wird umgedreht, damit er sich von der Wand wegbewegt
endif


Wenn du speed mit Rand ändern willst besteht ja die Gefahr, dass der Roboter weiterhin
in die selbe Richtung läuft.

Du musst speed natürlich am Anfang auch definieren sprich speed=1 Wink

Xeres

Moderator

BeitragSo, Jan 09, 2011 15:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn man einen Wert mit -1 Multipliziert, kehrt man das Vorzeichen um. Das ist was anderes (!) als 1 ab zu ziehen.
Wenn du immer 0 raus bekommst, lies dir etwas zum Thema an: SeedRnd, Rand, Rnd
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

jörg111

BeitragSo, Jan 09, 2011 16:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Und wie gehts wenn er nicht immer nur bei Kollission von rechts nach links bzw. von oben nach unten laufen soll?

Also z.b. bei Kollission an rechter Wand dann nicht nach links sondern nach oben oder unten laufen, wie macht man das?
Ich denke mit zwei Richtungsvariablen oder: RichtungX und RichtungY

Aber irgendwie bin mir nicht sicher

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group