Page 1 of 1

Need help with collision {SOLVED by IceSoft ]

Posted: Fri Jul 11, 2008 3:46 am
by Rook Zimbabwe
OK I am trying to read a list to check for sprite collisions. Having problems!

Code: Select all

; replaced by Ice-Softs code
Images are in BMP format and are:

http://www.bluemesapc.com/Downloads/game1.zip

:D

Posted: Fri Jul 11, 2008 4:43 am
by byo
Hi, Rook.

The example is missing cursor0.bmp. :wink:

Kind regards,
byo

Posted: Fri Jul 11, 2008 6:01 am
by IceSoft
Try this one:

Code: Select all

; German forum: http://www.purebasic.fr/german/archive/viewtopic.php?t=1518&start=10 
; Author: ChaOsKid (updated for PB4.00 by blbltheworm) 
; Date: 07. July 2003 
; modified by Rook Zimbabwe (Ralph Dunn) 7 JULY 2008 (that is a weird coincidence!) 
; english by RZ as well (99%) 


; Pressing left mousebutton fires a shot in the direction of the mouse cursor 
Enumeration 
    #Head 
    #Body 
    #Bullet 
    #Cursor 
    #Target 
EndEnumeration 

Structure Player 
  x.f 
  y.f 
  hSIZE.l 
  Speedo.l 
  TrickSpeedo.l 
  Angle.l 
  GoalAngle.l 
EndStructure 

Structure Projectile 
  x.f 
  y.f 
  SpeedoX.f 
  SpeedoY.f 
  Angle.l 
  GoalAngle.l 
  Scalar.l 
  Dimmer.l 
EndStructure 

Global NewList Projectile.Projectile() 

Procedure.l gATan(a.l, b.l) 
  Angle.l = Int(ATan(a/b)*57.2957795) 
  If b < 0 
    Angle + 180 
  EndIf 
  If Angle < 0 : Angle + 360 : EndIf 
  If Angle > 359 : Angle - 360 : EndIf 
  ProcedureReturn Angle 
EndProcedure 

Procedure.f gSin(Angle.l) 
   ; Eingabe: Angle ( 0 - 360 ) 
   ; Ausgabe: Sine with Angle 
   ProcedureReturn Sin(Angle*0.01745329) 
EndProcedure 

Procedure.f gCos(Angle.l) 
   ; Entry Angle ( 0 - 360 ) 
   ; Output: Cosine with Angle 
   ProcedureReturn Cos(Angle*0.01745329) 
EndProcedure 

Procedure NewBullet(x.f, y.f, SpeedoX.f, SpeedoY.f) 
  AddElement(Projectile()) 
  Projectile()\x = x 
  Projectile()\y = y 
  Projectile()\SpeedoX = SpeedoX 
  Projectile()\SpeedoY = SpeedoY 
  Projectile()\Scalar = 5 
EndProcedure 

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 
  MessageRequester("Error", "DirectX 7 Fail!", 0) 
  End 
EndIf 

wide = 800 
High = 600 

If OpenScreen ( wide, High,32,"Standard") = 0 
  MessageRequester("Error", "No screen could be Initialized...", 0) 
  End 
EndIf 

