Panda3D Game Jam 2022!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

321 lines
13 KiB

from panda3d.core import NodePath, Vec3, TransformState, Point3
from panda3d.bullet import BulletVehicle, BulletBoxShape, ZUp
from panda3d.bullet import BulletRigidBodyNode
from random import randint
class PlayerPhysics():
def __init__(self, bullet_world, spawn_pos=(0, 0, 50)):
self.bullet_world = bullet_world
self.make_vehicle()
self.vehicle_node.set_pos(spawn_pos)
self.hook = render.attach_new_node('player_hook')
base.task_mgr.add(self.update)
self.board_speed = 0
self.in_focus = True
self.coin_frames = 0
self.total_money = 0
self.total_coins = 0
base.accept('f2', self.manual_reset)
def manual_reset(self):
self.vehicle_node.set_pos(0, 0, 50)
self.vehicle_node.set_hpr(Vec3())
def make_vehicle(self):
self.vehicle_node = vehicle_node = render.attach_new_node(BulletRigidBodyNode('sandboard_1'))
v_shape = BulletBoxShape(Vec3(1, 2, 0.1))
transform_shape_space = TransformState.make_pos(Point3(0, 0, 0))
vehicle_node.node().add_shape(v_shape, transform_shape_space)
vehicle_node.node().set_ccd_motion_threshold(0.000000007)
vehicle_node.node().set_ccd_swept_sphere_radius(0.30)
vehicle_node.node().set_deactivation_enabled(False)
vehicle_node.node().set_mass(300.0) # mass in kilograms
vehicle_node.node().set_friction(0.01)
# vehicle_node.node().set_linear_factor(3)
self.bullet_world.attach_rigid_body(vehicle_node.node())
# instantiate vehicle
self.sandboard_1 = BulletVehicle(self.bullet_world, vehicle_node.node())
self.sandboard_1.set_coordinate_system(ZUp)
self.bullet_world.attach_vehicle(self.sandboard_1)
def add_wheel(sandboard, pos, front_wheel):
wheel = sandboard.create_wheel()
wheel.set_chassis_connection_point_cs(pos)
wheel.set_front_wheel(front_wheel)
wheel.set_wheel_direction_cs(Vec3(0, 0, -1))
wheel.set_wheel_axle_cs(Vec3(1, 0, 0))
wheel.set_wheel_radius(0.4)
wheel.set_max_suspension_travel_cm(15.0)
wheel.set_suspension_stiffness(75.0)
wheel.set_wheels_damping_relaxation(2.0)
wheel.set_wheels_damping_compression(4.0)
wheel.set_friction_slip(15)
wheel.set_roll_influence(0.01)
return wheel
for p in [
(Point3(1, 2, 0), True),
(Point3(-1, 2, 0), True),
(Point3(1, -2, 0), False),
(Point3(-1, -2, 0), False),
]:
add_wheel(self.sandboard_1, *p)
# vehicle state handler begins
self.steering_increment_1 = 0.0
self.engine_force_1 = 0.0
self.brake_force_1 = 0.0
def collider_data(self, pos_1 = Vec3(), pos_2 = Vec3()):
coll = self.bullet_world.ray_test_closest(pos_1, pos_2)
out_data = [coll.get_hit_pos(), coll.get_hit_normal(), coll.get_hit_fraction(), coll.get_node()]
return out_data
def sandboard_phys(self):
v_pos = self.vehicle_node.get_pos()
self.hook.set_pos(v_pos)
self.hook.set_hpr(self.vehicle_node.get_hpr())
self.has_coin()
input_context = base.device_listener.read_context('player')
self.board_speed = self.sandboard_1.current_speed_km_hour
self.board_speed = self.board_speed / 1.61
# sandboard_1 handler begins
if input_context['accelerate']:
self.engine_force_1 = 1200
self.brake_force_1 = 0.0
if self.board_speed > 100:
self.engine_force_1 = 0
# simulate transmission/engine/air drag
if not input_context['accelerate']:
if self.board_speed > 0:
self.engine_force_1 = -50.0
if self.board_speed < 0:
self.engine_force_1 = 50.0
self.brake_force_1 = 0.0
if input_context['brake']:
self.brake_force_1 = 20.0
self.engine_force_1 = 0.0
if self.board_speed < 1:
self.brake_force_1 = 20.0
self.engine_force_1 = -2400.0
if self.board_speed < -60:
self.engine_force_1 = 0
self.brake_force_1 = 0
if input_context['steering'] == -1:
# set max steering angle
if self.steering_increment_1 < 40:
if self.board_speed < 40:
self.steering_increment_1 += 0.9
elif self.board_speed > 40:
self.steering_increment_1 += 0.45
if input_context['steering'] == 1:
# set min steering angle
if self.steering_increment_1 > -35:
if self.board_speed < 40:
self.steering_increment_1 -= 0.9
elif self.board_speed > 40:
self.steering_increment_1 -= 0.45
# relax steering to center with thermostatic feedback
if not input_context['steering'] == 1:
if not input_context['steering'] == -1:
if abs(self.steering_increment_1) < 0.2:
self.steering_increment_1 = 0
if self.steering_increment_1 > 0.25:
self.steering_increment_1 -= 0.25
if self.steering_increment_1 < -0.25:
self.steering_increment_1 += 0.25
if input_context['glide'] == 1:
self.steering_increment_1 = 0
# activate front steering
self.sandboard_1.set_steering_value(self.steering_increment_1, 0)
self.sandboard_1.set_steering_value(self.steering_increment_1, 1)
# activate front and rear power, braking
for i in range(4):
self.sandboard_1.apply_engine_force(self.engine_force_1, i)
self.sandboard_1.set_brake(self.brake_force_1, i)
# allow player to pitch the board in midair
if self.vehicle_node.get_p() < 30:
if input_context['pitchup']:
torque = Vec3(1500, 0, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
# stabilize the board pitch
if self.vehicle_node.get_p() > 20:
torque = Vec3(-2000, 0, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
if self.vehicle_node.get_p() < -20:
torque = Vec3(2000, 0, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
# ensure rotational velocity remains rational
if self.vehicle_node.get_r() < 120:
if self.vehicle_node.get_r() > -120:
r_vel = self.vehicle_node.node().angular_velocity[2]
if r_vel < -0.5:
torque = Vec3(0, 0, 3000)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
if r_vel > 0.5:
torque = Vec3(0, 0, -3000)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
if self.is_on_ground():
# stabilize the board roll
if self.vehicle_node.get_r() > 10:
torque = Vec3(0, -750, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
if self.vehicle_node.get_r() < -10:
torque = Vec3(0, 750, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
# reset the board if it turns upside down
if self.vehicle_node.get_r() > 150:
self.vehicle_node.set_hpr(Vec3())
if self.vehicle_node.get_r() < -150:
self.vehicle_node.set_hpr(Vec3())
if not self.is_on_ground():
# stabilize the board roll
if self.vehicle_node.get_r() > 10:
torque = Vec3(0, -750, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
vel = self.vehicle_node.node().get_angular_velocity()
self.vehicle_node.node().set_angular_velocity((vel[0], 0, vel[2]))
if self.vehicle_node.get_r() < -10:
torque = Vec3(0, 750, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
vel = self.vehicle_node.node().get_angular_velocity()
self.vehicle_node.node().set_angular_velocity((vel[0], 0, vel[2]))
if input_context['glide'] == 1:
if self.board_speed <= 125:
force = Vec3(0, 8000, 3000)
elif self.board_speed > 100:
force = Vec3(0, 0, 3000)
# apply the gliding forces
force = render.get_relative_vector(self.vehicle_node, force)
self.vehicle_node.node().apply_central_force(force)
# allow player to control the heading of the in-flight sandboard
if input_context['steering'] == 1:
torque = Vec3(0, 0, -750)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
elif input_context['steering'] == -1:
torque = Vec3(0, 0, 750)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
else:
torque = Vec3(0, 0, 0)
torque = render.get_relative_vector(self.vehicle_node, torque)
self.vehicle_node.node().apply_torque(torque)
def is_on_ground(self):
v_pos = self.vehicle_node.get_pos()
pos_1 = Vec3(v_pos[0], v_pos[1], v_pos[2] - 0.5)
pos_2 = Vec3(v_pos[0], v_pos[1], v_pos[2] - 2)
truth = self.collider_data(pos_1, pos_2)[3]
if 'sandboard_1' in str(truth):
return False
else:
return truth
def has_coin(self):
v_pos = self.vehicle_node.get_pos()
pos_1 = Vec3(v_pos[0], v_pos[1], v_pos[2])
pos_2 = Vec3(v_pos[0], v_pos[1] + 4, v_pos[2])
truth = self.collider_data(pos_1, pos_2)[3]
if 'silver' in str(truth):
t_str = str(truth).split(' ')
np = t_str[1]
target = render.find('**/' + np)
t_pos = target.get_pos(render)
t_pos = (round(t_pos[0], 1), round(t_pos[1], 1), round(t_pos[2], 1))
target.get_parent().detach_node()
self.bullet_world.remove(truth)
reward = randint(35000, 60000)
self.total_money += reward
money_np = aspect2d.find('**/money_info')
money_np.node().set_text('Money: ' + str(self.total_money) + ' credits')
success_np = aspect2d.find('**/success_info')
success_np.node().set_text('Congrats!' + '\n\n' + 'You found resources for the city ship!' + '\n\n' + 'The city ship will now explore area: ' + str(t_pos) + '\n\n' + 'You made ' + str(reward) + ' ' + 'credits!')
self.total_coins += 1
if self.total_coins > 7:
if success_np.is_hidden():
success_np.show()
success_np.node().set_text('Congratulations, you have just beat Sandastray!' + '\n\n' + 'Total Earnings: ' + str(self.total_money))
if 'gold' in str(truth):
t_str = str(truth).split(' ')
np = t_str[1]
target = render.find('**/' + np)
t_pos = target.get_pos(render)
t_pos = (round(t_pos[0], 1), round(t_pos[1], 1), round(t_pos[2], 1))
target.get_parent().detach_node()
self.bullet_world.remove(truth)
reward = randint(65000, 120000)
self.total_money += reward
money_np = aspect2d.find('**/money_info')
money_np.node().set_text('Money: ' + str(self.total_money) + ' credits')
success_np = aspect2d.find('**/success_info')
success_np.node().set_text('Congrats!' + '\n\n' + 'You found resources for the city ship!' + '\n\n' + 'The city ship will now explore area: ' + str(t_pos) + '\n\n' + 'You made ' + str(reward) + ' ' + 'credits!')
self.total_coins += 1
if self.total_coins > 7:
if success_np.is_hidden():
success_np.show()
success_np.node().set_text('Congratulations, you have just beat Sandastray!' + '\n\n' + 'Total Earnings: ' + str(self.total_money))
def update(self, task):
dt = base.clock.get_dt()
if self.in_focus: # quick HACK to disable input when not in focus!.
self.sandboard_phys()
return task.cont
# get
@property
def b_speed(self):
return self.board_speed