Seite 1 von 2

Colisionscode streikt?!

Verfasst: 30.05.2006 20:43
von Ghost
Hi

Ich sitz grad an einen Weltraumshooter hab aber ein Problem mit den Colisionscode.

Code: Alles auswählen

...
  If SpriteCollision(1,GatlingshootI()\x,GatlingshootI()\y,2, LGJaeger()\x, LGJaeger()\y) And LGJaeger()\Shield > 0
    DeleteElement(GatlingshootI())
         ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 
    LGJaeger()\Shield - GatlingshootI()\Schildschaden
  test - GatlingshootI()\Schildschaden 
...
(edit)
      ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 
    GatlingshootI()\Schildschaden  = 50
       Wend

(edit)
Bei den Zeilen
LGJaeger()\Shield - GatlingshootI()\Schildschaden
test - GatlingshootI()\Schildschaden
zieht er nicht wie vorgeschrieben 50 ab , sondern einen zufälligen wert
über die angegebenen 50 (hab ich am Screenautput "test" gesehen)

Weiß jemand wodran das liegt ?
ich stell mal alles rein was mit den 2 Objeckten zu tun hatt .

Code: Alles auswählen



InitMovie()
InitSprite()
InitKeyboard()
InitMouse()
InitSound()

OpenScreen(1024,768,32,"name")

Global FeuerateRoketI.l 
Global MaxLGJaeger.l 
Global FeuerateGatlingshootI.l
Global erstellLGJaeger.l
Global GattlingshootIausgeruestet.l
Global GatlingshootsI.l
Global Treffer.l
Global test.l
test = 0




;STRUCTUREN


Structure GatlingshootI    
 x.l
 y.l
 speedX.l
 speedY.l 
 Feuerate.l
 Schildschaden.l
 Huellenschaden.l
EndStructure
NewList GatlingshootI.GatlingshootI()

Structure LGJaeger
  x.l                  
  y.l
  speedX.l
  speedY.l
  Armor.l
  Shield.l
 EndStructure
NewList LGJaeger.LGJaeger()                                  
 

; PROZEDUREN


Procedure AddGatlingshootI (x, y, speedX, speedY)
 AddElement (GatlingshootI())
 GatlingshootI()\x = x
GatlingshootI()\y = y
GatlingshootI()\speedX = speedX
GatlingshootI()\speedY = speedY
GatlingshootI()\Feuerate = Feuerate
GatlingshootI()\Schildschaden = Schildschaden
GatlingshootI()\Huellenschaden = Huellenschaden

EndProcedure 


Procedure AddLGJaeger(x,y,speedX,speedY)
 AddElement(LGJaeger())
 LGJaeger()\x = x
 LGJaeger()\y = y
 LGJaeger()\speedX = speedX
 LGJaeger()\speedY = speedY
 LGJaeger()\Armor =  Armor
 LGJaeger()\Shield = Shield
EndProcedure 
  
  
  
  
; MAIN LOOP  
Repeat 
ExamineMouse()
 ExamineKeyboard()
 ClearScreen(0,255,0) 


  If FeuerateGatlingshootI > 0 
  FeuerateGatlingshootI - 1       
 EndIf 
 


; ADD'S      
     
 If MaxLGJaeger < 40 And erstellLGJaeger <=0
 
 AddLGJaeger(1000,Random(600),-2,0)
 erstellLGJaeger + 20
 LGJaeger()\Armor = 100
 LGJaeger()\Shield = 200
 MaxLGJaeger + 1
 EndIf 

  If erstellLGJaeger > 0
 erstellLGJaeger - 1
 EndIf 

 
 If MaxSpieler = 0 
 AddSpieler(400,400,2,2)
 MaxSpieler + 1
 EndIf 
 
 
 
 ;collisionen
 
 
   ResetList(LGJaeger()) 
While NextElement(LGJaeger()) 

  ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 

 If SpriteCollision(1,GatlingshootI()\x,GatlingshootI()\y,2, LGJaeger()\x, LGJaeger()\y) And LGJaeger()\Shield <= 0 
    DeleteElement(GatlingshootI())
    ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 
    LGJaeger()\Armor -  GatlingshootI()\Huellenschaden / (GatlingshootsI / 2 )

   Wend 
GatlingshootsI - 1
Treffer + 1
   EndIf 
 Wend 
      Wend 

    
                 
       ResetList(LGJaeger()) 
