ok, here's is some code i put together. press space bar to fire a bullet. it will send the bullet to the location of the target at the time of the shot being fired.
Graphics 800,600
SetBuffer BackBuffer()
player=CreateImage(32,32); create player ship
SetBuffer ImageBuffer(player)
Rect 0,0,32,32
target=CreateImage(64,64);create target ship
SetBuffer ImageBuffer(target)
Rect 0,0,64,64
bullet=CreateImage(1,1); create bullet image
SetBuffer ImageBuffer(bullet)
Rect 0,0,1,1
SetBuffer BackBuffer(); set the buffer to the back for double buffering
MidHandle player
MidHandle target
MidHandle bullet; set midhandles on all the images. Meaning the x and y co-ords will be taken for the middle of the image instead of the top left corner
px=400; set player co-ords
py=500
tx=400; set target co-ords
ty=50
t_dir=1; set target direction 1=right, -1=left
bul_speed=2; set speed of the bullet
Type bul; set up the types for the bullet
Field image
Field x#,y#
Field angle
End Type
While Not KeyHit(1)
Cls
If KeyDown(203) Then px=px-1:If px<20 Then px=20; move the player left, if he moves too far left then move him back to x=20
If KeyDown(205) Then px=px+1:If px>750 Then px=750; move the player right, if he moves too far right then move him back to x=750
If KeyHit(57) Then Gosub createbullet; if user presses space bar then fire a bullet
DrawImage player,px,py; draw the player image
DrawImage target,tx,ty; draw the target image
Gosub updatetarget; goto the subroutine to update and move the target
Gosub updatebullet; goto the subroutine to update and move the bullets
Flip; flip the backbuffer to the frontbuffer so we can see it
Wend
End
.createbullet
b.bul=New bul
b\image=CopyImage(bullet); copy bullet image to type collection
b\x=px
b\y=py
b\angle=ATan2(tx-px,ty-py)get the angle between the ship and the target
Return
.updatebullet
For b.bul=Each bul
DrawImage b\image,b\x,b\y
b\x=b\x+Sin(b\angle)*bul_speed;move the bullet in the x dir using sin and the angle variable
b\y=b\y+Cos(b\angle)*bul_speed;move the bullet in the y dir using cos and the angle variable
If b\y<0 Then; if bullet leaves the top of the screen then delete it
FreeImage b\image; free the image, other wise it will still be in memory
Delete b.bul; delete the type instance
End If
Next
Return
.updatetarget
tx=tx+t_dir; move target in the dir
If tx>750 Or tx<50 Then t_dir=t_dir*-1
Return
In this next code, (it's basically the same code) the bullet will move slightly towards the target/enemy.
Graphics 800,600
SetBuffer BackBuffer()
player=CreateImage(32,32)
SetBuffer ImageBuffer(player)
Rect 0,0,32,32
target=CreateImage(64,64)
SetBuffer ImageBuffer(target)
Rect 0,0,64,64
bullet=CreateImage(1,1)
SetBuffer ImageBuffer(bullet)
Rect 0,0,1,1
SetBuffer BackBuffer()
MidHandle player
MidHandle target
MidHandle bullet
px=400
py=500
tx=400
ty=50
t_dir=1
bul_speed=2
Type bul
Field image
Field x#,y#
Field angle
End Type
While Not KeyHit(1)
Cls
If KeyDown(203) Then px=px-1:If px<20 Then px=20
If KeyDown(205) Then px=px+1:If px>750 Then px=750
If KeyHit(57) Then Gosub createbullet
DrawImage player,px,py
DrawImage target,tx,ty
Gosub updatetarget
Gosub updatebullet
Flip
Wend
End
.createbullet
b.bul=New bul
b\image=CopyImage(bullet)
b\x=px
b\y=py
b\angle=ATan2(tx-px,ty-py)
Return
.updatebullet
For b.bul=Each bul
b\angle=ATan2(tx-px,ty-py); this time work out the angle eerytime based on the player and the target
DrawImage b\image,b\x,b\y
b\x=b\x+Sin(b\angle)*bul_speed
b\y=b\y+Cos(b\angle)*bul_speed
If b\y<0 Then
FreeImage b\image
Delete b.bul
End If
Next
Return
.updatetarget
tx=tx+t_dir
If tx>750 Or tx<50 Then t_dir=t_dir*-1
Return
Finally, this code will hit the enemy always.
Graphics 800,600
SetBuffer BackBuffer()
player=CreateImage(32,32)
SetBuffer ImageBuffer(player)
Rect 0,0,32,32
target=CreateImage(64,64)
SetBuffer ImageBuffer(target)
Rect 0,0,64,64
bullet=CreateImage(1,1)
SetBuffer ImageBuffer(bullet)
Rect 0,0,1,1
SetBuffer BackBuffer()
MidHandle player
MidHandle target
MidHandle bullet
px=400
py=500
tx=400
ty=50
t_dir=1
bul_speed=2
bul_count=0
Type bul
Field image
Field x#,y#
Field angle
End Type
While Not KeyHit(1)
Cls
If KeyDown(203) Then px=px-1:If px<20 Then px=20
If KeyDown(205) Then px=px+1:If px>750 Then px=750
If KeyHit(57) Then Gosub createbullet
DrawImage player,px,py
DrawImage target,tx,ty
Gosub updatetarget
Gosub updatebullet
Text 0,0," bul="+bul_count
Flip
Wend
End
.createbullet
b.bul=New bul
b\image=CopyImage(bullet)
b\x=px
b\y=py
b\angle=ATan2(tx-px,ty-py)
bul_count=bul_count+1
Return
.updatebullet
For b.bul=Each bul
b\angle=ATan2(tx-b\x,ty-b\y); work out the angle based on the bullet and the target(most accurate)
DrawImage b\image,b\x,b\y
b\x=b\x+Sin(b\angle)*bul_speed
b\y=b\y+Cos(b\angle)*bul_speed
If b\y<0 Then
FreeImage b\image
Delete b.bul
bul_count=bul_count-1
ElseIf ImagesCollide(b\image,b\x,b\y,0,target,tx,ty,0) Then; this time since the bullet will not leave the screen we must check to see if it collides with the target, if so then delete it
FreeImage b\image
Delete b.bul
bul_count=bul_count-1
End If
Next
Return
.updatetarget
tx=tx+t_dir
If tx>750 Or tx<50 Then t_dir=t_dir*-1
Return
The homing effect is caused by contant recalculating the angle. the first code only calculates the angle once, and travels to the enemy last position when the space was pressed.
The second code recalculates the angle all the time, using the ship and targets position, so it will home in on the target with more accuracy than the first code, but will still miss. useful for taking rough shots.
The final code will never miss and always track the enemy and always hit. This uses the bullets position and the targets position to get the angle.
and that as they say, is that :)
(oh you will probably want to put the collision code in anyway, to see if the bullet has actually hit the ship :^) )