How to fire a bullet??

Iam trying to fire a bullet from an object. I got the bullet fired but its direction is my problem. It always moves in one direction but not according to the movement of object.

self.sphereMovement = self.sphereAxis.hprInterval(10.0,Vec3(0,0,0),startHpr=Vec3(0,0,0))
self.sphereMovement.loop()

this is the code that i used for the movement of bullet.

Plzz help me to change its direction according to the movement of object.

You’re going to need the movement command that references the self. I’m not entirely sure how to implement it on an interval, but I emulated that like this:
self.sphere.setY(self.sphere, number * globalClock.getDt())
Base command: self.object.setY(self.object, number)

Basically what that does is change the Y code of the object based on the direction and position of the referenced object. You can reference the object itself, or a different object (like the “gun”).

above thanxxx :smiley:
here sphere is your bullet n object is your gun right??
if my object is panda and i want to fire a bullet from panda then my referenced object will be panda right??

then how our bullet will move. By setY() we are only setting the Y coordinate of the bullet but how it will move in that direction??

…By resetting the Y coordinate? If you mean fluid movement, you can get that by using the local time to multiply the movement.

how can we get local time??

globalClock.getDt() returns the time in frames between somehow… Not entirely sure what it returns, tbh, but it works for movement functions.

what do you mean by local time?? i didn’t get it… :frowning:

The time of the program in frames.

thanxx…

i wrote the code as u told. But my bullet is not moving it only appears in the same position of the object with out any movement.Plzz help me to make it move…

if (self.keyMap["fire"] !=0 and task.time > task.nextBullet):
       self.blastNP = NodePath("smiley")
       self.blastNP.reparentTo(base.render)  
       pan=self.panda.getPos()
       actorHpr = self.panda.getHpr()
       self.sphere= loader.loadModel("models/sphere-highpoly")
       self.sphere.setScale(.02)
       self.sphere.reparentTo(self.blastNP)
		     
       self.sphere.setCollideMask(BitMask32.allOff())
       self.sphereCollider = self.sphere.attachNewNode(CollisionNode("blastCollider"))
		self.sphereCollider.node().addSolid(CollisionSphere(0, 0, 0.5, 0.4))
		self.sphereGroundHandler = CollisionHandlerQueue()
        	self.cTrav2.addCollider(self.sphereCollider, self.sphereGroundHandler) 		
		self.sphere.setPos(pan)
        	self.sphere.setHpr(actorHpr)	
		self.blastLife = 3
	 	for i in range(self.sphereGroundHandler.getNumEntries()):  
            		entrysphere=  self.sphereGroundHandler.getEntry(i)
			print("entry",entrysphere)
			self.sphere.setY(self.sphere, -80 * globalClock.getDt())
        		self.blastLife -= 1 * globalClock.getDt()

This is my code… plz help me if there is any mistake…
I want the bullete to move… Here self.sphere is bullet and self.panda is object…

In your code the position is simply set twice when fire is pressed. First you set it to the position of the shooter, then you set its Y position a small amount. For it to keep moving you need another task dedicated to updating the Y position every frame.

Judging from the code you’ve posted, it can only handle one bullet. If you hold the fire key down I’m guessing it will just continuously overwrite the self.sphere variable. You should consider starting with an empty list and appending new bullets to it. Then you have the added complication of clearing out “dead” bullets, or maintaining a pool of hidden bullets to reuse.

Since you’ve posted on this subject several times, I think a working example is needed:

from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor

app = ShowBase()

app.disableMouse()
app.acceptOnce("mouse3", app.enableMouse)

environ = loader.loadModel("environment")
environ.reparentTo(render)

panda = Actor("panda")
panda.reparentTo(render)
panda.setPos(40,-150,3)

pandaInterval = panda.hprInterval(5, (360,0,0), (0,0,0))
pandaInterval.loop()

bullets = []
bulletSpeed = -20.0 # negative because panda faces -Y
bulletLife = 5.0    # seconds bullet will remain in the scene

class Bullet(object):
    # model is left unparented because it will be copied
    model = loader.loadModel("smiley")
    
    def __init__(self, pos, hpr, speed, life):
        self.node = Bullet.model.copyTo(render)
        self.node.setPosHpr(pos, hpr)
        self.speed = speed
        self.life = life
        self.alive = True
    
    def update(self, dt):
        if not self.alive:
            return
        
        self.life -= dt
        
        if self.life > 0:
            # You should use the "fluid" versions of these functions
            # if you intend them to work with the collision system.
            self.node.setFluidY(self.node, self.speed * dt)
        else:
            self.node.removeNode()
            self.alive = False