While NextElement(LGJaeger()) 

  ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 

 If SpriteCollision(1,GatlingshootI()\x,GatlingshootI()\y,2, LGJaeger()\x, LGJaeger()\y) And LGJaeger()\Shield > 0
    DeleteElement(GatlingshootI())
         ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 
    LGJaeger()\Shield - GatlingshootI()\Schildschaden
  test - GatlingshootI()\Schildschaden 

 Wend
 GatlingshootsI - 1
 Treffer + 1
    EndIf 

 Wend
 Wend 
 
       
      ;STRUCKTUREIGENSCHAFTEN
    
    
      ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 
    If      GatlingshootI()\x > 1024   : DeleteElement(GatlingshootI()):GatlingshootsI - 1
    ElseIf GatlingshootI()\x < 0     : DeleteElement(GatlingshootI()):GatlingshootsI - 1
    ElseIf GatlingshootI()\y >786   : DeleteElement(GatlingshootI()):GatlingshootsI - 1
    ElseIf GatlingshootI()\y < 0     : DeleteElement(GatlingshootI()):GatlingshootsI - 1
    EndIf
         Wend
      ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 

    GatlingshootI()\Huellenschaden = 50
    GatlingshootI()\Schildschaden  = 50
       Wend
   
   
   

; STEUERUNG

