IMages Collide funktioniert nicht unter Draw3D?

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

M0rgenstern

Betreff: IMages Collide funktioniert nicht unter Draw3D?

BeitragSo, Sep 27, 2009 21:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo...

Ich hab mal wieder ein Problem, das scheinbar an Draw3D liegt (nichts für ungut, hectic).

Also, ich wollte ne Kollisionsüberprüfung für meine Schüsse und Gegner machen (nein der Fehler aus dem anderen Thread ist noch nicht behoben, aber ich weiß ja wann er auftritt und kann früh genug die Waffe wechseln).

Aber scheinbar mag der das "If ImagesCollide" nicht mehr.
Denn er zeigt mir (mal wieder) einen MAV an.
Wenn ich Die Reihe mit If ImagesCollide auskommentiere, dann bekomme ich keinen Fehler angezeigt.

Hier mal die (wnzige) Funktion (In anderen Projekten hat das übrigens immer so geklappt).

Code: [AUSKLAPPEN]
Function PSchussKollision()

   For Schuss.TPlayerSChuss = Each TPlayerSchuss
      For Gegner.TGegnerTest = Each TGegnerTest
         If ImagesCollide(Schuss\PSImage, Schuss\PSx#, Schuss\PSy#, 0, Gegner\GTImage, Gegner\GTx#, Gegner\GTy#, 0) Then
            Delete Gegner.TGegnerTest
            Delete Schuss.TPlayerSchuss
         EndIf
      Next
      
   Next

End Function


Die Hauptschleife sieht so aus:

Code: [AUSKLAPPEN]
Repeat

   SpielerSteuerung()
   SpielerSchuss()
   SSchussBewegen()
   GegnerErstellenTest()
   GegnerBewegenTest()
   PSchussKollision()
   AllesMalen()

   

   ;Zeichen()
   
   WaitTimer(Timer)
   RenderWorld
   Clear3D()
   Flip 0
Until KeyHit(1)
End



Da ich nicht weiß, wo der Fehler liegt, hier nochmal der ganze Code:

Code: [AUSKLAPPEN]
AppTitle "Draw3D V.3.2 - LoadFont3D"
Graphics3D 1024,768,0,1
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Local Timer=CreateTimer(60)
Local Camera=CreateCamera()
CameraClsColor Camera,5,5,5

Include "Includes\Draw3D.bb"
DrawInit3D(Camera)
Origin3D(1024,768)


;_______________________________________________
Global PlayerImage=LoadImage3D("gfx\spaceship3.png", 4, 2)
Global MouseImage = loadimage3d("gfx\target.png", 2, 2)
Global GegnerTestI = loadimage3d("gfx\block3.bmp", 1, 2)
Global PistSchuss = loadimage3d("gfx\PistolenSchuss.png", 2, 2)

;++++++++++++++

Global GegnerTimer = MilliSecs()

;++++++++++++++

Global Schriftart = loadfont3d("Fonts\Cosmic1.png", 2, 2, 0)


;++++++++++++++

Type TWaffe
 Field WName$
 Field WMunition%, WMagazine%
 Field WSchussProMagazin%, WKadenz%, WDamage%, WSpeed%
End Type

Global PW_Pistole.TWaffe = WaffeErstellen("Pistole", 10, 9999, 10, 400, 17, 15)
Global PW_MP.TWaffe = WaffeErstellen("MP", 25, 10, 25, 200, 13, 19)
Global PW_Schrot.TWaffe = WaffeErstellen("Shotgun", 8, 10, 8, 550, 33, 12)
Global PW_MG.TWaffe = WaffeErstellen("MG", 50, 10, 50, 100, 24, 25)
Global PW_Laser.TWaffe = WaffeErstellen("Laser", 500, 1, 500, 1, 22, 7)
Global PW_Magnum.TWaffe = WaffeErstellen(".45er Magnum", 7, 10, 7, 530, 26, 11)

Type TGegnerTest
 Field GTx#, GTy#, GTWinkel, GTGeschw#, GTImage, GTRotatGe#, Dead, GTRotatRich
End Type

Type TPlayerSchuss
 Field PSx#, PSy#, PSWinkel, PSGeschw#, PSImage, PSDead
End Type

Type TPlayer
 Field Px#, Py#, PWinkel, PEnergie, PAltx#, PAlty#, PGeschw#, Image, Dead
 Field PGewWaffe.TWaffe, PSchuTimer, PWafKadenz
End Type

Global Spieler.TPlayer = New TPlayer
 Spieler\Px# = (20)
 Spieler\Py# = (20)
 Spieler\PWinkel = 0
 Spieler\Image = PlayerImage
 Spieler\PEnergie = 100
 Spieler\PGeschw# = 5
 Spieler\Dead = 0
 Spieler\PGewWaffe = PW_Pistole
 Spieler\PSchuTimer = MilliSecs()
;_________________________________________________



Repeat

   SpielerSteuerung()
   SpielerSchuss()
   SSchussBewegen()
   GegnerErstellenTest()
   GegnerBewegenTest()
   PSchussKollision()
   AllesMalen()

   

   ;Zeichen()
   
   WaitTimer(Timer)
   RenderWorld
   Clear3D()
   Flip 0
Until KeyHit(1)
End



;___________________________________________________
Function SpielerSteuerung()

 Spieler\PAltx# = Spieler\Px#
 Spieler\PAlty# = Spieler\Py#

 Spieler\PWinkel#=ATan2(Spieler\Px#-MouseX3D,Spieler\Py#-MouseY3D) ;Blickrichtung



 ;Geradeaus
   If KeyDown(17) Then
      Spieler\Px#=Spieler\Px#-Sin(Spieler\PWinkel)*Spieler\PGeschw#
      Spieler\Py#=Spieler\Py#-Cos(Spieler\PWinkel)*Spieler\PGeschw#
   EndIf
   
   ;Links
   If KeyDown(30) Then
      Spieler\Px#=Spieler\Px#-Sin(Spieler\PWinkel+90)*Spieler\PGeschw#
      Spieler\Py#=Spieler\Py#-Cos(Spieler\PWinkel+90)*Spieler\PGeschw#
   EndIf
   
   ;Rechts
   If KeyDown(32) Then
      Spieler\Px#=Spieler\Px#+Sin(Spieler\PWinkel+90)*Spieler\PGeschw#
      Spieler\Py#=Spieler\Py#+Cos(Spieler\PWinkel+90)*Spieler\PGeschw#
   EndIf
   
   ;Nach hinten
   If KeyDown(31) Then
      Spieler\Px#=Spieler\Px#+Sin(Spieler\PWinkel)*Spieler\PGeschw#
      Spieler\Py#=Spieler\Py#+Cos(Spieler\PWinkel)*Spieler\PGeschw#
   EndIf
   
 ;Waffenauswahl
   If KeyDown(2) Then
      Spieler\PGewWaffe = PW_Pistole
      EndIf
   
   If KeyDown(3) Then
      Spieler\PGewWaffe = PW_MP
   EndIf
   
   If KeyDown(4) Then
      Spieler\PGewWaffe = PW_Schrot
   EndIf
   
   If KeyDown(5) Then
      Spieler\PGewWaffe = PW_MG
   EndIf
   
   If KeyDown(6) Then
      Spieler\PGewWaffe = PW_Laser
   EndIf
   
   If KeyDown(7) Then
      Spieler\PGewWaffe = PW_Magnum
   EndIf   

   If Spieler\Px# >= 490 Then Spieler\Px# = Spieler\PAltx#
   If Spieler\Px# <= -490 Then Spieler\Px# = Spieler\PAltx#
   If SPieler\Py# >= 350 Then Spieler\Py# = Spieler\PAlty#
   If Spieler\Py# <= -350 Then Spieler\Py# = Spieler\PAlty#

End Function

;++++++++++++++

Function GegnerErstellenTest()

   If (GegnerTimer + Rand(1000,2000)) < MilliSecs() Then
      
      For i = 1 To 3
         Gegner.TGegnerTest = New TGegnerTest
         Gegner\GTx# = Rand(-490, 490)
         Gegner\GTy# = 355
         Gegner\GTGeschw# = Rand(1,8)
         Gegner\GTWinkel = Rand(0,360)
         Gegner\GtRotatGe = Rand(0,20)
         Gegner\GTImage = GegnerTestI
         Gegner\GTRotatRich = Rand(1,2)
         Gegner\Dead = 0
      Next
      
      GegnerTimer = MilliSecs()
   EndIf

End Function

;++++++++++++++

Function GegnerBewegenTest()

   For Gegner.TGegnerTest = Each TGegnerTest
   
      Gegner\GTy# = Gegner\GTy# - Gegner\GTGeschw#
      
      If Gegner\GTRotatRich = 1 Then ;Im Uhrzeigersinn
         Gegner\GTWinkel = Gegner\GTWinkel + Gegner\GTRotatGe
      ElseIf Gegner\GTRotatRich = 2 Then
         Gegner\GTWinkel = Gegner\GTWinkel - Gegner\GTRotatGe
      EndIf
      
      If Gegner\GTy# > 384 Then Gegner\Dead = 1
      If Gegner\Dead = 1 Then Delete Gegner.TGegnerTest
      
   Next

End Function

;++++++++++++++

Function SpielerSchuss()
   
   If ((Spieler\PSchuTimer + Spieler\PGewWaffe\WKadenz) < MilliSecs()) And Spieler\Dead <> 1 Then
      If MouseDown(1) Then
            
               

         If Spieler\PGewWaffe\WMunition <= 0 Then ;Überprüfen ob überhaupt noch eine Kugel im Lauf ist
            Spieler\PGewWaffe\WMunition = 0 ;Damit auf jeden Fall von 0 an gerechnet wird
                  
               If Spieler\PGewWaffe\WMagazine > 0 Then
                  Spieler\PGewWaffe\WMunition = Spieler\PGewWaffe\WMunition + Spieler\PGewWaffe\WSchussProMagazin ;Waffe nachladen, wenn das Magazin leer war
                  Spieler\PGewWaffe\WMagazine = Spieler\PGewWaffe\WMagazine - 1 ;Ein Magazin weniger
               EndIf
               
         ElseIf Spieler\PGewWaffe\WMunition > 0 Then
                  
            If Spieler\PGewWaffe = PW_Schrot
                   
               For i = 1 To 5 ;Schrotflinte... Damit es ne schöne Streuung gibt
                        
                  Schuss.TPlayerSchuss = New TPlayerSchuss
                        
                  Schuss\PSy# = Spieler\Py#-Cos(Spieler\PWinkel)*Schuss\PSGeschw
                  Schuss\PSx# = Spieler\Px#-Sin(Spieler\PWinkel)*Schuss\PSGeschw
                  Schuss\PSWinkel = Spieler\PWinkel+Rand(-23,23)
                  Schuss\PSImage = PistSchuss
                  SChuss\PSDead = 0
                  Schuss\PSGeschw = Spieler\PGewWaffe\WSpeed
                        

               Next
                     
               Spieler\PGewWaffe\WMunition = Spieler\PGewWaffe\WMunition - 1
               If Spieler\PGewWaffe\WMunition < 0 Then Spieler\PGewWaffe\WMunition = 0
                  
            Else
                  
               Schuss.TPlayerSchuss = New TPlayerSchuss ;Ansonsten schießen
                  
               Schuss\PSy# = Spieler\Py#-Cos(Spieler\PWinkel)*Schuss\PSGeschw
               Schuss\PSx# = Spieler\Px#-Sin(Spieler\PWinkel)*Schuss\PSGeschw
               Schuss\PSWinkel = Spieler\PWinkel
         
               Schuss\PSImage = PistSchuss
               Schuss\PSDead = 0
               Schuss\PSGeschw = Spieler\PGewWaffe\WSpeed
               Spieler\PGewWaffe\WMunition = Spieler\PGewWaffe\WMunition - 1
               If Spieler\PGewWaffe\WMunition < 0 Then Spieler\PGewWaffe\WMunition = 0 ;Nochmal extra überprüfen dass nichts unter 0 geht
            EndIf
         EndIf
         

      
      
         
         
         Schuss\PSDead = 0
         
         Spieler\PSchuTimer = MilliSecs()
      EndIf
   EndIf
         

End Function

;++++++++++++++

Function SSchussBewegen()

   For Schuss.TPlayerSchuss = Each TPlayerSchuss
   
      Schuss\PSx#=Schuss\PSx#-Sin(Schuss\PSWinkel)*Schuss\PSGeschw#
     Schuss\PSy#=Schuss\PSy#-Cos(Schuss\PSWinkel)*Schuss\PSGeschw#
      
            
      If SChuss\Psx# >= 512 Then Schuss\PSDead = 1
      If Schuss\Psx# <= -512 Then Schuss\PSDead = 1
      If Schuss\Psy# >= 384 Then Schuss\PSDead = 1
      If Schuss\Psy# <= -384 Then Schuss\PSDead = 1
      
      If Schuss\PSDead = 1 Then Delete Schuss.TPlayerSchuss
      
   Next

End Function

;++++++++++++++

Function AllesMalen()

   
   For Gegner.TGegnerTest = Each TGegnerTest
      Drawimage3D(Gegner\GTImage, Gegner\GTx#, Gegner\Gty#, 0, Gegner\GTWinkel, 1)
   Next
   
   For SChuss.TPlayerSchuss = Each TPlayerSchuss
      Drawimage3D(Schuss\PSImage, Schuss\PSx#, SChuss\PSy#, 0, SChuss\PSWinkel, 1.5)
   Next
   
   DrawImage3D(PlayerImage, Spieler\Px#, Spieler\Py#, 0, Spieler\PWinkel#, 1)
   Drawimage3d(MouseImage, MouseX3D, MouseY3D, 0, 0, 1)
   
   ColorT3D(255, 10, 10, 1)
   
   
   

   Text3D(Schriftart, (-400), 300, "Waffe: " + Spieler\PGewWaffe\Wname)
   Text3D(Schriftart, (-400), 280, "Munition: " + Spieler\PGewWaffe\WMunition + "/" + Spieler\PGewWaffe\WMagazine, 0, 0, 0)

End Function

;++++++++++++++

Function WaffeErstellen.TWaffe(name$, Munition, Magazine, SchussProMagazin, Kadenz, Damage, Speed)

   Local W.TWaffe = New TWaffe
   W\WName = name$
   W\WMunition = Munition
   W\WMagazine = Magazine
   W\WSchussProMagazin = SchussProMagazin
   W\WKadenz = Kadenz
   W\WDamage = Damage
   W\WSpeed = Speed
   
   Return W

End Function

Function PSchussKollision()

   For Schuss.TPlayerSChuss = Each TPlayerSchuss
      For Gegner.TGegnerTest = Each TGegnerTest
         If ImagesCollide(Schuss\PSImage, Schuss\PSx#, Schuss\PSy#, 0, Gegner\GTImage, Gegner\GTx#, Gegner\GTy#, 0) Then
            Delete Gegner.TGegnerTest
            Delete Schuss.TPlayerSchuss
         EndIf
      Next
      
   Next

End Function



Ich geh einfach mal davon aus, dass es sich nicht mit Draw3D verträgt oder so. Weil in alten Projekten in denen ich kein Draw3D nutze funktionierts genau so.

Ich verzweifle noch an diesem Spiel....

Lg, M0rgenstern
 

da_poller

BeitragSo, Sep 27, 2009 21:09
Antworten mit Zitat
Benutzer-Profile anzeigen
dir is aber schon klar, das images in draw3d keine bilder sondern sprites sind und imagescollide somit nicht funktionieren KANN.???

M0rgenstern

BeitragSo, Sep 27, 2009 21:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein war mir nicht klar.
Sorry.

Wie kann ich dann in Draw3D ne Kollision abfragen?

Lg, M0rgenstern

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Sep 28, 2009 2:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab für die Draw3D2 eine ImagesOverlap3D -Funktion geschrieben. Diese überprüft nicht nicht pixelgenau, sondern eine Überlagerung von zwei Bildern oder Teilbildern.

In Anbetracht dessen, dass ImagesCollide verbugt ist und auf bestimmten Rechner überhaupt nicht funktioniert oder das Programm einfach mit einem MAV abbricht, stellt die von mir erstellte Funktion nichtmal einen Nachteil gegenüber von BlitzBasic 2D dar, da ein verbugter Befehl im grunde nutzlos ist.

Falls du das so gebrauchen kannst, hab ich mal hier eine an die Draw3D V.3.2 angepasste Version gepostet. Wink

- - -

Edit1: Ich bin mir grad nicht sicher welchen Status diese Funktion hat. Sollten Probleme auftreten, dann sag Bescheid, da ich zu der Zeit gerade an dieser Funktion gearbeitet hatte und ggf. bereits eine neuere Version verfügbar ist welche aber noch nicht an die V.3.2 angepasst wurde.

M0rgenstern

BeitragMo, Sep 28, 2009 19:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke.
Funktioniert prima.
Das einzige Problem ist halt, dass der Alphachanneln nicht berücksichtigt wird. Aber das fällt später bestimmt nicht auf.
Hab auch die Entfernungsprüfung aus dem anderen Thread mit eingefügt.

Lässt sich das mit dem Alphachannel irgendwie beheben?

Danke nochmal.

Lg, M0rgenstern

Edit:

Das Problem war ja, dass Schüsse, die einen Gegner etwa gleichzeitig erreicht haben, alle angesprochen und somit auch gelöscht wurden, weil der Alphachannel nicht berücksichtigt wird.

Habe das jetzt folgendermaßen gelöst, klappt auch richtig gut, muss ich sagen:

Code: [AUSKLAPPEN]

Function PSchussKollision()

   For Schuss.TPlayerSChuss = Each TPlayerSchuss
      For Gegner.TGegnerTest = Each TGegnerTest
         If ImagesOverlap3D(Schuss\PSImage, Schuss\PSx#, Schuss\PSy#, SChuss\PSWinkel, 1.5 ,Gegner\GTImage, Gegner\GTx#, Gegner\GTy#, Gegner\GTWinkel, 1) Then
            If Gegner\Dead = 0 Then
               Gegner\Dead = 1
               Schuss\PSDead = 1
            EndIf
         EndIf
      Next
      
   Next

End Function



Lg, M0rgenstern.

Danke nochmal, Hectic.

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Sep 28, 2009 20:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit dem Alphachannel wäre dann der Unterschied zwischen ImagesOverlap und ImagesCollide. Und da das letztere auch unter 2D nicht benutzt werden sollte, steht die Draw3D nun in dieser Hinsicht dem 2D nicht mehr nach.

Ich habe mir allerdings auch schon Gedanken darüber gemacht, doch so einfach wäre es nicht, da hier dann im schlimmsten Fall alle Pixel von zwei Bildern gegeneinander geprüft werden müssen. Du kannst aber nach jeder Overlap-Kollision eine weitere Prüfung mit kleineren und transparenten Bildelementen unterziehen. Das sollte reichen.

Als allerletzte Lösung - die ich aber unsinnig finde - wäre eine Überprüfung des Alphachannels mithilfe von GetTexel3D.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

M0rgenstern

BeitragMo, Sep 28, 2009 20:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Also mit Dummy Grafiken?
Wäre ne Idee, aber so funktioniert es ja.
Ich mein, ob der SChuss jetzt 3 Millisekunden "zu früh" auftrifft oder eben nicht, das tut ja nichts zur Sache, da er ja sowieso treffen würde, in gerader Linie.

Wenns aber bei einigen Bilder zu extrem werden sollte, dann werde ich es mal testen mit den Dummy Grafiken.

Lg, M0rgenstern

hectic

Sieger des IS Talentwettbewerb 2006

BeitragMo, Sep 28, 2009 23:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein, das meine ich nicht. Due Dummygrafiken können dazu genutzt werden, den Überlappungsumpfang etwas kleiner zu machen. Dadurch würde man als Spieler eher das Gefühl des gerechten Treffens emfinden, als das eigentlich vorbei fliegende Schüsse auf einmal treffen, nur weil da ein transparenter Alphachannel von mehreren Pixel um ein Objekt sich befindet.

Werf mal einen Blick auf diese FAQ. Da sollte klar sein, wozu das gut sein soll. Kein Mensch wird ein Spiel verfluchen, wenn mal ein Pixel ungenauigkeit zwischen Kollisionen statt finden. Aber schon, wenn er getroffen wurde, obwohl ein Schuss noch Handbreit an ihm vorbei fliegt.

Edit1: Ach, ich bin ja doof, du kannst natürlich mit der Funktion einfach das Scale vom Bild auf 80% oder so stellen. Dann ergibt sich das ganze mit den Dummygrafiken von selbst.

Kommt davon, wenn man Funktionen schreibt und ausgiebig testetm aber nicht in einem echtem Projekt benutzt.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

M0rgenstern

BeitragDi, Sep 29, 2009 12:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Ah, das ist super zu wissen.
Dankeschön.

Werds heute mittag nach der Schule einbauen.

Lg, M0rgenstern

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group