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!
Images are in BMP format and are:
http://www.bluemesapc.com/Downloads/game1.zip

Posted: Fri Jul 11, 2008 4:43 am
by byo
Hi, Rook.
The example is missing cursor0.bmp.
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:
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???
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!
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
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