ResetList(Spieler())
While NextElement(Spieler()) 
  DisplayTransparentSprite(0,Spieler()\x, Spieler()\y) 
  If KeyboardPushed(#PB_key_Right)
  Spieler()\x + Spieler()\speedX
  EndIf 
  If KeyboardPushed(#PB_key_Left)
  Spieler()\x - Spieler()\speedX
  EndIf 
  If KeyboardPushed(#PB_key_Down)
  Spieler()\y + Spieler()\speedY
  EndIf 
  If KeyboardPushed(#PB_key_Up)
  Spieler()\y - Spieler()\speedY
  EndIf 
  If KeyboardPushed (#PB_key_LeftControl) And  FeuerateGatlingshootI  = 0
     AddGatlingshootI(Spieler()\x+25, Spieler()\y -2, 7, 0)   
     FeuerateGatlingshootI = 5
     GatlingshootsI + 1
  


   AddGatlingshootI(Spieler()\x, Spieler()\y+19, 7, 0)   
     FeuerateGatlingshootI = 5
     GatlingshootsI + 1
     EndIf
  Wend 
    
      
  ResetList(LGJaeger()) 
While NextElement(LGJaeger()) 
    If      LGJaeger()\x > 1200  : DeleteElement(LGJaeger()):MaxLGJaeger-1
    ElseIf LGJaeger()\x < 0     : DeleteElement(LGJaeger()):MaxLGJaeger-1
    ElseIf LGJaeger()\y > 600   : DeleteElement(LGJaeger()):MaxLGJaeger-1
    ElseIf LGJaeger()\y < 0     : DeleteElement(LGJaeger()):MaxLGJaeger-1
    ElseIf LGJaeger()\Armor < 1 : DeleteElement(LGJaeger()):MaxLGJaeger-1      
    EndIf
    
    Wend 
    
    
    
;BILDER
    ResetList(GatlingshootI()) 
While NextElement(GatlingshootI()) 
    DisplayTransparentSprite(3, GatlingshootI()\x, GatlingshootI()\y)   
    GatlingshootI()\x + GatlingshootI()\speedX
    GatlingshootI()\y + GatlingshootI()\speedY
  Wend 
    

 



ResetList(LGJaeger())
While NextElement(LGJaeger()) 
    DisplayTransparentSprite(2,LGJaeger()\x, LGJaeger()\y)   
  LGJaeger()\x + LGJaeger()\speedX
  LGJaeger()\y + LGJaeger()\speedY
  Wend 



  
 StartDrawing(ScreenOutput()) 
 DrawingMode(1)               
 Locate(0,0)                 
 FrontColor(0,0,255)          
 DrawText("Punkte:" + Str(test )) 
StopDrawing ()
    
FlipBuffers()
Until KeyboardPushed(1):End  


Verfasst: 31.05.2006 08:41
von Kaeru Gaman
es geht ja wohl um diesen abschnitt.

Code: Alles auswählen

ResetList(LGJaeger()) 
While NextElement(LGJaeger()) 

    ResetList(GatlingshootI()) 
    While NextElement(GatlingshootI()) 

    If SpriteCollision(1,GatlingshootI()\x,GatlingshootI()\y,2, LGJaeger()\x, LGJaeger()\y) And LGJaeger()\Shield > 0 
        DeleteElement(GatlingshootI()) 
        ResetList(GatlingshootI()) 
        While NextElement(GatlingshootI()) 
            LGJaeger()\Shield - GatlingshootI()\Schildschaden 
            test - GatlingshootI()\Schildschaden 
        Wend 
        GatlingshootsI - 1 
        Treffer + 1 
    EndIf 
    Wend 
Wend 
die innerste schleife ist unfug.

im falle einer collision löscht du den richtigen schuss, aber dann ziehst du für alle danach verbleibenden schüsse shield ab.

nimm die innerste schleife komplett raus auch ihr resetlist,
und zieh die shieldpoints direkt VOR dem deleten des betreffenden schusses ab.

was macht die variable GatlingshootsI ?
interner Zähler? müsste so gehen, treffer und test auch...

Verfasst: 31.05.2006 10:54
von Ghost
ok danke funktioniert

Ja GattlingsshootsI war ein Zähler ich dachte er zieht den angegebenen Wert mal der Anzahl der schüsse ab
Da wusste ich noch nicht das er den angegebenen wert (50) durch ein zufälligen ersetzt .

naja danke jedenfalls :)

Verfasst: 31.05.2006 18:01
von AND51
Hallo!

Ich habe zu den Kolisionsabfragen auch mal eine Frage: Warum muss man z. B. bei SpriteCollision() die x und y-Parameter beider Sprites angeben? Ist doch egal, Hauptsache, die Bilder kollidieren, egal, wie deren Position ist, oder wofür sollen diese Angaben sein?

Verfasst: 31.05.2006 18:07
von Alves
kann man da nicht #PB_Any einsetzen?

Sonst wär es ein bisschen doof.

Verfasst: 31.05.2006 18:32
von DarkDragon
AND51 hat geschrieben:Hallo!

Ich habe zu den Kolisionsabfragen auch mal eine Frage: Warum muss man z. B. bei SpriteCollision() die x und y-Parameter beider Sprites angeben? Ist doch egal, Hauptsache, die Bilder kollidieren, egal, wie deren Position ist, oder wofür sollen diese Angaben sein?
Hä?! Du verstehst das SpriteSystem nicht richtig:

Die Sprites, die Angezeigt werden, werden in ihren Koordinaten nirgenwo festgehalten.

[EDIT]

Dann müsstest du ja nur SpriteCollision(#Sprite1, Random(10000), Random(10000), #Sprite2, Random(10000), , Random(10000)) machen, wenn du es so für logisch empfindest.

Verfasst: 31.05.2006 18:50
von AND51
Du hast Recht, ich versteh das nicht.

Momantan ist SpriteCollision(#Sprite, 0, 0, #Sprite2, 0, 0) für mich dasselbe, wie SpriteCollision(#Sprite, Random(1000), Random(1000), #Sprite2, Random(1000), Random(1000)).

Also wie gesagt, wofür sind die Parameter x1, x2, y1, y2 bei

Code: Alles auswählen

SpriteCollision(#Sprite, x1, y1, #Sprite2, x2, y2)
?

Und warum setzt man da häufig die x- und y-Koord's der jeweiligen Sprites ein, statt "irgendwelche" Zahlen? Ihr müsst auch wissen, dass ich mich das erste mal so richtig mit Sprites beschäftige, seit der Thread über Udos Tut aufgetaucht ist; davor habe ich eher GUIs programmiert.

Verfasst: 31.05.2006 23:38
von Kaeru Gaman
wie DD schon sagte, die koordinaten der sprites sind nirgendwo festgehalten.

ein sprite ist kein objekt, sondern ne art brush, ein pinsel, mit dem du pixel auf den screen malst.

du kannst sprite nummer 42 auch 16 mal auf den screen pinnen, das ist völlig egal.

deswegen ist dieses sprite-collision auch nur für leute, die ihre koordinaten-kollisionen nicht selber ausrechnen können...

Verfasst: 31.05.2006 23:46
von AND51
Es tut mir echt leid, ich treibe euch in den Wahnsinn, aber ich verstehe das immer noch nicht. :oops: :( :lamer:

Aber das da ist schon mal ein guter Ansatz: Manchmal brauch ich es nur mit anderen Worten erklärt.

OK, also "Die koordinaten sind nirgendwo festgehalten" heißt, sie sind nirgendwo gespeichert, wie z. B. bei einem Gadget, richtig? Das kling logisch, denn bei jeem Schleifendurchlauf kann ich bei StartDrawing ja dem Sprite immer eine neue, beliebige Position verabreichen. Habe ich das schon mal verstanden?

Edit: jetzt verstehe ich!!!!!
Angenommen, ich habe 2 Sprites, beide auf Position (0|0), mit der größe 50x50. Momentan überlappen sie sich ja!
Aber wenn ich bei SpriteCollisiion() z. B. einmal die Position (111|111) und (555|555) angeben würde, gibt diese Wert keine Kollision zurück, da sie denkt, die Bilder seien zu weit auseinader, da kann ich sie in echt ruhig wie beschrieben auch überlappen lassen. Ist das korrekt?

Verfasst: 31.05.2006 23:55
von Kaeru Gaman
ja, aber immernoch zu umständlich gedacht.

die interne sprite-collision ist eigentlich nur eine koordinaten-kollision.

der befehl braucht die Spritenummer, um höhe und breite zu ermitteln.
zusammen mit der x/y-pos hat sie dann ein rechteck.
nun überprüft sie lediglich, ob sich die beiden rechtecke überlappen.

man hat weniger tipp-arbeit, aber auch weniger performance.

ich hab schon mal nen mauszeiger gemacht, wo ich nen pfeil-sprite angezeigt hab,
aber ein 1x1pix großes sprite (das garnich angezeigt wurde) auf kollision geprüft,
damit man nur mit der pfeilspitze den button aktivieren kann.

denk einfach dran:
ein sprite ist ein bunter stempel, den du auf den screen drückst.
kein objekt kein garnix, nurn bissel farbe.