Skip to content

Instantly share code, notes, and snippets.

@kergalym
Last active December 30, 2021 13:00
Show Gist options
  • Save kergalym/ed34d5b9874d0b3dec28109e80f0ca4e to your computer and use it in GitHub Desktop.
Save kergalym/ed34d5b9874d0b3dec28109e80f0ca4e to your computer and use it in GitHub Desktop.
Panda3D Archery Logic
def bow_shoot(self, actor_name, arrow_name, bow_name):
""" Function : bow_shoot
Description : Performs bow shooting.
Input : Strings, Nodepath
Output : None
Return : None
"""
if actor_name and arrow_name and bow_name and self.world:
# Find actor which should do bow shoot
if render.find("**/{0}".format(actor_name)):
actor = render.find("**/{0}".format(actor_name))
# Find arrow from that actor
if actor.find("**/{0}".format(arrow_name)):
arrow = actor.find("**/{0}".format(arrow_name))
if arrow and self.aimed_target_pos and self.aimed_target_np:
bow = actor.find("**/{0}".format(bow_name))
# Start arrow trajectory
if bow:
self.trajectory = ProjectileInterval(arrow, duration=1, startPos=bow.get_pos(),
endPos=self.aimed_target_pos, gravityMult=1.0)
self.trajectory.start()
arrow.reparent_to(render)
if self.trajectory.isPlaying():
if isinstance(self.aimed_target_np, NodePath):
arrow.setCollideMask(BitMask32.allOff())
arrow.reparent_to(self.aimed_target_np)
arrow.set_h(0)
# print(arrow, arrow.get_pos())
def bow_shoot_enhanced(self, actor_name, arrow_name, bow_name):
""" Function : bow_shoot_enhanced
Description : Performs enhanced bow shooting.
Input : Strings, Nodepath
Output : None
Return : None
"""
if actor_name and arrow_name and bow_name and self.world:
# Find actor which should do bow shoot
if render.find("**/{0}".format(actor_name)):
actor = render.find("**/{0}".format(actor_name))
# Find arrow from that actor
if actor.find("**/{0}".format(arrow_name)):
arrow = actor.find("**/{0}".format(arrow_name))
# Construct arrow and start its trajectory
if arrow and self.aimed_target_pos and self.aimed_target_np:
# Calculate initial velocity
velocity = self.aimed_target_pos - actor.get_pos() + Vec3(0, 0.4, 0)
# velocity = self.aimed_target_pos - self.bow.get_pos()
velocity.normalize()
velocity *= 100.0
# Create Bullet collider for an arrow
shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))
body = BulletRigidBodyNode('Bullet')
body_np = render.attachNewNode(body)
body_np.node().addShape(shape)
body_np.node().setMass(2.0)
body_np.node().setLinearVelocity(velocity)
body_np.setPos(actor.get_pos() + (0, 0.5, 0))
body_np.setCollideMask(BitMask32.allOff())
arrow.reparent_to(body_np)
arrow.set_pos(0, 0, 0)
arrow.set_hpr(velocity)
# Enable Bullet Continuous Collision Detection
body_np.node().setCcdMotionThreshold(1e-7)
body_np.node().setCcdSweptSphereRadius(0.50)
self.world.attachRigidBody(body_np.node())
Wait(1)
arrow.setCollideMask(BitMask32.allOff())
self.world.removeRigidBody(body.node())
def calculate_arrow_trajectory_task(self, actor, task):
""" Function : calculate_arrow_trajectory_task
Description : Task calculating arrow trajectory.
Input : Strings, Nodepath
Output : None
Return : Task status
"""
if not actor:
return task.done
elif actor:
bow_name = "bow"
if "Player" in actor.get_name():
bow_name = "bow_kazakh"
arrow = actor.find("**/{0}".format(bow_name))
if arrow:
mouse_watch = base.mouseWatcherNode
if mouse_watch.has_mouse():
pos_mouse = base.mouseWatcherNode.get_mouse()
pos_from = Point3()
pos_to = Point3()
base.camLens.extrude(pos_mouse, pos_from, pos_to)
pos_from = self.render.get_relative_point(actor, pos_from)
pos_to = self.render.get_relative_point(base.camera, pos_to)
raytest_result = self.world.rayTestClosest(pos_from, pos_to)
# print(raytest_result.hasHit())
if (raytest_result.get_node()
and "Korlan" not in str(raytest_result.get_node())):
self.aimed_target_np = raytest_result.get_node()
self.aimed_target_pos = raytest_result.get_hit_pos()
# Leave this here for testing purposes
if self.aimed_target_pos:
self.target_test_ui.setText("")
name = self.aimed_target_np.get_name()
self.target_test_ui.setText("Target hit: {0}".format(name))
elif not self.aimed_target_np:
self.target_test_ui.setText("")
else:
self.target_test_ui.setText("")
return task.cont
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment