Ejemplo n.º 1
0
	def test_bind_controllers(self):
		from lepton import ParticleGroup
		ctrl1 = TestController()
		ctrl2 = TestController()
		ctrl3 = TestController()
		ctrl4 = TestController()
		group = ParticleGroup()
		self.failIf(group.controllers)

		# Can bind controllers in constructor and after
		group = ParticleGroup(controllers=(ctrl1, ctrl2))
		self.assertEqual(tuple(group.controllers), (ctrl1, ctrl2))
		group.bind_controller(ctrl3, ctrl4)
		self.assertEqual(tuple(group.controllers), (ctrl1, ctrl2, ctrl3, ctrl4))

		'''
Ejemplo n.º 2
0
    def test_bind_controllers(self):
        from lepton import ParticleGroup
        ctrl1 = TestController()
        ctrl2 = TestController()
        ctrl3 = TestController()
        ctrl4 = TestController()
        group = ParticleGroup()
        self.failIf(group.controllers)

        # Can bind controllers in constructor and after
        group = ParticleGroup(controllers=(ctrl1, ctrl2))
        self.assertEqual(tuple(group.controllers), (ctrl1, ctrl2))
        group.bind_controller(ctrl3, ctrl4)
        self.assertEqual(tuple(group.controllers),
                         (ctrl1, ctrl2, ctrl3, ctrl4))
        '''
Ejemplo n.º 3
0
class Rocket(ActiveSound, Engine):
    sound = load_sound('data/sounds/rocket.wav')

    @classmethod
    def load(cls):
        super(Rocket, cls).load()
        img = loader.image('data/sprites/rocket-spark.png')
        cls.particle_texture = img
        w = img.width
        h = img.height
        img.anchor_x = w * 0.5
        img.anchor_y = h * 0.5
        cls.particle_controllers = [
            controller.Movement(),
            controller.Lifetime(max_age=2),
            controller.Growth(30.0),
            controller.ColorBlender([
                (0, (1.0, 0.9, 0.0, 1.0)),
                (1, (0.0, 0.0, 0.0, 0.2)),
                (3, (0.0, 0.0, 0.0, 0.0)),
            ]),
            controller.Bounce(domain=domain.Plane((0, SEA_LEVEL, 0),
                                                  (0, 1, 0)),
                              bounce=0.02)
        ]
        cls.particle_renderer = Renderer(cls.particle_texture)

    MASS = 10
    BURN_TIME = 3
    FORCE = v(100000, 0)
    FUEL_CONSUMPTION = 0

    def __init__(self, *args):
        super(Rocket, self).__init__(*args)
        psystem = self.squid.world.particles
        self.particlegroup = ParticleGroup(
            renderer=self.particle_renderer,
            controllers=self.particle_controllers,
            system=psystem)

        self.emitter = None

    def __del__(self):
        self.particlegroup.system.remove_group(self.particlegroup)

    def controller(self):
        return OneTimeController(self)

    def is_enabled(self):
        return not self.active

    def set_active(self, _):
        if not self.active:
            self.time_left = self.BURN_TIME
            self.active = True
            self.on_start()

            # Stuff in any numbers for now, update later
            self.vel_domain = domain.Disc((0, 0, 0), (0, 0, 1), 100)
            self.pos_domain = domain.Cone((0, 0, 0), (-1, 0, 0), 1)
            self.template = Particle(
                size=(20.0, 20.0, 0),
                color=(1.0, 0.5, 0.0, 1.0),
            )
            self.emitter = StaticEmitter(
                position=self.pos_domain,
                velocity=self.vel_domain,
                template=self.template,
                rate=30,
                time_to_live=self.BURN_TIME,
            )
            self.particlegroup.bind_controller(self.emitter)

    def update_emitter(self, dt):
        tv = v(-100, 0).rotated(math.degrees(self.rotation))  # thrust vel
        bv = v(self.squid.body.velocity)  # body vel

        ve = (tv + bv) * 0.5  # velocity of emitted particles
        self.vel_domain.center = (ve.x, ve.y, 0)

        pos = self.position
        cone = ve * dt
        if cone.length2 < 0.001:
            cone = tv * 0.1
        base = pos + cone
        self.pos_domain.apex = (pos.x, pos.y, 0)
        self.pos_domain.base = (base.x, base.y, 0)
        self.pos_domain.outer_radius = cone.length * 0.2

    def update(self, dt):
        if self.active:
            self.time_left -= dt
            if self.time_left > 0:
                self.update_emitter(dt)
                super(Rocket, self).update(dt)
            else:
                self.on_stop()

    def draw_particles(self):
        self.particlegroup.draw()

    def draw(self):
        self.draw_particles()
        super(Rocket, self).draw()
