def attack(self, render, time): if time - self.shootTimeDelayNow >= ( self.shootTimeDelay if not self.has_a_gun else self.gun. seconde_between_shoot) and self.shoot_or_not_decision > 0.5: theta = self.shoot_decision shootammo = Actor("model_territory/ammo2") shootammo.reparentTo(render) shootammo.setPos(self.getPos() + (cos(theta) * 1.5, sin(theta) * 1.5, 5)) #print(shootammo.getPos()) shootammo.setScale(4) shootammo.setColor(1, 0., 0, 1.0) if not self.has_a_gun: shootammo.dammage = random.randint(2, 8) else: shootammo.dammage = random.randint(self.gun.min_damage, self.gun.max_damage) shootammo.id = self.id shootammo.x_origine = shootammo.getX() shootammo.y_origine = shootammo.getY() shootammo.time = time shootammo.r = 4 shootammo.theta = theta shootammo.number = self.ammonumber shootammo.hit = False a = shootammo.attach_new_node( CollisionNode('ammo/' + str(self.id) + '/' + str(self.ammonumber))) a.node().addSolid(CollisionSphere(0, 0, 0, 0.5)) a.show() #print(shootammo.getTightBounds()) self.shoot.append(shootammo) self.shootTimeDelayNow = time self.ammonumber += 1
class Walker (PhysicalObject): collide_bits = SOLID_COLLIDE_BIT def __init__(self, incarnator, colordict=None, player=False): super(Walker, self).__init__() self.spawn_point = incarnator self.on_ground = False self.mass = 150.0 # 220.0 for heavy self.xz_velocity = Vec3(0, 0, 0) self.y_velocity = Vec3(0, 0, 0) self.factors = { 'forward': 7.5, 'backward': -7.5, 'left': 2.0, 'right': -2.0, 'crouch': 0.0, } self.movement = { 'forward': 0.0, 'backward': 0.0, 'left': 0.0, 'right': 0.0, 'crouch': 0.0, } self.head_height = Vec3(0, 1.5, 0) self.collides_with = MAP_COLLIDE_BIT | SOLID_COLLIDE_BIT self.grenade_loaded = False self.energy = 1.0 self.left_gun_charge = 1.0 self.right_gun_charge = 1.0 self.primary_color = [1,1,1,1] self.colordict = colordict if colordict else None self.crouching = False self.player = player self.can_jump = False self.crouch_impulse = 0 def get_model_part(self, obj_name): return self.actor.find("**/%s" % obj_name) def create_node(self): self.actor = Actor('walker.egg') if self.colordict: self.setup_color(self.colordict) self.actor.set_pos(*self.spawn_point.pos) self.actor.look_at(*self.spawn_point.heading) self.spawn_point.was_used() self.left_barrel_joint = self.actor.exposeJoint(None, 'modelRoot', 'left_barrel_bone') self.right_barrel_joint = self.actor.exposeJoint(None, 'modelRoot', 'right_barrel_bone') return self.actor def create_solid(self): walker_capsule = BulletGhostNode(self.name + "_walker_cap") self.walker_capsule_shape = BulletCylinderShape(.7, .2, YUp) walker_bullet_np = self.actor.attach_new_node(walker_capsule) walker_bullet_np.node().add_shape(self.walker_capsule_shape) walker_bullet_np.node().set_kinematic(True) walker_bullet_np.set_pos(0,1.5,0) walker_bullet_np.wrt_reparent_to(self.actor) self.world.physics.attach_ghost(walker_capsule) walker_bullet_np.node().setIntoCollideMask(GHOST_COLLIDE_BIT) return None def setup_shape(self, gnodepath, bone, pname): shape = BulletConvexHullShape() gnode = gnodepath.node() geom = gnode.get_geom(0) shape.add_geom(geom) node = BulletRigidBodyNode(self.name + pname) np = self.actor.attach_new_node(node) np.node().add_shape(shape) np.node().set_kinematic(True) np.wrt_reparent_to(bone) self.world.physics.attach_rigid_body(node) return np def setup_color(self, colordict): if colordict.has_key('barrel_color'): color = colordict['barrel_color'] self.get_model_part('left_barrel').setColor(*color) self.get_model_part('right_barrel').setColor(*color) if colordict.has_key('visor_color'): self.get_model_part('visor').setColor(*colordict['visor_color']) if colordict.has_key('body_primary_color'): color = colordict['body_primary_color'] self.primary_color = color for part in ['hull_primary', 'rt_leg_primary', 'lt_leg_primary', 'lb_leg_primary', 'rb_leg_primary', 'left_barrel_ring', 'right_barrel_ring', 'hull_bottom']: self.get_model_part(part).setColor(*color) if colordict.has_key('body_secondary_color'): color = colordict['body_secondary_color'] for part in ['hull_secondary', 'visor_stripe', 'rb_leg_secondary', 'rt_leg_secondary', 'lb_leg_secondary', 'lt_leg_secondary']: self.get_model_part(part).setColor(*color) return def attached(self): self.integrator = Integrator(self.world.gravity) self.world.register_collider(self) self.world.register_updater(self) left_bones = LegBones( self.world.render, self.world.physics, self.actor.exposeJoint(None, 'modelRoot', 'left_hip_bone'), self.actor.exposeJoint(None, 'modelRoot', 'left_foot_bone'), *[self.actor.controlJoint(None, 'modelRoot', name) for name in ['left_top_bone', 'left_bottom_bone']] ) right_bones = LegBones( self.world.render, self.world.physics, self.actor.exposeJoint(None, 'modelRoot', 'right_hip_bone'), self.actor.exposeJoint(None, 'modelRoot', 'right_foot_bone'), *[self.actor.controlJoint(None, 'modelRoot', name) for name in ['right_top_bone', 'right_bottom_bone']] ) self.skeleton = Skeleton(left_bones, right_bones, self.actor.controlJoint(None, 'modelRoot', 'pelvis_bone')) self.skeleton.setup_footsteps(self.world.audio3d) self.head_bone = self.actor.controlJoint(None, 'modelRoot', 'head_bone') self.head_bone_joint = self.actor.exposeJoint(None, 'modelRoot', 'head_bone') self.loaded_missile = Hat(self.head_bone_joint, self.primary_color) self.loaded_grenade = Sack(self.head_bone_joint, self.primary_color) if self.player: self.sights = Sights(self.left_barrel_joint, self.right_barrel_joint, self.world.render, self.world.physics) def collision(self, other, manifold, first): world_pt = manifold.get_position_world_on_a() if first else manifold.get_position_world_on_b() print self, 'HIT BY', other, 'AT', world_pt def handle_command(self, cmd, pressed): if cmd is 'crouch' and pressed: self.crouching = True if self.on_ground: self.can_jump = True if cmd is 'crouch' and not pressed and self.on_ground and self.can_jump: self.crouching = False self.y_velocity = Vec3(0, 6.8, 0) self.can_jump = False if cmd is 'fire' and pressed: self.handle_fire() return if cmd is 'missile' and pressed: if self.loaded_grenade.can_fire(): self.loaded_grenade.toggle_visibility() self.loaded_missile.toggle_visibility() return if cmd is 'grenade' and pressed: if self.loaded_missile.can_fire(): self.loaded_missile.toggle_visibility() self.loaded_grenade.toggle_visibility() return if cmd is 'grenade_fire' and pressed: if self.loaded_missile.can_fire(): self.loaded_missile.toggle_visibility() if not self.loaded_grenade.can_fire(): self.loaded_grenade.toggle_visibility() walker_v = Vec3(self.xz_velocity) walker_v.y = self.y_velocity.y self.loaded_grenade.fire(self.world, walker_v) return self.movement[cmd] = self.factors[cmd] if pressed else 0.0 def handle_fire(self): if self.loaded_missile.can_fire(): self.loaded_missile.fire(self.world) elif self.loaded_grenade.can_fire(): walker_v = self.xz_velocity walker_v.y = self.y_velocity.y self.loaded_grenade.fire(self.world, walker_v) else: p_energy = 0 hpr = 0 if self.left_gun_charge > self.right_gun_charge: origin = self.left_barrel_joint.get_pos(self.world.render) hpr = self.left_barrel_joint.get_hpr(self.world.render) p_energy = self.left_gun_charge if p_energy < MIN_PLASMA_CHARGE: return self.left_gun_charge = 0 else: origin = self.right_barrel_joint.get_pos(self.world.render) hpr = self.right_barrel_joint.get_hpr(self.world.render) p_energy = self.right_gun_charge if p_energy < MIN_PLASMA_CHARGE: return self.right_gun_charge = 0 hpr.y += 180 plasma = self.world.attach(Plasma(origin, hpr, p_energy)) def st_result(self, cur_pos, new_pos): return self.world.physics.sweepTestClosest(self.walker_capsule_shape, cur_pos, new_pos, self.collides_with, 0) def update(self, dt): dt = min(dt, 0.2) # let's just temporarily assume that if we're getting less than 5 fps, dt must be wrong. yaw = self.movement['left'] + self.movement['right'] self.rotate_by(yaw * dt * 60, 0, 0) walk = self.movement['forward'] + self.movement['backward'] start = self.position() cur_pos_ts = TransformState.make_pos(self.position() + self.head_height) if self.on_ground: friction = DEFAULT_FRICTION else: friction = AIR_FRICTION speed = walk pos = self.position() self.move_by(0, 0, speed) direction = self.position() - pos newpos, self.xz_velocity = Friction(direction, friction).integrate(pos, self.xz_velocity, dt) self.move(newpos) # Cast a ray from just above our feet to just below them, see if anything hits. pt_from = self.position() + Vec3(0, 1, 0) pt_to = pt_from + Vec3(0, -1.1, 0) result = self.world.physics.ray_test_closest(pt_from, pt_to, MAP_COLLIDE_BIT | SOLID_COLLIDE_BIT) #this should return 'on ground' information self.skeleton.update_legs(walk, dt, self.world.render, self.world.physics) if self.y_velocity.get_y() <= 0 and result.has_hit(): self.on_ground = True self.crouch_impulse = self.y_velocity.y self.y_velocity = Vec3(0, 0, 0) self.move(result.get_hit_pos()) else: self.on_ground = False current_y = Point3(0, self.position().get_y(), 0) y, self.y_velocity = self.integrator.integrate(current_y, self.y_velocity, dt) self.move(self.position() + (y - current_y)) if self.crouching and self.skeleton.crouch_factor < 1: self.skeleton.crouch_factor += (dt*60)/10 self.skeleton.update_legs(0, dt, self.world.render, self.world.physics) elif not self.crouching and self.skeleton.crouch_factor > 0: self.skeleton.crouch_factor -= (dt*60)/10 self.skeleton.update_legs(0, dt, self.world.render, self.world.physics) #if self.crouch_impulse < 0: goal = self.position() adj_dist = abs((start - goal).length()) new_pos_ts = TransformState.make_pos(self.position() + self.head_height) sweep_result = self.st_result(cur_pos_ts, new_pos_ts) count = 0 while sweep_result.has_hit() and count < 10: moveby = sweep_result.get_hit_normal() self.xz_velocity = -self.xz_velocity.cross(moveby).cross(moveby) moveby.normalize() moveby *= adj_dist * (1 - sweep_result.get_hit_fraction()) self.move(self.position() + moveby) new_pos_ts = TransformState.make_pos(self.position() + self.head_height) sweep_result = self.st_result(cur_pos_ts, new_pos_ts) count += 1 if self.energy > WALKER_MIN_CHARGE_ENERGY: if self.left_gun_charge < 1: self.energy -= WALKER_ENERGY_TO_GUN_CHARGE[0] self.left_gun_charge += WALKER_ENERGY_TO_GUN_CHARGE[1] else: self.left_gun_charge = math.floor(self.left_gun_charge) if self.right_gun_charge < 1: self.energy -= WALKER_ENERGY_TO_GUN_CHARGE[0] self.right_gun_charge += WALKER_ENERGY_TO_GUN_CHARGE[1] else: self.right_gun_charge = math.floor(self.right_gun_charge) if self.energy < 1: self.energy += WALKER_RECHARGE_FACTOR * (dt) if self.player: self.sights.update(self.left_barrel_joint, self.right_barrel_joint)
class Walker (PhysicalObject): collide_bits = SOLID_COLLIDE_BIT def __init__(self, incarnator, colordict=None, player=False): super(Walker, self).__init__() self.spawn_point = incarnator self.on_ground = False self.mass = 150.0 # 220.0 for heavy self.xz_velocity = Vec3(0, 0, 0) self.y_velocity = Vec3(0, 0, 0) self.factors = { 'forward': 7.5, 'backward': -7.5, 'left': 2.0, 'right': -2.0, 'crouch': 0.0, } self.movement = { 'forward': 0.0, 'backward': 0.0, 'left': 0.0, 'right': 0.0, 'crouch': 0.0, } self.head_height = Vec3(0, 1.5, 0) self.collides_with = MAP_COLLIDE_BIT | SOLID_COLLIDE_BIT self.grenade_loaded = False self.energy = 1.0 self.left_gun_charge = 1.0 self.right_gun_charge = 1.0 self.primary_color = [1,1,1,1] self.colordict = colordict if colordict else None self.crouching = False self.player = player self.can_jump = False self.crouch_impulse = 0 def get_model_part(self, obj_name): return self.actor.find("**/%s" % obj_name) def create_node(self): self.actor = Actor('walker.egg') if self.colordict: self.setup_color(self.colordict) self.actor.set_pos(*self.spawn_point.pos) self.actor.look_at(*self.spawn_point.heading) self.spawn_point.was_used() self.left_barrel_joint = self.actor.exposeJoint(None, 'modelRoot', 'left_barrel_bone') self.right_barrel_joint = self.actor.exposeJoint(None, 'modelRoot', 'right_barrel_bone') return self.actor def create_solid(self): walker_capsule = BulletGhostNode(self.name + "_walker_cap") self.walker_capsule_shape = BulletCylinderShape(.7, .2, YUp) walker_bullet_np = self.actor.attach_new_node(walker_capsule) walker_bullet_np.node().add_shape(self.walker_capsule_shape) walker_bullet_np.node().set_kinematic(True) walker_bullet_np.set_pos(0,1.5,0) walker_bullet_np.wrt_reparent_to(self.actor) self.world.physics.attach_ghost(walker_capsule) walker_bullet_np.node().setIntoCollideMask(GHOST_COLLIDE_BIT) return None def setup_shape(self, gnodepath, bone, pname): shape = BulletConvexHullShape() gnode = gnodepath.node() geom = gnode.get_geom(0) shape.add_geom(geom) node = BulletRigidBodyNode(self.name + pname) np = self.actor.attach_new_node(node) np.node().add_shape(shape) np.node().set_kinematic(True) np.wrt_reparent_to(bone) self.world.physics.attach_rigid_body(node) return np def setup_color(self, colordict): if colordict.has_key('barrel_color'): color = colordict['barrel_color'] self.get_model_part('left_barrel').setColor(*color) self.get_model_part('right_barrel').setColor(*color) if colordict.has_key('visor_color'): self.get_model_part('visor').setColor(*colordict['visor_color']) if colordict.has_key('body_primary_color'): color = colordict['body_primary_color'] self.primary_color = color for part in ['hull_primary', 'rt_leg_primary', 'lt_leg_primary', 'lb_leg_primary', 'rb_leg_primary', 'left_barrel_ring', 'right_barrel_ring', 'hull_bottom']: self.get_model_part(part).setColor(*color) if colordict.has_key('body_secondary_color'): color = colordict['body_secondary_color'] for part in ['hull_secondary', 'visor_stripe', 'rb_leg_secondary', 'rt_leg_secondary', 'lb_leg_secondary', 'lt_leg_secondary']: self.get_model_part(part).setColor(*color) return def attached(self): self.integrator = Integrator(self.world.gravity) #self.world.register_collider(self) self.world.register_updater(self) pelvis_bone = self.actor.controlJoint(None, 'modelRoot', 'pelvis_bone') left_foot_bone = self.actor.exposeJoint(None, 'modelRoot', 'left_foot_bone') left_foot_bone_origin_ref = self.actor.attach_new_node("left_foot_reference") left_foot_bone_origin_ref.set_pos(left_foot_bone.get_pos()) #pelvis_bone.attach_new_node(left_foot_bone_origin_ref) right_foot_bone = self.actor.exposeJoint(None, 'modelRoot', 'right_foot_bone') right_foot_bone_origin_ref = self.actor.attach_new_node("right_foot_reference") right_foot_bone_origin_ref.set_pos(right_foot_bone.get_pos()) #pelvis_bone.attach_new_node(right_foot_bone_origin_ref) left_bones = LegBones( self.world.scene, self.world.physics, self.actor.exposeJoint(None, 'modelRoot', 'left_hip_bone'), left_foot_bone, left_foot_bone_origin_ref, *[self.actor.controlJoint(None, 'modelRoot', name) for name in ['left_top_bone', 'left_bottom_bone']] ) right_bones = LegBones( self.world.scene, self.world.physics, self.actor.exposeJoint(None, 'modelRoot', 'right_hip_bone'), right_foot_bone, right_foot_bone_origin_ref, *[self.actor.controlJoint(None, 'modelRoot', name) for name in ['right_top_bone', 'right_bottom_bone']] ) self.skeleton = Skeleton(left_bones, right_bones, pelvis_bone) self.skeleton.setup_footsteps(self.world.audio3d) self.head_bone = self.actor.controlJoint(None, 'modelRoot', 'head_bone') self.head_bone_joint = self.actor.exposeJoint(None, 'modelRoot', 'head_bone') self.loaded_missile = LoadedMissile(self.head_bone_joint, self.primary_color) self.loaded_grenade = LoadedGrenade(self.head_bone_joint, self.primary_color) if self.player: self.sights = Sights(self.left_barrel_joint, self.right_barrel_joint, self.world) def collision(self, other, manifold, first): world_pt = manifold.get_position_world_on_a() if first else manifold.get_position_world_on_b() print self, 'HIT BY', other, 'AT', world_pt def handle_command(self, cmd, pressed): if cmd is 'crouch' and pressed: self.crouching = True if self.on_ground: self.can_jump = True if cmd is 'crouch' and not pressed and self.on_ground and self.can_jump: self.crouching = False self.y_velocity = Vec3(0, 6.8, 0) self.can_jump = False if cmd is 'fire' and pressed: self.handle_fire() return if cmd is 'missile' and pressed: if self.loaded_grenade.can_fire(): self.loaded_grenade.toggle_visibility() self.loaded_missile.toggle_visibility() return if cmd is 'grenade' and pressed: if self.loaded_missile.can_fire(): self.loaded_missile.toggle_visibility() self.loaded_grenade.toggle_visibility() return if cmd is 'grenade_fire' and pressed: if self.loaded_missile.can_fire(): self.loaded_missile.toggle_visibility() if not self.loaded_grenade.can_fire(): self.loaded_grenade.toggle_visibility() walker_v = Vec3(self.xz_velocity) walker_v.y = self.y_velocity.y self.loaded_grenade.fire(self.world, walker_v) return self.movement[cmd] = self.factors[cmd] if pressed else 0.0 def handle_fire(self): if self.loaded_missile.can_fire(): self.loaded_missile.fire(self.world) elif self.loaded_grenade.can_fire(): walker_v = self.xz_velocity walker_v.y = self.y_velocity.y self.loaded_grenade.fire(self.world, walker_v) else: p_energy = 0 hpr = 0 if self.left_gun_charge > self.right_gun_charge: origin = self.left_barrel_joint.get_pos(self.world.scene) hpr = self.left_barrel_joint.get_hpr(self.world.scene) p_energy = self.left_gun_charge if p_energy < MIN_PLASMA_CHARGE: return self.left_gun_charge = 0 else: origin = self.right_barrel_joint.get_pos(self.world.scene) hpr = self.right_barrel_joint.get_hpr(self.world.scene) p_energy = self.right_gun_charge if p_energy < MIN_PLASMA_CHARGE: return self.right_gun_charge = 0 hpr.y += 180 plasma = self.world.attach(Plasma(origin, hpr, p_energy)) def st_result(self, cur_pos, new_pos): return self.world.physics.sweepTestClosest(self.walker_capsule_shape, cur_pos, new_pos, self.collides_with, 0) def update(self, dt): dt = min(dt, 0.2) # let's just temporarily assume that if we're getting less than 5 fps, dt must be wrong. yaw = self.movement['left'] + self.movement['right'] self.rotate_by(yaw * dt * 60, 0, 0) walk = self.movement['forward'] + self.movement['backward'] start = self.position() cur_pos_ts = TransformState.make_pos(self.position() + self.head_height) if self.on_ground: friction = DEFAULT_FRICTION else: friction = AIR_FRICTION #to debug walk cycle (stay in place) #riction = 0 speed = walk pos = self.position() self.move_by(0, 0, speed) direction = self.position() - pos newpos, self.xz_velocity = Friction(direction, friction).integrate(pos, self.xz_velocity, dt) self.move(newpos) # Cast a ray from just above our feet to just below them, see if anything hits. pt_from = self.position() + Vec3(0, 1, 0) pt_to = pt_from + Vec3(0, -1.1, 0) result = self.world.physics.ray_test_closest(pt_from, pt_to, MAP_COLLIDE_BIT | SOLID_COLLIDE_BIT) # this should return 'on ground' information self.skeleton.update_legs(walk, dt, self.world.scene, self.world.physics) if self.y_velocity.get_y() <= 0 and result.has_hit(): self.on_ground = True self.crouch_impulse = self.y_velocity.y self.y_velocity = Vec3(0, 0, 0) self.move(result.get_hit_pos()) self.skeleton.left_leg_on_ground = True self.skeleton.right_leg_on_ground = True else: self.on_ground = False current_y = Point3(0, self.position().get_y(), 0) y, self.y_velocity = self.integrator.integrate(current_y, self.y_velocity, dt) self.move(self.position() + (y - current_y)) if self.crouching and self.skeleton.crouch_factor < 1: self.skeleton.crouch_factor += (dt*60)/10 self.skeleton.update_legs(0, dt, self.world.scene, self.world.physics) elif not self.crouching and self.skeleton.crouch_factor > 0: self.skeleton.crouch_factor -= (dt*60)/10 self.skeleton.update_legs(0, dt, self.world.scene, self.world.physics) #if self.crouch_impulse < 0: goal = self.position() adj_dist = abs((start - goal).length()) new_pos_ts = TransformState.make_pos(self.position() + self.head_height) sweep_result = self.st_result(cur_pos_ts, new_pos_ts) count = 0 while sweep_result.has_hit() and count < 10: moveby = sweep_result.get_hit_normal() self.xz_velocity = -self.xz_velocity.cross(moveby).cross(moveby) moveby.normalize() moveby *= adj_dist * (1 - sweep_result.get_hit_fraction()) self.move(self.position() + moveby) new_pos_ts = TransformState.make_pos(self.position() + self.head_height) sweep_result = self.st_result(cur_pos_ts, new_pos_ts) count += 1 if self.energy > WALKER_MIN_CHARGE_ENERGY: if self.left_gun_charge < 1: self.energy -= WALKER_ENERGY_TO_GUN_CHARGE[0] self.left_gun_charge += WALKER_ENERGY_TO_GUN_CHARGE[1] else: self.left_gun_charge = math.floor(self.left_gun_charge) if self.right_gun_charge < 1: self.energy -= WALKER_ENERGY_TO_GUN_CHARGE[0] self.right_gun_charge += WALKER_ENERGY_TO_GUN_CHARGE[1] else: self.right_gun_charge = math.floor(self.right_gun_charge) if self.energy < 1: self.energy += WALKER_RECHARGE_FACTOR * (dt) if self.player: self.sights.update(self.left_barrel_joint, self.right_barrel_joint)
class Hobot: max_speed = 0.25 acceleration = 0.5 deceleration = 0.5 def __init__(self, anim_root): self.move_root = base.render.attach_new_node('hobot') self.anim_root = anim_root self.model = Actor('hobot/hobot.bam') self.hand = self.model.expose_joint(None, 'modelRoot', 'hand') head = self.model.expose_joint(None, 'modelRoot', 'head') self.model.reparent_to(self.anim_root) self.model.set_two_sided(True) self.model.find("**/+GeomNode").set_transform( self.model.get_joint_transform_state('modelRoot', 'hobot root').get_inverse()) self.model.set_z(0.1) self.facing = 1.0 self.move_control = self.model.get_anim_control('move_forward') self.speed = 0.0 self.locked = True self.model.wrt_reparent_to(self.move_root) self.model.hide() light_texture = loader.load_texture('hobot/light_on.png') light_texture.set_wrap_u(core.SamplerState.WM_clamp) light_texture.set_wrap_v(core.SamplerState.WM_clamp) cm = core.CardMaker('card') cm.set_frame(-0.15, 0.15, 0.15, 0.45) self.lightbulb = head.attach_new_node(cm.generate()) self.lightbulb.set_texture(light_texture) self.lightbulb.set_attrib( core.ColorBlendAttrib.make(core.ColorBlendAttrib.M_add, core.ColorBlendAttrib.O_incoming_alpha, core.ColorBlendAttrib.O_one)) self.lightbulb.set_depth_test(False) self.lightbulb.set_bin('fixed', 0) self.lightbulb.set_p(-90) self.lightbulb.set_billboard_point_eye() self.lightbulb.set_two_sided(True) self.lightbulb.hide() shadow_texture = loader.load_texture('hobot/drop_shadow.png') shadow_texture.set_wrap_u(core.SamplerState.WM_clamp) shadow_texture.set_wrap_v(core.SamplerState.WM_clamp) cm = core.CardMaker('card') cm.set_frame(-0.35, 0.35, -0.45, -0.1) self.shadow = self.model.attach_new_node(cm.generate()) self.shadow.set_texture(shadow_texture) self.shadow.set_attrib( core.ColorBlendAttrib.make( core.ColorBlendAttrib.M_add, core.ColorBlendAttrib.O_zero, core.ColorBlendAttrib.O_one_minus_incoming_alpha)) self.shadow.set_p(-90) self.shadow.set_depth_write(False) self.shadow.set_x(0.2) self.shadow.set_billboard_point_eye() self.shadow.set_two_sided(True) self.shadow.set_bin('transparent', 0) self.shadow.set_alpha_scale(0) self.shadow_fade = None self.ding_sfx = loader.load_sfx('hobot/sfx/ding.wav') self.ding_sfx.set_volume(0.5) self.move_sfx = loader.load_sfx('hobot/sfx/move.wav') self.move_sfx.set_loop(True) self.action_callback = None def destroy(self): if self.move_control.playing: self.move_control.stop() self.move_sfx.stop() # RIP hobot :-( self.model.cleanup() def set_action(self, callback): self.action_callback = callback if self.lightbulb.is_hidden(): self.ding_sfx.play() self.lightbulb.show() def clear_action(self): self.action_callback = None self.lightbulb.hide() def do_action(self): if self.action_callback: self.action_callback() def lock(self): #self.model.wrt_reparent_to(self.anim_root) self.locked = True self.speed = 0.0 def unlock(self): self.model.set_pos(self.anim_root.get_pos()) self.locked = False self.model.set_hpr(0, 0, -90) self.model.show() def face(self, dir): if dir: self.facing = 1 if dir > 0 else -1 self.model.set_sz(self.facing * -self.model.get_sx()) def process_input(self, input, dt, level): if self.locked: return if input.get_action('interact'): self.do_action() move_x = input.get_axis('move-horizontal') move_y = input.get_axis('move-vertical') if move_x: self.speed += move_x * self.acceleration * dt self.face(move_x) elif self.speed > 0: self.speed = max(0, self.speed - self.deceleration * dt) elif self.speed < 0: self.speed = min(0, self.speed + self.deceleration * dt) delta = core.Vec2(0, 0) if move_y: delta.y = move_y * dt * MOVE_Y_SPEED if self.speed != 0: if self.speed > self.max_speed: self.speed = self.max_speed elif self.speed < -self.max_speed: self.speed = -self.max_speed delta.x = self.speed * dt pos_changed = True self.move_control.set_play_rate(self.speed * self.facing * 4.0) if not self.move_control.playing: self.move_control.loop(False) self.move_sfx.play() elif self.move_control.playing: self.move_control.stop() self.move_sfx.stop() if delta.length_squared() > 0: old_pos = self.model.get_pos() new_pos = level.adjust_move(old_pos.xy, delta) self.model.set_pos(core.LPoint3(new_pos, old_pos.z))