# Every frame this task calls update on each bullet in the bullets list.
def updateBullets(task):
    dt = globalClock.getDt()
    
    for bullet in bullets:
        bullet.update(dt)
    
    return task.cont

def shoot():
    global bullets
    bullets = [b for b in bullets if b.alive] # remove any dead bullets
    bullets.append( Bullet(panda.getPos(), panda.getHpr(), bulletSpeed, bulletLife) )

app.accept("space", shoot)
taskMgr.add(updateBullets, "updateBullets")

app.camera.setPos(40,-250,70)
app.camera.lookAt(panda)

app.run()

This doesn’t do collisions. That would have made it much longer and I just wanted to show the basics.

above Thank you so much…

I implemented the code for shoot like this

class World(DirectObject):
    
    sphere= loader.loadModel("models/sphere-highpoly")
    sphere.setScale(.02)
    def fire(self,time,posx,posy,posz, hpr, speed, life):
		global bullets 
		bullets = [b for b in bullets if b.alive]		
		bullets.append(posx)
		posz1=posz+.5		
		self.node = World.sphere.copyTo(render)
        	self.node.setPos(posx,posy,posz1)
		self.node.setHpr(hpr)        	
		self.speed = speed
        	self.life = life
        	self.alive = True
		
    		print("bul",bullets)
    def __init__(self):

but i got error like this
File “battle0711.py”, line 41, in fire
bullets = [b for b in bullets if b.alive]
NameError: global name ‘bullets’ is not defined

please help me to correct this error plzzz…

The code you posted could not work as it is. Did you post all the code relevant to the problem? If no, please post the full relevant code. If yes, you should learn more about how to script Panda. Look at the “Asteroids” sample that comes with Panda (or download it on the website). The code that Hollower posted should work, but you did not really understand it I think. The code he posted is propably a bit too complex for a beginner. I think the “Asteroids” code is simpler.

For example, why do you put the init function after the fire function? The bullets variable might work as a global, but you could also make it a class attribute by putting it into the init and using self.bullets =

Maybe more like this (this code might not be working as is):

from direct.showbase.ShowBase import ShowBase
from direct.actor.Actor import Actor

app = ShowBase()
app.disableMouse()

class Environment(DirectObject):

	def __init__(self):
	
		self.environ = loader.loadModel("environment")
		self.environ.reparentTo(render)

		self.panda = Actor("panda")
		self.panda.reparentTo(render)
		self.panda.setPos(0,0,0)
		self.pandaInterval = self.panda.hprInterval(5, (360,0,0), (0,0,0))
		self.pandaInterval.loop()

		self.accept("mouse1", self.shoot)
		
	def shoot():
		start_pos = self.panda.getPos()
		end_pos = render.getRelativePoint(self.panda, Point3(0,8,0))
		start_heading = self.panda.getH()
		
		sphere = loader.loadModel("models/sphere-highpoly")
		sphere.setScale(.2)
		sphere.setPos(start_pos)
		sphere.setH(start_heading)
		
		sphere_lerp_pos = LerpPosInterval(sphere, duration=2.0, pos=end_pos, startPos=start_pos)
		sphere_seq = Sequence(sphere_lerp_pos, Func(sphere.removeNode)).start()
		
app.camera.setPos(20,20,20)
app.camera.lookAt(0,0,0)

app.run() 

hello i have completed the firing of bullets by using the code mentioned above by HOLLOWER. Then how can i find the collision of bullets with the object?? plz help me…

first you have to set collision nodes
def setupCollisions(self):
self.collTrav = CollisionTraverser()

    # rapid collisions detected using below plus FLUID pos
    self.collTrav.setRespectPrevTransform(True)

    self.playerGroundSphere = CollisionSphere(0,1.5,-1.5,1.5)
    self.playerGroundCol = CollisionNode('playerSphere')
    self.playerGroundCol.addSolid(self.playerGroundSphere)

    # bitmasks
    self.playerGroundCol.setFromCollideMask(BitMask32.bit(0))
    self.playerGroundCol.setIntoCollideMask(BitMask32.allOff())
    self.world.setGroundMask(BitMask32.bit(0))
    self.world.setWaterMask(BitMask32.bit(0))

    # and done
    self.playerGroundColNp = self.player.attach(self.playerGroundCol)
    self.playerGroundHandler = CollisionHandlerQueue()
    self.collTrav.addCollider(self.playerGroundColNp, self.playerGroundHandler)

    # DEBUG 
    if (self.debug == True):
        self.playerGroundColNp.show()
        self.collTrav.showCollisions(self.render)