If InitSprite3D() = 0 
  MessageRequester("DirectX fail !", "Cannot open DirectX...", #PB_MessageRequester_Ok) 
  End 
EndIf 

LoadSprite(1011, "BLIP\body1.bmp",#PB_Sprite_Texture) 

LoadSprite(1012, "BLIP\head1.bmp",#PB_Sprite_Texture) 

LoadSprite(1013, "BLIP\blip00.bmp",#PB_Sprite_Texture) 

Sprite3DQuality(#PB_Sprite3D_BilinearFiltering) 

CreateSprite3D(#Head, 1011) 
CreateSprite3D(#Body, 1012) 
CreateSprite3D(#Bullet, 1013) 

LoadSprite(#Target, "BLIP\blip11.bmp",#PB_Sprite_Memory) 

LoadSprite(#Cursor, "BLIP\cursor0.bmp",#PB_Sprite_Memory) 

Player1.Player 
Player1\hSIZE = 16 ; was 16 
Player1\x = wide/2 - Player1\hSIZE 
Player1\y = High/2 - Player1\hSIZE 
Player1\Speedo = 2 ; was 2 
Player1\TrickSpeedo = 2 ; was 2 
Player1\Angle = 0 ; was 270 


Maus.Point 

targetflag = 1 

Repeat 
ClearScreen(RGB(0,0,0)) 

  ExamineMouse() 
  ExamineKeyboard() 

  Maus\x = MouseX() - 16 
  Maus\y = MouseY() - 16 
  a.l = Maus\y - Player1\y 
  b.l = Maus\x - Player1\x 
  Player1\GoalAngle = gATan(a, b) 
  
  If KeyboardPushed(#PB_Key_Left) Or KeyboardPushed(#PB_Key_A) 
    Player1\Angle - Player1\TrickSpeedo 
  EndIf 
  If KeyboardPushed(#PB_Key_Right) Or KeyboardPushed(#PB_Key_D) 
    Player1\Angle + Player1\TrickSpeedo 
  EndIf 
  ; 
  If KeyboardPushed(#PB_Key_Up) Or KeyboardPushed(#PB_Key_W) 
    Player1\x + (gCos(Player1\Angle) * Player1\Speedo) 
    Player1\y + (gSin(Player1\Angle) * Player1\Speedo) 
  EndIf 
  If KeyboardPushed(#PB_Key_Down) Or KeyboardPushed(#PB_Key_S) 
    Player1\x - (gCos(Player1\Angle) * Player1\Speedo) 
    Player1\y - (gSin(Player1\Angle) * Player1\Speedo) 
  EndIf 
  
  If Player1\x > wide - 32 
    Player1\x = wide - 32 
  EndIf 
  If Player1\x < 0 
    Player1\x = 0 
  EndIf 
  If Player1\y > High - 32 
    Player1\y = High - 32 
  EndIf 
  If Player1\y < 0 
    Player1\y = 0 
  EndIf 
  
Start3D() 

  If MouseButton(1) 

    If Delaytime < 1 
      Delaytime = 1 ; was 10 THIS IS HOW FAST YOU FIRE 
      Speedo.l = 8 
      Lifetime.l = 8 ; was 33 
      SpeedoX.f = gCos(Player1\GoalAngle) 
      SpeedoY.f = gSin(Player1\GoalAngle) 
      
    NewBullet(Player1\x + Player1\hSIZE + SpeedoX * Lifetime, Player1\y + Player1\hSIZE + SpeedoY * Lifetime, SpeedoX * Speedo, SpeedoY * Speedo) 
    DisplaySprite3D(#Bullet, Int(Player1\x), Int(Player1\y) ) 
    
    EndIf 

  If Delaytime > 0 
    Delaytime - 1 
  EndIf 
EndIf 

If targetflag = 1 
 DisplayTransparentSprite(#Target, 400,100) 
EndIf 

    RotateSprite3D(#Head, Player1\Angle, 0) 
    DisplaySprite3D(#Head, Int(Player1\x), Int(Player1\y),200) 
    RotateSprite3D(#Body, Player1\GoalAngle, 0) 
    DisplaySprite3D(#Body, Int(Player1\x), Int(Player1\y)) ;, 80) ; was 20 

    ResetList(Projectile()) 
    While NextElement(Projectile()) 
      If Projectile()\x < 0 Or Projectile()\y < 0 Or Projectile()\x > wide Or Projectile()\y > High Or Projectile()\Dimmer < - 254 
        DeleteElement(Projectile()) 
      Else 
        Projectile()\x + Projectile()\SpeedoX 
        Projectile()\y + Projectile()\SpeedoY 
        Projectile()\Scalar + 1 ; size to increase by 1 to 10 but 10 is HUGE 
        Projectile()\Dimmer - 4 ; rate of decay... 10 fast 1 slow (3 to 7 is good for fire BALANCED by scalar!) 
        Projectile()\Angle + 10 ; rotation try 3, 8, 12 and 48 
        ZoomSprite3D(#Bullet, Projectile()\Scalar, Projectile()\Scalar) 
        RotateSprite3D(#Bullet, Int(Projectile()\Angle), 0) 
        DisplaySprite3D(#Bullet, Int(Projectile()\x), Int(Projectile()\y) , Int(Projectile()\Dimmer)) 
        EndIf 
    Wend 
    ; *************************************************************************************** 
    ; check for collision 

   ; *************************************************************************************** 
     ResetList(Projectile()) 
     While NextElement(Projectile()) 
         If Projectile()\x > 0 Or Projectile()\y > 0 Or Projectile()\x < wide Or Projectile()\y < High 
                If SpriteCollision(1013, Projectile()\x,Projectile()\y, #Target, 400,100) 
                    targetflag = 0 
                EndIf 
            EndIf 
     Wend 
 Stop3D() 

  
 DisplayTransparentSprite(#Cursor, Maus\x, Maus\y) 
  
  FlipBuffers() 
    
  If KeyboardPushed(#PB_Key_Escape) 
    Quit = 1 
  EndIf 

  Delay(3) 
Until Quit 

Posted: Fri Jul 11, 2008 2:36 pm
by Rook Zimbabwe
The example is missing cursor0.bmp. ::Wink::

ACK!!!

here:

http://www.bluemesapc.com/Downloads/cursor0.bmp

Sorry!

Posted: Fri Jul 11, 2008 2:41 pm
by Rook Zimbabwe
If SpriteCollision(1013, Projectile()\x,Projectile()\y, #Target, 400,100)
Oh heck... I was referencing the wrong sprite!!! I had thought that was a TEXTURE only...

Silly me! :roll:

Posted: Fri Jul 11, 2008 2:46 pm
by IceSoft
Rook Zimbabwe wrote:
If SpriteCollision(1013, Projectile()\x,Projectile()\y, #Target, 400,100)
Oh heck... I was referencing the wrong sprite!!! I had thought that was a TEXTURE only...

Silly me! :roll:
You forgot this also:

Code: Select all

ResetList(Projectile()) 

Posted: Fri Jul 11, 2008 3:30 pm
by Rook Zimbabwe
OK...
But whay is it, NOW when I do the check for collision it does nothing?

Also... The bullet has turned into the target???

Code: Select all

; WORKING CODE FURTHER ON
I only modified the collision check a small bit and added a loop to build a list of targets! :?:

Posted: Fri Jul 11, 2008 4:00 pm
by Baldrick

Code: Select all

LoadSprite(bullet, "BLIP\blip00.bmp",#PB_Sprite_Texture) 
LoadSprite(enemy, "BLIP\blip11.bmp",#PB_Sprite_Texture) 
Both have a 0 value

Posted: Fri Jul 11, 2008 4:17 pm
by Rook Zimbabwe
0 value...

Hmmm, maybe because they are words and unreferenced before... HAH!!! Let me try that with numbers! Thanks!

:D

Well that fixed the sprite\image errors, now if I could just figure out why collision isn't working!

I cahnged that line to:

Code: Select all

     While NextElement(Projectile())
               If SpriteCollision(1013, Projectile()\x,Projectile()\y, 1014, target()\x, target()\y)
                   DeleteElement(target())
                   DeleteElement(Projectile())
               EndIf
     Wend
8)

Nope... no juice

Posted: Fri Jul 11, 2008 4:28 pm
by Rook Zimbabwe
I have even tried this:

Code: Select all

    ; ***************************************************************************************
    ; check for collision {{THUNK OUT BY Ice-Soft}} mangeld by Rook Zimbabwe
     ; ***************************************************************************************
     While NextElement(Projectile())
              ; If SpriteCollision(1013, Projectile()\x,Projectile()\y, 1014, target()\x, target()\y)
               If (Projectile()\x+32 >= target()\x And Projectile()\x < target()\x+32 And (Projectile()\y+32 >= target()\y) And Projectile()\y < target()\y+32)
                   DeleteElement(target())
                   DeleteElement(Projectile())
               EndIf
     Wend
Nope...

I am suspecting that it may be working but not re drawing!

Posted: Fri Jul 11, 2008 5:03 pm
by byo
I'll take a look when I'm home. Thanks.

Posted: Fri Jul 11, 2008 5:40 pm
by IceSoft
Easy:
You ceck only the LATEST target() with ALL Projectile()
So only the LATEST target can be removed if the collision is TRUE.ยด

Here the code which is working:

Code: Select all

; German forum: http://www.purebasic.fr/german/archive/viewtopic.php?t=1518&start=10 
; Author: ChaOsKid (updated for PB4.00 by blbltheworm) 
; Date: 07. July 2003 
; modified by Rook Zimbabwe (Ralph Dunn) 7 JULY 2008 (that is a weird coincidence!) 
; english by RZ as well (99%) 


; Pressing left mousebutton fires a shot in the direction of the mouse cursor 
Enumeration 
    #Head 
    #Body 
    #Bullet 
    #Cursor 
    #Target 
EndEnumeration 

Structure Player 
  x.f 
  y.f 
  hSIZE.l 
  Speedo.l 
  TrickSpeedo.l 
  Angle.l 
  GoalAngle.l 
EndStructure 

Structure Projectile 
  x.f 
  y.f 
  SpeedoX.f 
  SpeedoY.f 
  Angle.l 
  GoalAngle.l 
  Scalar.l 
  Dimmer.l 
EndStructure 

Structure target 
  x.f 
  y.f 
EndStructure 

Global NewList Projectile.Projectile() 
Global NewList Target.target() 

Procedure.l gATan(a.l, b.l) 
  Angle.l = Int(ATan(a/b)*57.2957795) 
  If b < 0 
    Angle + 180 
  EndIf 
  If Angle < 0 : Angle + 360 : EndIf 
  If Angle > 359 : Angle - 360 : EndIf 
  ProcedureReturn Angle 
EndProcedure 

Procedure.f gSin(Angle.l) 
   ; Eingabe: Angle ( 0 - 360 ) 
   ; Ausgabe: Sine with Angle 
   ProcedureReturn Sin(Angle*0.01745329) 
EndProcedure 

Procedure.f gCos(Angle.l) 
   ; Entry Angle ( 0 - 360 ) 
   ; Output: Cosine with Angle 
   ProcedureReturn Cos(Angle*0.01745329) 
EndProcedure 

Procedure NewBullet(x.f, y.f, SpeedoX.f, SpeedoY.f) 
  AddElement(Projectile()) 
  Projectile()\x = x 
  Projectile()\y = y 
  Projectile()\SpeedoX = SpeedoX 
  Projectile()\SpeedoY = SpeedoY 
  Projectile()\Scalar = 5 
EndProcedure 

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 
  MessageRequester("Error", "DirectX 7 Fail!", 0) 
  End 
EndIf 

wide = 800 
High = 600 

If OpenScreen ( wide, High,32,"Standard") = 0 
  MessageRequester("Error", "No screen could be Initialized...", 0) 
  End 
EndIf 

If InitSprite3D() = 0 
  MessageRequester("DirectX fail !", "Cannot open DirectX...", #PB_MessageRequester_Ok) 
  End 
EndIf 

LoadSprite(1011, "BLIP\body1.bmp",#PB_Sprite_Texture) 
LoadSprite(1012, "BLIP\head1.bmp",#PB_Sprite_Texture) 
LoadSprite(bullet, "BLIP\blip00.bmp",#PB_Sprite_Texture) 
LoadSprite(enemy, "BLIP\blip11.bmp",#PB_Sprite_Texture) 

Sprite3DQuality(#PB_Sprite3D_BilinearFiltering) 

CreateSprite3D(#Head, 1011) 
CreateSprite3D(#Body, 1012) 
CreateSprite3D(#Bullet, bullet) 
CreateSprite3D(#Target,enemy) 

LoadSprite(#Cursor, "BLIP\cursor0.bmp",#PB_Sprite_Memory) 

Player1.Player 
Player1\hSIZE = 16 ; was 16 
Player1\x = wide/2 - Player1\hSIZE 
Player1\y = High/2 - Player1\hSIZE 
Player1\Speedo = 2 ; was 2 
Player1\TrickSpeedo = 2 ; was 2 
Player1\Angle = 0 ; was 270 

Maus.Point 

targetflag = 1 

For y.l = 0 To 97 Step 32 
      For x.l = 0 To 800 Step 32 
         AddElement(target()) 
         target()\x = x 
         target()\y = y 
      Next 
   Next 

Repeat 
ClearScreen(RGB(0,0,0)) 

  ExamineMouse() 
  ExamineKeyboard() 

  Maus\x = MouseX() - 16 
  Maus\y = MouseY() - 16 
  a.l = Maus\y - Player1\y 
  b.l = Maus\x - Player1\x 
  Player1\GoalAngle = gATan(a, b) 
  
  If KeyboardPushed(#PB_Key_Left) Or KeyboardPushed(#PB_Key_A) 
    Player1\Angle - Player1\TrickSpeedo 
  EndIf 
  If KeyboardPushed(#PB_Key_Right) Or KeyboardPushed(#PB_Key_D) 
    Player1\Angle + Player1\TrickSpeedo 
  EndIf 
  ; 
  If KeyboardPushed(#PB_Key_Up) Or KeyboardPushed(#PB_Key_W) 
    Player1\x + (gCos(Player1\Angle) * Player1\Speedo) 
    Player1\y + (gSin(Player1\Angle) * Player1\Speedo) 
  EndIf 
  If KeyboardPushed(#PB_Key_Down) Or KeyboardPushed(#PB_Key_S) 
    Player1\x - (gCos(Player1\Angle) * Player1\Speedo) 
    Player1\y - (gSin(Player1\Angle) * Player1\Speedo) 
  EndIf 
  
  If Player1\x > wide - 32 
    Player1\x = wide - 32 
  EndIf 
  If Player1\x < 0 
    Player1\x = 0 
  EndIf 
  If Player1\y > High - 32 
    Player1\y = High - 32 
  EndIf 
  If Player1\y < 0 
    Player1\y = 0 
  EndIf 
  
Start3D() 

  If MouseButton(1) 

    If Delaytime < 1 
      Delaytime = 9 ; was 10 THIS IS HOW FAST YOU FIRE 
      Speedo.l = 8 
      Lifetime.l = 8 ; was 33 
      SpeedoX.f = gCos(Player1\GoalAngle) 
      SpeedoY.f = gSin(Player1\GoalAngle) 
      
    NewBullet(Player1\x + Player1\hSIZE + SpeedoX * Lifetime, Player1\y + Player1\hSIZE + SpeedoY * Lifetime, SpeedoX * Speedo, SpeedoY * Speedo) 
    DisplaySprite3D(#Bullet, Int(Player1\x), Int(Player1\y) ) 
    
    EndIf 

  If Delaytime > 0 
    Delaytime - 1 
  EndIf 
EndIf 


    RotateSprite3D(#Head, Player1\Angle, 0) 
    DisplaySprite3D(#Head, Int(Player1\x), Int(Player1\y),200) 
    RotateSprite3D(#Body, Player1\GoalAngle, 0) 
    DisplaySprite3D(#Body, Int(Player1\x), Int(Player1\y)) ;, 80) ; was 20 

    ResetList(Projectile()) 
    While NextElement(Projectile()) 
      If Projectile()\x < 0 Or Projectile()\y < 0 Or Projectile()\x > wide Or Projectile()\y > High Or Projectile()\Dimmer < - 254 
        DeleteElement(Projectile()) 
      Else 
        Projectile()\x + Projectile()\SpeedoX 
        Projectile()\y + Projectile()\SpeedoY 
        Projectile()\Scalar + 1 ; size to increase by 1 to 10 but 10 is HUGE 
        Projectile()\Dimmer - 4 ; rate of decay... 10 fast 1 slow (3 to 7 is good for fire BALANCED by scalar!) 
        Projectile()\Angle + 10 ; rotation try 3, 8, 12 and 48 
        ZoomSprite3D(#Bullet, Projectile()\Scalar, Projectile()\Scalar) 
        RotateSprite3D(#Bullet, Int(Projectile()\Angle), 0) 
        DisplaySprite3D(#Bullet, Int(Projectile()\x), Int(Projectile()\y) , Int(Projectile()\Dimmer)) 
        EndIf 
    Wend 
    
    ResetList(target()) 
    While NextElement(target()) 
        DisplaySprite3D(#Target, Int(target()\x), Int(target()\y) ) 
    Wend 
    ; *************************************************************************************** 
    ; check for collision {{THUNK OUT BY Ice-Soft}} mangeld by Rook Zimbabwe 
     ; *************************************************************************************** 
     ResetList(Projectile()) 
     While NextElement(Projectile()) 
         If Projectile()\x > 0 Or Projectile()\y > 0 Or Projectile()\x < wide Or Projectile()\y < High
          
               ForEach(target())
                  If SpriteCollision(bullet, Projectile()\x,Projectile()\y, enemy, target()\x, target()\y) 
               
                    DeleteElement(target()) 
                    DeleteElement(Projectile()) 
                    break
                  EndIf 
                Next  
            EndIf 
     Wend 
 Stop3D() 


 DisplayTransparentSprite(#Cursor, Maus\x, Maus\y) 
  
  FlipBuffers() 
    
  If KeyboardPushed(#PB_Key_Escape) 
    Quit = 1 
  EndIf 

  Delay(3) 
Until Quit