Problem with my bullets

Blitz3D Forums/Blitz3D Beginners Area/Problem with my bullets

Hello,

I was wondering if anyone could help me with my bullet functions. All the variables are declared Global. The thing is that when the player presses spacebar the CreateBullet function is called. The new bullet entity is placed in front of the player and made to face in the same direction as the player. This is done by using a temporary Pivot entity in front of the player and then using PointEntity to point the bullet at the player. The DoBullet function moves the bullet forward and then destroys it at certain distance.
However, when I use this code I only see the first bullet fired. Also, the bullet always heads in the same direction, even if the player is looking another way.

The player consists of three entities, the camera, the player mesh and a pivot between them (called "pivot" in the code which acts as the parent.
Could anyone give me a hint?
{code}

Function CreateBullet()

bullet = CreateCube()

temp = CreatePivot ()
PositionEntity temp, EntityX(pivot)+5,EntityY(pivot),EntityZ(pivot) +5
PointEntity bullet, temp
bullet_dist = 0
EntityRadius bullet,1
EntityType bullet,4
bullet_exist = True

End Function

Function DoBullet()
If bullet_exist

MoveEntity bullet,0,0,player_speed#+1
bullet_dist = bullet_dist+1
If EntityCollided (bullet, 3)
FreeEntity bullet
bullet_exist = False
End If
If bullet_dist = 60
bullet_dist=0
FreeEntity bullet
bullet_exist=False
End If
End If
End Function

{/code}

Look at this code here... the bullet part of it anyway. It is something similar to what I use. but not what I use...
http://www.blitzbasic.com/Community/posts.php?topic=42581

-RZ

To get the bullet to face the same way as the player, just Rotate it, using the players global EntityPitch(), EntityRoll() and EntityYaw()

Check out my FPS example code I wrote.

Look under the "Add code to allow the player to shoot:" section...

Yeah... Wolron is the one who helped me do this!

Wow! Great! I think the problem was that I was using local coordinates instead of global ones. Thanks WolRon (I looked at your code more than the others, but they're great too!). And thanks to Ross for recommending EntityYaw, pitch, roll (I had forgotten those.

I have another question now, I am trying to "destroy" the enemy entity once its been hit. But because I am not using types for my enemy entities (I don't understand them too well yet) I don't have a way of detecting which enemy entity was actually hit (my enemy meshes are in a normal array). I believe I can get this entity with the CollisionEntity command, but I don't get how to use it.
I tried this but I get a memory access violation error:

For x = 1 To CountCollisions (bullet)
      FreeEntity CollisionEntity(bullet,x)
    Next


Try posting your code again.

Try using the EntityCollided command. :o)

Here's my new code:

Function CreateBullet()
bullet = CreateCube() 
bullet_dist = 0
EntityRadius bullet,1
EntityType bullet,4
bullet_exist = True

;position bullet
PositionEntity bullet,EntityX(pivot),EntityY(pivot),EntityZ(pivot)
;orient bullet
RotateEntity bullet,EntityPitch(pivot,1),EntityYaw(pivot,1),EntityRoll(pivot,1)

End Function

Function DoBullet()
If bullet_exist 

  MoveEntity bullet,0,0,player_speed#+1
  bullet_dist = bullet_dist+1
  If CountCollisions(bullet) >0
    hit_enemy = EntityCollided (bullet,3)
    For x = 1 To CountCollisions (bullet)
      FreeEntity CollisionEntity(bullet,x)
    Next 
    FreeEntity bullet
    FreeEntity hit_enemy
    bullet_exist = False
    remaining = remaining -1
  End If
  If bullet_dist = 60
    bullet_dist=0
    FreeEntity bullet
    bullet_exist=False
  End If
End If
End Function



I am going to post some code I edited for a user on blitzcoder. I am posting it because I cannot find the topic on blitzcoder anymore. ALSO I am the one that used functions and types to try and modify his code from the rat's nest MESS it was...
That said, the reason this code works is because of me (and by extension Wolron and Rob and a few others who taught me about functions and types):
; ###########################################   THIS CODE IS NOT INDENTED AND IS VERY HARD TO READ
; 												VERY MESSY. 
Graphics3D 640,480,16,0 
SetBuffer BackBuffer()
AmbientLight 60, 60, 50

HidePointer

Global set = 0
h=CreatePivot()
PositionEntity h,20,2,40
Global power=1
Global gun_timer=MilliSecs() ; timer to track the difference in millisecs
Global gun_time=750 ; time in milliseconds that the gun will fire
Global ammo
Global score
; ################################################  CHANGED THIS FOR MORE FREE FIRE
Type bullet
	Field entity
	Field speed#
	Field range
	Field pivot
End Type 

aim=LoadImage("aimpoint2.png") ; you are going to need a PNG for this to work 32X32 Black Back and Yellow Cross is simple enough
light=CreateLight(1)

aimer=CreateCamera()
PositionEntity aimer,20,2,20

Global bullet=CreateSphere(32)
EntityType bullet,1
PositionEntity bullet,20,2,20
EntityColor bullet,222,255,222
ScaleEntity bullet,Rand(1,2),Rand(1,2),Rand(1,2)

plane=CreatePlane(2)
EntityColor plane,0,0,255
EntityShininess plane,62
EntityType plane,1

tilt = 360
turn = 1
turning = 0

bottle=CreateCylinder(40)
PositionEntity bottle,20,0,50
ScaleEntity bottle,1,2,1
EntityRadius bottle, 2
EntityType bottle, 1

 
; #########################  SET COLLISIONS SO WE CAN SEE IF WE HIT
Collisions 1,2,2,1
Collisions 2,1,2,1

ammo = 10

While Not KeyDown(1)

update_bullet()
check_collide()

If MilliSecs()>gun_time+gun_timer Then ShowEntity bullet
If MilliSecs()<gun_time+gun_timer Then HideEntity bullet


If turn = 1 Then
	turning = 1
		tilt = tilt - 1
			If tilt >= 370
				turn = 2
			EndIf 
EndIf 

If turn = 2 Then 
	turning = -1
		tilt = tilt - 1
			If tilt <= 350
				turn = 1
			EndIf 
EndIf  

If turn =1 = True Then TurnEntity bottle,0,0,turning

If turn =2 = True Then TurnEntity bottle,0,0,turning

mxs#=MouseXSpeed()/4
mys#=MouseYSpeed()/4

xa#=(xa#-mxs#)Mod 360
ya#=(ya#+mys#)Mod 360

MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
RotateEntity aimer,ya#,xa#,0

If KeyDown( 201 )=True Then power=power+1 ; PAGE UP power up

If KeyDown( 209 )=True Then power=power-1 ; PAGE DOWN power down

If power <= 1 Then
	power = 1
EndIf
 
If power >= 12 Then 
	power = 12
EndIf 

; #####################################################   Polished this up a bit
If KeyHit(57) = True Then
	gun_timer=MilliSecs() 	; reset the bullet timer
	create_bullet(aimer)	; call function to create a bullet. Pass across the aimer entity to the function
						  	; so the bullet can come from the guns position
EndIf 

UpdateWorld()
RenderWorld()

DrawImage aim,297,227

Rect 70,15,powerful,5

Text 10,10,"Power:"
Text 10,30,"Energy: " + power
Text 10,70,"Rocks Left: " + ammo
Text 10,90,"SCORE: "+score

check_collide()

Flip
Wend 
End 
; ################################# FUNCTIONS
Function create_bullet(gun_entity) ; this creates a bullet at the aimer


If ammo = 0 Then Return
ammo = ammo - 1

HideEntity bullet ; hide old entity

	b.bullet=New bullet
		temp_x=EntityX(gun_entity,True)
		temp_y=EntityY(gun_entity,True)
		temp_z=EntityZ(gun_entity,True)
			b\entity=CopyEntity(bullet)
			b\pivot=CreatePivot()
				PositionEntity b\entity,temp_x,temp_y,temp_z
					EntityType b\entity,2
						RotateEntity b\entity,EntityPitch(gun_entity,True),EntityYaw(gun_entity,True),0
					PositionEntity b\pivot,temp_x,temp_y,temp_z
				b\range = 250  ; set bullet range so it does not clutter the screen (I used power but usually set it at 200 - 300
		b\speed = power  ; set initial bullet speed

End Function

Function update_bullet()

	For b.bullet = Each bullet
		MoveEntity b\entity,0,0,b\speed
		If EntityDistance#(b\entity,b\pivot) > b\range Then
			FreeEntity b\entity
			FreeEntity b\pivot
			Delete b.bullet
		End If
	Next
	
End Function

Function check_collide()

For b.bullet = Each bullet
	If EntityCollided(b\entity,1) Then ;since our bottle is a 1

				HideEntity b\entity
				score = score +10
				FreeEntity b\entity
				FreeEntity b\pivot
				Delete b.bullet
	EndIf
Next
	
	; this function could be reversed to hide the bottle and place a new bottle in a new location
	; simply by a small change of code... 
End Function
I edited it some more... still a little messy. Now it is essentially my code with whoevers mesh creation elements in it... those are general so they really do not apply to anybody. This is how you can apply entitycollided and use arrays to do things... modify it... use the ideas from it. Have fun!

Thanks Rook,

It's a little messy but got some ideas. The ShowEntity/HideEntity for the bullet is nice. I am using CreateCube for the bullet and then FreeEntity to destroy it, but there is a certain lag (if you keep pressing the fire button the game basically stops). It's nice to just be able to have there all the time and use when needed. I think I also figured out how to use EntityCollided.

This is a "demo" I am making. I plan to post the full code once I finish it (to give something back to the community). It is not something very complex, but I think beginner's could find it useful to learn the basics (I myself have using Blitz only since January).

It seems like you can only shoot one bullet at a time. Probably you want to be able to shoot them frequently, regardless of how many bullets are still in the air. You may use an array for bullets too, and Millisecs to allow new bullets.
something like

if gun_ready<=millisecs()
 gun_ready=millisecs()+100 ; 10 rounds/s
 CreateBullet()
endif

and the CreateBullet and DoBullet Functions could be prety much as they are now, just add an array index to the Bullet variable, and a global counter that will increment with each bullet, and if it reaches the max index, reset it to zero. If the array is big enough (considering the distance that will auto-free bullets), it should work nicely. Of course, you need to parse the whole array to check the distances. But make sure to set Bullet(n) to zero after Freeentity, this way you'll be able to check if a bullet mesh is still existing before you create a new one with this bullet array index.

Actually if you modify this:
Global gun_time=750 ; time in milliseconds that the gun will fire
with a lower number you can spit bullets like a hose at a three alarm fire! ; )
-RZ

I was talking about Skys Code, not yours, Rook, of course, your code may solve the problem as well.

Thanks for the advice everyone, sorry for the long delay in answering, but I've been busy in other projects (not Blitz related). The single bullet thing was intentional. I didn't want to complicate matters too much as I'm still quite the beginner, but I will try to make it be multiple bullet. However, I think that when I do that, I will rather use types to represent the bullets, the enemies and the player, it seems so much simpler. Still, I appreciate your suggestions. Thanks.