Enemy Shots?

Blitz3D Forums/Blitz3D Beginners Area/Enemy Shots?

steyskal(Posted 2003) [#1]
Hi guys...
I wanted to make my enemys(in my space-shooter) to shot.
And these shots shall fly to my main-ship..
like a heatseeking rocket...
But ive no idea how i can ccode this...

so please help my with an code example :)

(I'm an Austrian boy, therefore my English is very bad...
sry^^)


Ross C(Posted 2003) [#2]
well, the first thing you should think of is getting the co-ords of the ship thats firing, and the ship the bullet is going towards. then drawing a straight line but everytime the target ship moves just readjusting the line.

sorry, don't have any code off hand, but this is the way i did it :o)

find the angle between the ship and target ship
angle=Atan2( shipy-targety,shipx-targetx)

using the angle now, take the sin and cos of it for x and y
bulletx=bulletx+sin(angle)
bullety=bullety+cos(angle)


if you want the bullet to travel faster then simply multiply the sin and cos by a speed

bulletx=bulletx+(sin(angle)*speed)
bullety=bullety+(cos(angle)*speed)


then just simply draw the bullet on screen
drawimage bullet,bulletx,bullety


that will send the bullet to the enemys or targets location.

Please note that this will only goto the location that the enemy/target was at when the angle was worked out.

if you want it to home in on the enemy then work out the angle every loop. and you must also make sure that the bullet doesn't travel forever. just say if its x or y co-ords leave the screen then delete it.

Hope this helps you out !


semar(Posted 2003) [#3]
Well, I try to describe a very rough example for a 3D shooter.

For testing purpose, just let's make an enemy shooting when you press the space bar:
Const K_SB = 57
if heyhit(L_SB) then
;shoot
endif

Now, what is a shoot ? Usually a rocket model, or something like that. For now, let's just use a sphere - you can easily substitute it with anything else.

The shooted sphere should travel from the starting point - which is an enemy - to the target point - which is, the ship. The shoot should also have a speed.
So basically, once fired, the shoot should continuosly point toward the target, and travel.

This scenario suggests to use a type structure for a shoot:
type t_shoot
field ent ;the shoot entity - ex. a sphere
field speed# ;the speed
field target ;the target entity where to point to
End Type
Global shoot.t_shoot

So, suppose we have also:
- an entity called 'ship' which represents our target
- an entity called 'enemy' which fires the shoot toward the target

Said that, the code would look like:
Const K_SB = 57
if heyhit(L_SB) then
   ;create a shoot
   shoot.t_shoot = new shoot

   ;create the entity
   shoot\ent = createshpere()
 
  ;assign a speed
   shoot\speed = 1.5

   ;assigh the target
   shoot\target = target

   ;color the entity
   entitycolor shoot\ent,255,0,0

   ;position the entity at the enemy position
   positionentity shoot\ent, entityx(enemy),entityy(enemy),entityz(enemy)
   
endif

;now, we should call the move_shoot routine at each loop:
function move_shoot()
for shoot.t_shoot = each t_shoot ;for all the shoot we have

   ;point the shoot toward the target
   pointentity shoot\ent,shoot\target

;move it along z axis
moveentity shoot\ent, 0,0,shoot\speed

;check for collision between shoot and target
;you do this part ;-)
;once collided with the ship, remember to:
-- free the entity shoot\ent
-- delete the element shoot

next

end function


I hope this is a good starting for you. Good luck and have fun !

Sergio.


steyskal(Posted 2003) [#4]
Yeah.. thx..

i will test it^^


steyskal(Posted 2003) [#5]
sorry guys but it doesn't work :'(
@joker
ive read your example and thought that it must (funktionieren) but it doesn't...
can you give me a full example?
In my code the shot flew away?!?!

@semar
sanks for your code..
if i code anytime a 3d-shooter i use you code ;)
thx!

PS: i would also learn how to make the NPCs thinking!
You know?
How to program a simple KI like: shot,not shot,flew away from the players shot and so on..
It works with a Case-Loop?
thx leutz^^


Ross C(Posted 2003) [#6]
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 :^) )


steyskal(Posted 2003) [#7]
juhuu....
/me give joker ab big fat kiss ;)

thx 4 everything!!!


Ross C(Posted 2003) [#8]
lol, hey no problem man, just glad i could help ya. let me know how you get one :D

see ya


steyskal(Posted 2003) [#9]
sry but i have problems to change the code into one with types...

example..
Graphics 800,600,32,1
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Global schiff=LoadAnimImage("dreher.png",48,48,0,18)
Global main=LoadAnimImage("raumschiff.bmp",64,64,0,5)
Global schuss=LoadImage("boom.jpg")
Global shoot=0
Global frame=9
Global verhalten_dreher=1
Global sek=10300
Global tymer=MilliSecs()

Global xs=400,ys=500
Type alien
Field image
Field x,y
Field max_frame
Field current_frame
Field starttime
Field speed
End Type

Type bul
	Field image
	Field x#,y#
	Field angle
End Type
Global bs.bul

While Not KeyHit(1)
Cls

If MilliSecs() - tymer > 10 Then sek = sek -1
tymer = MilliSecs() 
If KeyHit(57) Then 
For dreher.alien=Each alien

createbullet(schuss,dreher\x+4,dreher\y-4)
shoot=2
Next
EndIf
DrawImage main,xs,ys,2

Text 200,100,sek
If sek=10050 Then
For i=1 To 10
create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
Next
EndIf

If sek=9750 Then
For i=1 To 10
create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
Next
EndIf

If sek=9550 Then
For i=1 To 10
create_dreher(schiff,Rnd(50,500),Rnd(-150,-350),17)
Next
EndIf


switch_verhalten()
updatebullet()

draw_dreher()


Flip
Wend
End


Function create_dreher(image,x,y,maxframe)
	dreher.alien = New alien
	dreher\image = image
	dreher\x = x
	dreher\y = y
	dreher\speed = 3
	dreher\max_frame = maxframe
	dreher\current_frame = 0
	dreher\starttime = MilliSecs()
End Function

Function draw_dreher()
	; Enemies
	For dreher.alien=Each alien
	verhalten_dreher=1
	;dreher\x = dreher\x+Sin(dreher\y)*4
	;dreher\y# = (dreher\y# + dreher\speed) Mod 600
		DrawImage dreher\image,dreher\x,dreher\y,dreher\current_frame
		If MilliSecs()-dreher\starttime>20
			dreher\starttime=MilliSecs()
			dreher\current_frame=dreher\current_frame+1
		EndIf
		If MilliSecs()-dreher\starttime>1000
			dreher\starttime=MilliSecs()
			verhalten_dreher=2
		EndIf

		If dreher\current_frame>dreher\max_frame Then dreher\current_frame=0
		If dreher\y>590 Then Delete dreher.alien
		
	Next
End Function

Function switch_verhalten()
 For dreher.alien=Each alien
  Select verhalten_dreher

   Case 1
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600

   Case 2
       dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
	shoot=1

   Default
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
End Select
Next
End Function 

Function createbullet(image,x,y)
	bs.bul=New bul
	bs\image=CopyImage(image)
	bs\x=x
	bs\y=y
	bs\angle=ATan2(xs-x,ys-y)
End Function

function updatebullet()	
For bs.bul=Each bul
	
		bs\angle=ATan2(x-bs\x,y-bs\y); work out the angle based on the bullet and the target(most accurate)
		DrawImage bs\image,bs\x,bs\y
		bs\x=bs\x+Sin(bs\angle)*bul_speed
		bs\y=bs\y+Cos(bs\angle)*bul_speed
		If bs\y<0 Then
			FreeImage bs\image
			Delete bs.bul
			
		ElseIf ImagesCollide(bs\image,bs\x,bs\y,0,main,xs,ys,2) 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 bs\image
			Delete bs.bul			
		End If
	Next

end function


can anyone make this code running?
i want to press space and then the aliens should shoot a rocket to the player...
but it doesnt work...
can u help me??

thx^^


Ross C(Posted 2003) [#10]
can you mail me the code along with the media files?


steyskal(Posted 2003) [#11]
here is the download link
http://home.pages.at/maniac88/dreher.zip

thx guy^^

edit: send it please to save_my_soul88@...
or post it into the forum :D


Ross C(Posted 2003) [#12]
hey, here's your code, got it to work. the reason your bullets weren't moving is because you didn't set any speed value on the bul_speed value :)

also i changed a few variables because the ones you were using weren't the correct ones for working out the homing effect. i also put a midhandle on the main pleyer image, works better. feel free to post back and tell me how you get on! :D


steyskal(Posted 2003) [#13]
where is the code? ;)

have you send it to save_my_soul88@...?
you can also send it to we_want_freedom@...
more webspace =)


Ross C(Posted 2003) [#14]
strange, i'm pretty sure i posted it :S sorry !

well here it is

Graphics 800,600,32
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Global schiff=LoadAnimImage("dreher.png",48,48,0,18)
Global main=LoadAnimImage("raumschiff.bmp",64,64,0,5)
MidHandle main
Global schuss=LoadImage("boom.jpg")
Global shoot=0
Global frame=9
Global verhalten_dreher=1
Global sek=10300
Global tymer=MilliSecs()
Global bul_speed=1

Global xs=400,ys=500
Type alien
Field image
Field x,y
Field max_frame
Field current_frame
Field starttime
Field speed
End Type

Type bul
	Field image
	Field x#,y#
	Field angle
End Type
Global bs.bul

While Not KeyHit(1)
	Cls
	
	If MilliSecs() - tymer > 10 Then sek = sek -1
	tymer = MilliSecs() 
	
	If KeyHit(57) Then 
		For dreher.alien=Each alien
			
			createbullet(schuss,dreher\x+4,dreher\y-4)
			shoot=2
		Next
	EndIf

	
	Text 200,100,sek
	If sek=10050 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
		Next
	EndIf
	
	If sek=9750 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
		Next
	EndIf
	
	If sek=9550 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(50,500),Rnd(-150,-350),17)
		Next
	EndIf
	
	
	switch_verhalten()
	Gosub updatebullet
	
	draw_dreher()
	DrawImage main,xs,ys,2
	
	Flip
Wend
End


Function create_dreher(image,x,y,maxframe)
	dreher.alien = New alien
	dreher\image = image
	dreher\x = x
	dreher\y = y
	dreher\speed = 3
	dreher\max_frame = maxframe
	dreher\current_frame = 0
	dreher\starttime = MilliSecs()
End Function

Function draw_dreher()
	; Enemies
	For dreher.alien=Each alien
	verhalten_dreher=1
	;dreher\x = dreher\x+Sin(dreher\y)*4
	;dreher\y# = (dreher\y# + dreher\speed) Mod 600
		DrawImage dreher\image,dreher\x,dreher\y,dreher\current_frame
		If MilliSecs()-dreher\starttime>20
			dreher\starttime=MilliSecs()
			dreher\current_frame=dreher\current_frame+1
		EndIf
		If MilliSecs()-dreher\starttime>1000
			dreher\starttime=MilliSecs()
			verhalten_dreher=2
		EndIf

		If dreher\current_frame>dreher\max_frame Then dreher\current_frame=0
		If dreher\y>590 Then Delete dreher.alien
		
	Next
End Function

Function switch_verhalten()
 For dreher.alien=Each alien
  Select verhalten_dreher

   Case 1
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600

   Case 2
       dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
	shoot=1

   Default
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
End Select
Next
End Function 

Function createbullet(image,x,y)
	bs.bul=New bul
	bs\image=CopyImage(image)
	bs\x=x
	bs\y=y
	bs\angle=0
	bs\angle=ATan2(y-ys,xs-x)
End Function

.updatebullet	
For bs.bul=Each bul
	
		bs\angle=ATan2(xs-bs\x,ys-bs\y); work out the angle based on the bullet and the target(most accurate)
		DrawImage bs\image,bs\x,bs\y
		bs\x=bs\x+Sin(bs\angle)*bul_speed
		bs\y=bs\y+Cos(bs\angle)*bul_speed
		If bs\y<0 Then
			FreeImage bs\image
			Delete bs.bul
			
		ElseIf ImagesCollide(bs\image,bs\x,bs\y,0,main,xs,ys,2) 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 bs\image
			Delete bs.bul			
		End If
	Next

Return



steyskal(Posted 2003) [#15]
YYYYYYYYYYEEEEEEEEEEEEEEEEEAAAAAAAAAAAAHHHHHHHHHHHHHHHHH
thats it^^

big THX

:)


Ross C(Posted 2003) [#16]
nah bother :D


steyskal(Posted 2003) [#17]
damn... =)

I tried to code an AI for the aliens to make them shot without pressing space i tried it with this code

Graphics 800,600,32
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Global schiff=LoadAnimImage("dreher.png",48,48,0,18)
Global main=LoadAnimImage("raumschiff.bmp",64,64,0,5)
MidHandle main
Global schuss=LoadImage("boom.jpg")
Global shoot=0
Global frame=9
Global verhalten_dreher=1
Global sek=10300
Global tymer=MilliSecs()
Global bul_speed=1

Global xs=400,ys=500
Type alien
Field image
Field x,y
Field max_frame
Field current_frame
Field starttime
Field speed
End Type

Type bul
	Field image
	Field x#,y#
	Field angle
End Type
Global bs.bul

While Not KeyHit(1)
	Cls
	
	If MilliSecs() - tymer > 10 Then sek = sek -1
	tymer = MilliSecs() 
	
	If shoot=1 Then ;<----NEW
		For dreher.alien=Each alien
			
			createbullet(schuss,dreher\x+4,dreher\y-4)
			shoot=2
		Next
	EndIf

	
	Text 200,100,sek
	If sek=10050 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
		Next
	EndIf
	
	If sek=9750 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
		Next
	EndIf
	
	If sek=9550 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(50,500),Rnd(-150,-350),17)
		Next
	EndIf
	
	
	switch_verhalten()
	Gosub updatebullet
	
	draw_dreher()
	DrawImage main,xs,ys,2
	
	Flip
Wend
End


Function create_dreher(image,x,y,maxframe)
	dreher.alien = New alien
	dreher\image = image
	dreher\x = x
	dreher\y = y
	dreher\speed = 3
	dreher\max_frame = maxframe
	dreher\current_frame = 0
	dreher\starttime = MilliSecs()
End Function

Function draw_dreher()
	; Enemies
	For dreher.alien=Each alien
	verhalten_dreher=1
	;dreher\x = dreher\x+Sin(dreher\y)*4
	;dreher\y# = (dreher\y# + dreher\speed) Mod 600
		DrawImage dreher\image,dreher\x,dreher\y,dreher\current_frame
		If MilliSecs()-dreher\starttime>20
			dreher\starttime=MilliSecs()
			dreher\current_frame=dreher\current_frame+1
		EndIf
		If MilliSecs()-dreher\starttime>1000
			dreher\starttime=MilliSecs()
			verhalten_dreher=2
		EndIf
if dreher\current_frame=8 then shoot=1;<-----NEW
		If dreher\current_frame>dreher\max_frame Then dreher\current_frame=0
		If dreher\y>590 Then Delete dreher.alien
		
	Next
End Function

Function switch_verhalten()
 For dreher.alien=Each alien
  Select verhalten_dreher

   Case 1
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600

   Case 2
       dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
	shoot=1

   Default
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
End Select
Next
End Function 

Function createbullet(image,x,y)
	bs.bul=New bul
	bs\image=CopyImage(image)
	bs\x=x
	bs\y=y
	bs\angle=0
	bs\angle=ATan2(y-ys,xs-x)
End Function

.updatebullet	
For bs.bul=Each bul
	
		bs\angle=ATan2(xs-bs\x,ys-bs\y); work out the angle based on the bullet and the target(most accurate)
		DrawImage bs\image,bs\x,bs\y
		bs\x=bs\x+Sin(bs\angle)*bul_speed
		bs\y=bs\y+Cos(bs\angle)*bul_speed
		If bs\y<0 Then
			FreeImage bs\image
			Delete bs.bul
			
		ElseIf ImagesCollide(bs\image,bs\x,bs\y,0,main,xs,ys,2) 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 bs\image
			Delete bs.bul			
		End If
	Next

Return

so my problem... they shot in a very short time(sry but i don't know what that mean in english^^)try it out and see it by yourself...

Is there anyway to make them slower?
Or make them to shot alone without pressing the space button?

thx.. =)


Ross C(Posted 2003) [#18]
i suppose you mean a sort of fire rate?
well i've put that in, basically involving a random number.

Graphics 800,600,32
SetBuffer BackBuffer()
SeedRnd MilliSecs()

Global schiff=LoadAnimImage("dreher.png",48,48,0,18)
Global main=LoadAnimImage("raumschiff.bmp",64,64,0,5)
MidHandle main
Global schuss=LoadImage("boom.jpg")
Global shoot=0
Global frame=9
Global verhalten_dreher=1
Global sek=10300
Global tymer=MilliSecs()
Global bul_speed=3
Global bullet_rate ;<------NEW  increase the value of this to make ships fire less often

Global xs=400,ys=500
Type alien
Field image
Field x,y
Field max_frame
Field current_frame
Field starttime
Field speed
End Type

Type bul
	Field image
	Field x#,y#
	Field angle
End Type
Global bs.bul

While Not KeyHit(1)
	Cls
	
	If MilliSecs() - tymer > 10 Then
		sek = sek -1
		tymer = MilliSecs() 
	End If
	
	If shoot=1 Then ;<----NEW
		For dreher.alien=Each alien
			If Int(Rnd(1,bullet_rate))=4 Then ;<-----NEW generates random number. if number is 4 then fire a bullet
				createbullet(schuss,dreher\x+4,dreher\y-4)
				shoot=2
			End If
		Next
	EndIf

	
	Text 200,100,sek
	If sek=10050 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
		Next
	EndIf
	
	If sek=9750 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(100,700),Rnd(-150,-350),17)
		Next
	EndIf
	
	If sek=9550 Then
		For i=1 To 10
			create_dreher(schiff,Rnd(50,500),Rnd(-150,-350),17)
		Next
	EndIf
	
	
	switch_verhalten()
	Gosub updatebullet
	
	draw_dreher()
	DrawImage main,xs,ys,2
	
	Flip
Wend
End


Function create_dreher(image,x,y,maxframe)
	dreher.alien = New alien
	dreher\image = image
	dreher\x = x
	dreher\y = y
	dreher\speed = 3
	dreher\max_frame = maxframe
	dreher\current_frame = 0
	dreher\starttime = MilliSecs()
End Function

Function draw_dreher()
	; Enemies
	For dreher.alien=Each alien
	verhalten_dreher=1
	;dreher\x = dreher\x+Sin(dreher\y)*4
	;dreher\y# = (dreher\y# + dreher\speed) Mod 600
		DrawImage dreher\image,dreher\x,dreher\y,dreher\current_frame
		If MilliSecs()-dreher\starttime>20
			dreher\starttime=MilliSecs()
			dreher\current_frame=dreher\current_frame+1
		EndIf
		If MilliSecs()-dreher\starttime>1000
			dreher\starttime=MilliSecs()
			verhalten_dreher=2
		EndIf
if dreher\current_frame=8 then shoot=1;<-----NEW
		If dreher\current_frame>dreher\max_frame Then dreher\current_frame=0
		If dreher\y>590 Then Delete dreher.alien
		
	Next
End Function

Function switch_verhalten()
 For dreher.alien=Each alien
  Select verhalten_dreher

   Case 1
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600

   Case 2
       dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
	shoot=1

   Default
    dreher\x = dreher\x+Sin(dreher\y)*4
	dreher\y# = (dreher\y# + dreher\speed) Mod 600
End Select
Next
End Function 

Function createbullet(image,x,y)
	bs.bul=New bul
	bs\image=CopyImage(image)
	bs\x=x
	bs\y=y
	bs\angle=0
	bs\angle=ATan2(y-ys,xs-x)
End Function

.updatebullet	
For bs.bul=Each bul
	
		bs\angle=ATan2(xs-bs\x,ys-bs\y); work out the angle based on the bullet and the target(most accurate)
		DrawImage bs\image,bs\x,bs\y
		bs\x=bs\x+Sin(bs\angle)*bul_speed
		bs\y=bs\y+Cos(bs\angle)*bul_speed
		If bs\y<0 Then
			FreeImage bs\image
			Delete bs.bul
			
		ElseIf ImagesCollide(bs\image,bs\x,bs\y,0,main,xs,ys,2) 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 bs\image
			Delete bs.bul			
		End If
	Next

Return



steyskal(Posted 2003) [#19]
thx
but so they dont shot^^
or to less :)

@joker sanks for your help ;)


Ross C(Posted 2003) [#20]
if you need anymore, feel free to post back :D