Ejemplo n.º 4
0
class ship(object):
    def __init__(self,
                 x,
                 y,
                 z,
                 r,
                 side=-1,
                 hp=50,
                 controlable=False,
                 weapon_range=5,
                 dispersion=5,
                 agility=50,
                 weapon_base_damage=2,
                 guidance=100,
                 shortguide=0,
                 partColor=(0.6, 0.5, 0.2, 1),
                 firerate=10,
                 shots=1,
                 vo=30,
                 maxvel=10,
                 ammoMaxvel=20,
                 combatDistance=50,
                 behavior=0,
                 commander=None,
                 multipleTargets=False,
                 name="",
                 ammoDamp=0.98):
        self.name = name
        self.domain = Sphere(
            (x, y, z), r
        )  # a.center -> vector del centro , a.outer_radius -> radio externo , a.inner_radius -> radio interno
        self.size = r
        self.controller = Collector(self.domain, callback=self.contact)
        self.magnet = Magnet(self.domain, charge=guidance, exponent=shortguide)
        self.commander = commander
        self.mission = self.domain.center
        self.target = None
        self.alive = True
        self.targetMode = ['standard', 1]
        self.behavior = behavior  # 0:free 1: escort 2: slave
        self.hp = hp
        self.agility = agility
        self.maxvel = maxvel
        self.timer = {0: 0, 1: 2, 2: 0, 3: 0, 4: 0}  # timers placeholder
        self.counter = {0: 0, 1: 0}  # counters placeholder
        self.side = side
        self.combatDistance = combatDistance
        self.velocity = Vec3(0, 0, 0)
        self.multipleTargets = multipleTargets
        self.firerate = firerate
        self.weapon_base_damage = weapon_base_damage
        wbd = self.weapon_base_damage
        rr = r * 2
        self.dispersion = dispersion
        self.vo = vo
        self.ammoDamp = ammoDamp
        self.ammoMaxvel = ammoMaxvel
        self.shots = shots
        self.weapon_range = weapon_range
        self.xx = self.yy = self.zz = 0
        self.Objective = Sphere((0, 0, 0), 1)
        self.color = partColor  # (0.4,0.5,0.4,0.5)
        #self.prevController = Collector(self.domain)#DUMMY CONTROLLER
        self.controlable = controlable
        self.impacto = ParticleGroup(renderer=BillboardRenderer(texturizer),
                                     controllers=[
                                         Lifetime(1),
                                         Fader(fade_out_start=0,
                                               fade_out_end=1),
                                     ])
        self.deathplosion = ParticleGroup(
            renderer=BillboardRenderer(texturizer),
            controllers=[
                Lifetime(self.size / 5 + 1),
                Fader(fade_out_start=0, fade_out_end=self.size / 5 + 1),
            ])
        self.selector_emitter = StaticEmitter(template=Particle(
            position=(0, 0, 0),
            color=self.color,
        ))
        self.impacto_emitter = StaticEmitter(
            template=Particle(
                position=(0, 0, 0),
                color=(0.9, 0.8, 0.8),
            ),
            position=self.domain,
            #size=[(5, 5, 5), (10, 10, 10), (15, 15, 15)],
        )
        self.hull = ParticleGroup(renderer=BillboardRenderer(texturizer2),
                                  controllers=[
                                      Lifetime(100000),
                                      Movement(max_velocity=self.maxvel,
                                               damping=0.98),
                                      Magnet(self.Objective,
                                             charge=self.agility,
                                             exponent=0),
                                  ])
        emiter = StaticEmitter(position=self.domain,
                               template=Particle(
                                   color=self.color,
                                   size=(rr, rr, rr),
                               ))
        emiter.emit(1, self.hull)

        if trails:
            if maxvel / r >= 20:
                self.trail = ParticleGroup(
                    renderer=BillboardRenderer(texturizer2),
                    controllers=[
                        Lifetime(trailSize[0]),
                        Fader(fade_in_start=0,
                              fade_in_end=0.1,
                              fade_out_start=0,
                              fade_out_end=trailSize[0]),
                        Growth(-1 * r),
                        PerParticleEmitter(self.hull,
                                           rate=trailSize[1],
                                           template=Particle(
                                               color=self.color,
                                               size=(rr, rr, rr),
                                           )),
                    ])

        self.ammo = ParticleGroup(renderer=BillboardRenderer(texturizer),
                                  controllers=[
                                      self.magnet,
                                      Movement(min_velocity=0,
                                               max_velocity=self.ammoMaxvel,
                                               damping=self.ammoDamp),
                                      Lifetime(self.weapon_range),
                                      Fader(fade_out_start=self.weapon_range -
                                            1,
                                            fade_out_end=self.weapon_range),
                                  ])

        self.weapon = PerParticleEmitter(
            self.hull,  # rate=self.firerate,
            template=Particle(
                velocity=self.velocity,  # fixed value
                position=(self.getPosition()),
                color=partColor,
            ),
            position=self.domain,
            size=[(wbd * 0.5, wbd * 0.5, wbd * 0.5), (wbd, wbd, wbd),
                  (wbd * 1.5, wbd * 1.5, wbd * 1.5)],
            deviation=Particle(
                velocity=(self.dispersion, self.dispersion,
                          self.dispersion * d3),
                rotation=(0, 0, math.pi / 6),
                #color=(0.05,0.05,0.05,0),
            ))

    def nearest_enemy(self,
                      ships,
                      min_dist=99999,
                      side=-1,
                      addCollectors=False,
                      limit=10,
                      lazy=lazysearch):
        colla = 0
        target = None
        min_dist **= 2
        colld = min_dist
        if self.targetMode[0] == 'custom':
            selfRadius = self.targetMode[1]
        else:
            selfRadius = self.size
        selfAmmo = self.ammo
        if lazy != -1:
            c = lazysearch
            for ship in ships:
                if colla < limit and c > 0:
                    if ship != self and ship.side != side:
                        #var = math.fabs(ship.size - selfRadius) + 0.1
                        #var = 1 if math.fabs(ship.domain.radius - selfRadius) < selfRadius else 5
                        var = 0.1 if math.fabs(ship.size -
                                               selfRadius) < selfRadius else 2
                        dist = distance_to_ship(self, ship, squared=True) * var
                        if addCollectors:
                            if dist < colld:
                                colla += 1
                                selfAmmo.bind_controller(*[ship.controller])
                        if dist < min_dist and c > 0:
                            c -= 1
                            target = ship
                            min_dist = dist
                else:
                    break
        else:
            for ship in ships:
                if colla < limit:
                    if ship != self and ship.side != side:
                        #var = math.fabs(ship.size - selfRadius) + 0.1
                        #var = 1 if math.fabs(ship.domain.radius - selfRadius) < selfRadius else 5
                        var = 0.1 if math.fabs(ship.size -
                                               selfRadius) < selfRadius else 2
                        dist = distance_to_ship(self, ship, squared=True) * var
                        if addCollectors:
                            if dist < colld:
                                colla += 1
                                selfAmmo.bind_controller(*[ship.controller])
                        if dist < min_dist:
                            target = ship
                            min_dist = dist
                else:
                    break
        return target

    def getPosition(self):
        return (self.domain.center[0], self.domain.center[1],
                self.domain.center[2])

    def getPositionVec3(self):
        return Vec3(self.domain.center[0], self.domain.center[1],
                    self.domain.center[2])

    def contact(self, particle, group, bola):
        if self.hp > 0:
            #dam = math.ceil(particle.size[0] * (particle.color[0] + particle.color[1] + particle.color[2]))  # color-based damage
            dam = math.ceil(particle.size[0])
            self.hp -= dam
            self.impacto_emitter.template.position = self.getPosition()
            self.impacto_emitter.template.size = (dam, dam, dam)
            self.impacto_emitter.emit(1, self.impacto)
            if self.hp <= 0:
                self.color = (0.5, 0.1, 0.1)
                self.controlable = False
                self.destroy()

    def destroy(self,
                flag=True):  # flag = True if it has been destroyed in combat
        global trails
        self.alive = False
        for part in self.hull:  # remove hull particle
            self.hull.kill(part)
        if flag:  # if destroyed in combat, explode
            s = self.size
            ss = s * 10
            self.impacto_emitter.template.size = (ss, ss, ss)
            self.impacto_emitter.emit(int(2 * s + 1), self.deathplosion)
            ships.remove(self)
            battle.removeShip(self.side)

    def DirToTarget(self, target):
        direction = target.getPositionVec3() - self.getPositionVec3()
        direction = direction.normalize()
        return direction

    def targetManagement(self, ships):
        stimer = self.timer
        if stimer[2] <= 0:
            stimer[2] = random.randint(100, 500)
            if self.target == None or distance_to_ship(
                    self, self.target, squared=True) > (
                        self.weapon_range * self.ammoMaxvel * 1.5)**2:
                [
                    self.ammo.unbind_controller(i)
                    for i in self.ammo.controllers
                    if i.__class__.__name__ == "Collector"
                ]
                self.target = self.nearest_enemy(
                    ships,
                    side=self.side,
                    min_dist=self.weapon_range * self.ammoMaxvel * 1.5,
                    addCollectors=self.multipleTargets,
                    lazy=False)
                if self.target and self.target.alive:
                    self.magnet.domain = self.target.domain
                    if not self.multipleTargets:
                        self.ammo.bind_controller(*[self.target.controller
                                                    ])  # NO COLLECTOR TEST
                if self.commander and self.target == None:
                    self.mission = self.commander.getOrders(self).domain.center
        if stimer[3] <= 0:
            stimer[3] = 30
            if self.target and not self.target.alive:  # targeting a dead ship
                self.target = None
                stimer[2] = 10
        if stimer[1] <= 0 and self.target:
            for part in self.hull:
                h = part
            d = self.DirToTarget(self.target)
            self.weapon.template.velocity = d * self.vo + h.velocity
            self.weapon.emit(self.shots, self.ammo)
        stimer[2] -= 1
        stimer[3] -= 1

    def moveAround(self, ships):
        timer = self.timer
        for part in self.hull:
            self.domain.center = part.position
        timer[1] -= 1
        if timer[1] < 0:
            timer[1] = self.firerate
        if not self.controlable:
            self.targetManagement(ships)
            if timer[0] <= 0:
                timer[0] = random.randint(100, 300)
                agg = int(self.combatDistance)
                self.counter[0] += 1
                if self.counter[0] == 3:
                    agg += 100
                    self.counter[0] = 0
                self.xx = random.randint(-agg, agg)
                self.yy = random.randint(-agg, agg)
                self.zz = random.randint(-agg, agg)
            if timer[4] <= 0:
                timer[4] = 2
                if self.target and self.target.alive:
                    stdc = self.target.domain.center
                    self.Objective.center[0] = stdc[0] + self.xx
                    self.Objective.center[1] = stdc[1] + self.yy
                    if d3:
                        self.Objective.center[2] = stdc[2] + self.zz
                else:
                    if self.commander:
                        pos = self.mission
                    else:
                        pos = self.domain.center
                    self.Objective.center[0] = pos[0] + self.xx
                    self.Objective.center[1] = pos[1] + self.yy
                    if d3:
                        self.Objective.center[2] = pos[2] + self.zz
            timer[0] -= 1
            timer[4] -= 1