I'm using a variation of this duckcourt example, except I increased the speed and shrunk the ball so it looks like a bullet. Unfortunately the crosshair is not too accurate. I don't need pinpoint accuracy, but I would like the "bullet" to "shoot" from the middle of the crosshair. Sometimes when I shoot to the left or right, the bullet comes out from the left or right of the crosshair. I can't think of anyway to adjust this so the bullet comes out from the crosshair no matter what direction I'm shooting. Here is the code for your reference:
Code:
def MoveBullet(bullet,elapsed):
hitObject = 0
#check if bullet is colliding with an object
for object in collidables:
#perform the collision check with the object
info = bullet.collidingwith(object,1)
if info.intersected:
#set the bullets new vector to the reflection vector
bullet.vector = viz.Vector(vizmat.ReflectionVector(bullet.vector,info.normalVector))
#create a vector of the normal of the collision
normal = viz.Vector(info.normalVector)
#Check dot product of velocity and normal
if bullet.vector * normal <0:
bullet.vector*= -1
#calculate the rotation vector of the ball
bullet.rotvector = bullet.vector * rotRight
#if object.isTarget and ball.lastHit != object:
hitObject = object
#play ball bounce sound
viz.playsound('bounce.wav')
break
#get the bullet's current position
pos = bullet.get(viz.POSITION)
#calculate the balls future position based on it's velocity
futurePos = pos + (bullet.vector * elapsed)
bullet.translate(futurePos.get())
#rotate the bullet along it's rotation vector
#bullet.rotate(bullet.rotvector[0],bullet.rotvector[1],ball.rotvector[2],90*elapsed,viz.RELATIVE_WORLD)
#Update the bullet's shadow
bullet.shadow.translate(futurePos.x,0,futurePos.z)
def mytimer(num):
if num == ANIMATION:
#Calculate elapsed time since last update
elapsed = viz.elapsed()
#Update each active ball
for bullet in bullets:
if bullet.active:
#Move the ball and check if it has collided with any objects
MoveBullet(bullet,elapsed)
#Update the crosshair position
crosshair.translate(viz.mousepos()+[0])
elif num == START_AVATAR:
global nextAvatar
#Get the next available duck and start it
avatar = avatars[nextAvatar]
walkAvatar(avatar)
nextAvatar = (nextAvatar + 1) % NUM_AVATARS
viz.starttimer(START_AVATAR,TIME_BETWEEN_AVATARS)
#Shoot a ball whenever left mousebutton is clicked
vizact.onmousedown(viz.MOUSEBUTTON_LEFT,shootBullet)
#Create callbacks for timer events
viz.callback(viz.TIMER_EVENT,mytimer)
##Start a timer which starts the next available duck
viz.starttimer(START_AVATAR,0.1)
#Start the animation timer, which animates the ball and checks for collisions
viz.starttimer(ANIMATION,0.01,-1)