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)) '''
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)) '''
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()
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