Found time to have a bit of a play here..
I have used the IceSoft example code used above here.
For the bullets I have created a 2nd non displayed bullet of 1 x 1 pixel size which uses the projectile x,y coordinates for collisions testing.
For the sight collisions I have made a 2nd non displayed sprite with a size allowing the displayed bullets to appear to be entering the sighting cursor. I have disabled the displayed bullet zooming as this bit needs more work to get accuracy.
As I don't have a copy of your real cursor I have just created 1 in the form of a little scope sight...
Still not 100% accurate, but getting closer. ( there is a couple of points around the screen where the bullets will pass by the cursor still )
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
#enemy1
#Bullet1
#bullet2
#Cursor2
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 = 0;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, "\cursor\body1.bmp",#PB_Sprite_Texture)
LoadSprite(1012, "\cursor\head1.bmp",#PB_Sprite_Texture)
LoadSprite(#bullet1, "\cursor\blip00.bmp",#PB_Sprite_Texture)
LoadSprite(#enemy1, "\cursor\blip11.bmp",#PB_Sprite_Texture)
CreateSprite(#Cursor2,12,12) ; non displayed for sudo cursor collision testing
StartDrawing(SpriteOutput(#Cursor2))
Box(0,0,12,12,#Yellow)
StopDrawing()
CreateSprite(#Bullet2,1,1) ; non displayed for smallest possible collision testing region
StartDrawing(SpriteOutput(#Bullet2))
Box(0,0,1,1,#Red)
StopDrawing()
Sprite3DQuality(#PB_Sprite3D_BilinearFiltering)
CreateSprite3D(#Head, 1011)
CreateSprite3D(#Body, 1012)
CreateSprite3D(#Bullet, #bullet1)
CreateSprite3D(#Target,#enemy1)
;LoadSprite(#Cursor, "\cursor\cursor0.bmp",#PB_Sprite_Memory)
CreateSprite(#Cursor,32,32,#PB_Sprite_Memory) ; because i dont have the actual cursor used...
StartDrawing(SpriteOutput(#Cursor))
Circle(16,16,16,#Blue)
Circle(16,16,14,#Black)
Line(15,8,0,16,#Blue)
Line(8,15,16,0,#Blue)
StopDrawing()
Player1.Player
Player1\hSIZE = 0;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 = 12 ; 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-15), Int(Player1\y-15),200)
RotateSprite3D(#Body, Player1\GoalAngle, 0)
DisplaySprite3D(#Body, Int(Player1\x-15), Int(Player1\y-15)) ;, 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
If SpriteCollision(#bullet2, Projectile()\x,Projectile()\y, #Cursor2, Maus\x-5, Maus\y-5)
DeleteElement(Projectile())
Break
EndIf
CompensateX.l=SpriteWidth(#Bullet1)/2
CompensateY.l=SpriteHeight(#Bullet1)/2
Projectile()\x + Projectile()\SpeedoX
Projectile()\y + Projectile()\SpeedoY
Projectile()\Scalar + 1 ; size to increase by 1 to 10 but 10 is HUGE
Projectile()\Dimmer - 3 ; 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-CompensateX), Int(Projectile()\y-CompensateY) , Int(Projectile()\Dimmer))
;DisplaySprite(#Bullet2,Int(Projectile()\x), Int(Projectile()\y))
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(#bullet2, Projectile()\x,Projectile()\y, #enemy1, target()\x, target()\y)
DeleteElement(target())
DeleteElement(Projectile())
Break
EndIf
Next
EndIf
Wend
Stop3D()
DisplayTransparentSprite(#Cursor, Maus\x-15, Maus\y-15)
;DisplaySprite(#Cursor2,Maus\x-5,Maus\y-5)
FlipBuffers()
If KeyboardPushed(#PB_Key_Escape)
Quit = 1
EndIf
Delay(3)
Until Quit