Beispiel #1
0
    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
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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))