class ItemAttractorEffect(Effect): def __init__(self, lifetime, radius, force): Effect.__init__(self, lifetime) self.radius = radius self.is_collidable = True self.unique_in_target = True self.force = force self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("PowerUp") self.geometry = Circle(self.radius) self.collision_object.set_shape(self.geometry) self.collision_object.AddCollisionLogic("PowerUp", BasicColLogic(self) ) def Apply(self, dt): self.SetPos( self.target.GetPos() ) def HandleCollision(self, coltarget): if coltarget.CheckType("PowerUp"): # we can collide with any powerup or collidable effect, however we only affect powerups (the actual item)... v = self.GetPos() - coltarget.GetPos() v = v.Normalize() v = v * self.force coltarget.ApplyVelocity(v) def GetDetailString(self): return "Attracting Items"
class MatterAbsorptionEffect(Effect): def __init__(self, duration, life_absorbed_percent, energy_absorbed_percent): Effect.__init__(self, duration) self.life_absorbed_percent = life_absorbed_percent self.energy_absorbed_percent = energy_absorbed_percent self.is_collidable = True self.unique_in_target = True self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("PowerUp") self.geometry = Circle(1.0) self.geometry.thisown = 0 self.collision_object.set_shape( self.geometry ) self.life_hud = None def OnSceneAdd(self, scene): self.radius = self.target.size.get_y() /2.0 self.size = Vector2D(self.radius*2, self.radius*2) texture_name = "images/shockwave.png" texture_obj = Engine_reference().resource_manager().texture_container().Load(texture_name, texture_name) self.shape = TexturedRectangle( texture_obj, self.size ) self.shape.set_hotspot(Drawable.CENTER) self.node.set_drawable(self.shape) color = self.node.modifier().color() color.set_a(0.5) self.node.modifier().set_color(color) self.target.invulnerable = True self.geometry = Circle(self.radius) self.collision_object.set_shape(self.geometry) self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.life_hud = BarUI(self, "lifetime", Color(0.85,0.0,0.85,1.0), -(self.radius+BAR_SIZE), True) self.hud_node.AddChild(self.life_hud.node) def Apply(self, dt): self.SetPos( self.target.GetPos() ) self.target.invulnerable = True if self.life_hud != None: self.life_hud.Update() def HandleCollision(self, coltarget): if hasattr(coltarget, "GetGroup") and coltarget.GetGroup() != self.target.GetGroup() and coltarget.GetGroup() != Group.NEUTRAL: if coltarget.CheckType("Asteroid"): self.target.Heal(coltarget.life * self.life_absorbed_percent) elif coltarget.CheckType("Projectile"): self.target.RestoreEnergy(coltarget.GetDamage(self.target.type) * self.energy_absorbed_percent) coltarget.TakeDamage(coltarget.life + 10) def GetDetailString(self): return "Absorbing Matter" def Delete(self): Effect.Delete(self) if self.target != None: self.target.invulnerable = False
class RangeCheck(EntityInterface): def __init__(self, x, y, radius, target_type): EntityInterface.__init__(self, x, y, radius) self.parent = None self.target_type = target_type self.target = None self.dist = -1.0 self.setupCollisionObject() def setupCollisionObject(self): self.collision_object = CollisionObject(getCollisionManager(), self) #initialize collision object, second arg is passed to collisionlogic to handle collisions self.collision_object.InitializeCollisionClass("RangeCheck") # define the collision class self.geometry = Circle(self.radius) # self.collision_object.set_shape(self.geometry) # set our shape #finally add collision logics to whatever collision class we want self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.collision_object.thisown = 0 def GetTarget(self): return self.target def SetRadius(self, r): self.radius = r self.geometry.set_radius(r) def AttachToEntity(self, ent): self.parent = ent AddNewObjectToScene(self) def Update(self, dt): if self.parent != None: if self.parent.is_destroyed: self.Delete() else: self.SetPos(self.parent.GetPos()) if self.target != None: if self.target.is_destroyed: self.target = None self.dist = -1.0 else: self.dist = self.GetDistTo(self.target) def GetDistTo(self, ent): d = self.GetPos() - ent.GetPos() return d.Length() def HandleCollision(self, coltarget): if coltarget.CheckType(self.target_type): d = self.GetDistTo(coltarget) #if self.target_type == "Asteroid" and d < 150: # print "[%s :: %s] => [%s :: %s]" % (self.target,self.dist, coltarget,d) if self.target == None or d < self.dist: self.target = coltarget self.dist = d
class PowerUp (BasicEntity): def __init__(self, x, y, texture_name, lifetime, effect, name, effectCreationFunc): r = 15.0 BasicEntity.__init__(self, x, y, texture_name, r, 1) self.life_hud.node.set_active(False) self.max_velocity = 135.0 self.lifespan = lifetime self.lifetime = lifetime self.effect = effect self.effect.creation_func = effectCreationFunc self.wasApplied = False self.blink_time = 0.0 self.text = Engine_reference().text_manager().GetText(name) self.textNode = Node(self.text) self.textNode.modifier().set_offset( Vector2D(-self.text.width()/2.0, 0.0 ) ) # TODO: text hotspot! self.textNode.set_active(False) self.node.AddChild(self.textNode) def setupCollisionObject(self): self.collision_object = CollisionObject(getCollisionManager(), self) #initialize collision object, second arg is passed to collisionlogic to handle collisions self.collision_object.InitializeCollisionClass("PowerUp") # define the collision class self.collision_object.set_shape(self.geometry) # set our shape self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.collision_object.thisown = 0 def Update(self, dt): if not self.wasApplied: BasicEntity.Update(self, dt) self.lifetime -= dt if self.lifetime < self.lifespan*0.15 and not self.wasApplied: self.blink_time += dt if self.blink_time > self.lifetime/self.lifespan: self.blink_time = 0.0 self.node.set_active( not self.node.active() ) if self.lifetime < 0: self.Delete() def HandleCollision(self, target): if target.CheckType("Ship") and not self.wasApplied: self.effect.SetTarget(target) target.ApplyEffect(self.effect) self.wasApplied = True self.lifetime = 3.0 self.textNode.set_active(True) color = self.node.modifier().color() color.set_a(0.2) self.node.modifier().set_color(color) self.node.set_active(True)
def setupCollisionObject(self): self.collision_object = CollisionObject(getCollisionManager(), self) #initialize collision object, second arg is passed to collisionlogic to handle collisions self.collision_object.InitializeCollisionClass("Entity") # define the collision class self.collision_object.set_shape(self.geometry) # set our shape #finally add collision logics to whatever collision class we want self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.collision_object.thisown = 0
def setupCollisionObject(self): self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("Beam") self.geometry = ConvexPolygon(self.GetVertices()) self.collision_object.set_shape(self.geometry) self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.collision_object.thisown = 0
def __init__(self, lifetime, radius, force): Effect.__init__(self, lifetime) self.radius = radius self.is_collidable = True self.unique_in_target = True self.force = force self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("PowerUp") self.geometry = Circle(self.radius) self.collision_object.set_shape(self.geometry) self.collision_object.AddCollisionLogic("PowerUp", BasicColLogic(self) )
def __init__(self, duration, life_absorbed_percent, energy_absorbed_percent): Effect.__init__(self, duration) self.life_absorbed_percent = life_absorbed_percent self.energy_absorbed_percent = energy_absorbed_percent self.is_collidable = True self.unique_in_target = True self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("PowerUp") self.geometry = Circle(1.0) self.geometry.thisown = 0 self.collision_object.set_shape( self.geometry ) self.life_hud = None
def __init__(self, life): Effect.__init__(self, 10) self.max_life = life self.life = life self.is_collidable = True self.unique_in_target = True self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("PowerUp") self.geometry = Circle(1.0) self.geometry.thisown = 0 self.collision_object.set_shape( self.geometry ) self.life_hud = None
class ShieldEffect(Effect): def __init__(self, life): Effect.__init__(self, 10) self.max_life = life self.life = life self.is_collidable = True self.unique_in_target = True self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("PowerUp") self.geometry = Circle(1.0) self.geometry.thisown = 0 self.collision_object.set_shape( self.geometry ) self.life_hud = None def GetAttrDict(self): d = Effect.GetAttrDict(self) d["life"] = self.life d["max_life"] = self.max_life return d def OnSceneAdd(self, scene): self.radius = self.target.size.get_y()/2.0 self.size = Vector2D(self.radius*2, self.radius*2) texture_name = "images/shockwave.png" texture_obj = Engine_reference().resource_manager().texture_container().Load(texture_name, texture_name) self.shape = TexturedRectangle( texture_obj, self.size ) self.shape.set_hotspot(Drawable.CENTER) self.node.set_drawable(self.shape) color = self.node.modifier().color() color.set_a(0.5) self.node.modifier().set_color(color) self.target.invulnerable = True self.geometry = Circle(self.radius) self.collision_object.set_shape(self.geometry) self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.max_life += self.target.data.GetBonusLife() self.life += self.target.data.GetBonusLife() self.life_hud = BarUI(self, "life", Color(0.85,0.85,0.85,1.0), self.radius, True) self.hud_node.AddChild(self.life_hud.node) def Apply(self, dt): self.SetPos( self.target.GetPos() ) if self.life > 0 and not self.target.is_destroyed: self.lifetime = 10.0 self.target.invulnerable = True if self.life_hud != None: self.life_hud.Update() else: self.lifetime = 0.0 self.target.invulnerable = False def HandleCollision(self, coltarget): if coltarget.CheckType("Asteroid") or (coltarget.CheckType("Projectile") and coltarget.GetGroup() != self.target.GetGroup() ): self.life -= coltarget.GetDamage(self.target.type) coltarget.TakeDamage(coltarget.life + 10) #print "SHIELD COLLISION %s/%s" % (self.life, self.max_life) def GetDetailString(self): return "Shields On" def Delete(self): Effect.Delete(self) if self.target != None: self.target.invulnerable = False
class BasicEntity (EntityInterface): nextID = 1 def __init__(self, x, y, texture_name, radius, life, WtoHratio=1.0): EntityInterface.__init__(self, x, y, radius) self.size = Vector2D(self.radius*2, self.radius*2*WtoHratio) texture_obj = Engine_reference().resource_manager().texture_container().Load(texture_name, texture_name) self.shape = TexturedRectangle( texture_obj, self.size ) self.shape.set_hotspot(Drawable.CENTER) self.node.set_drawable(self.shape) #self.text = Engine_reference().text_manager().GetText( "#"+str(self.id) ) #self.text.set_hotspot(Drawable.CENTER) #self.textNode = Node(self.text) #self.textNode.modifier().set_offset( Vector2D(0.0, -self.radius ) ) #self.hud_node.AddChild(self.textNode) self.velocity = Vector2D(0.0, 0.0) self.max_velocity = 5000.0 #length of the maximum velocity - the entity can't achieve a velocity with length greater than this by whatever means self.last_velocity = None self.last_dt = 0.000001 self.life = life self.max_life = life self.hit_sounds = ["hit1.wav", "hit2.wav", "hit3.wav", "hit4.wav"] self.life_hud = BarUI(self, "life", Color(1.0,0.0,0.0,1.0), self.radius) self.hud_node.AddChild(self.life_hud.node) self.active_effects = {} self.group = Group.UNDETERMINED self.wraps_around_boundary = True self.invulnerable = False self.setupCollisionGeometry() self.setupCollisionObject() def setupCollisionGeometry(self): self.geometry = Circle(self.radius) def setupCollisionObject(self): self.collision_object = CollisionObject(getCollisionManager(), self) #initialize collision object, second arg is passed to collisionlogic to handle collisions self.collision_object.InitializeCollisionClass("Entity") # define the collision class self.collision_object.set_shape(self.geometry) # set our shape #finally add collision logics to whatever collision class we want self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.collision_object.thisown = 0 def ApplyEffect(self, effect): #since effects are entities too, we just do this AddNewObjectToScene(effect) if self.active_effects.has_key(effect.type): if effect.unique_in_target: for e in self.active_effects[effect.type]: e.Delete() self.active_effects[effect.type].append(effect) else: self.active_effects[effect.type] = [effect] def GetActiveEffectsDetailsList(self): aedl = [] for effectType, effects in self.active_effects.items(): countStr = "" count = len(effects) if count <= 0: continue if count > 1: countStr = "%sx " % count if effects[0].GetDetailString() != "": aedl.append( countStr+effects[0].GetDetailString() ) return aedl def GetActiveEffectsList(self): el = [] for effectType, effects in self.active_effects.items(): el = el + effects return el def CleanUpActiveEffects(self): for effectType, effects in self.active_effects.items(): for e in effects: if e.is_destroyed: self.active_effects[effectType].remove(e) def GetGroup(self): if self.group == Group.UNDETERMINED: if hasattr(self, "parent"): return self.parent.GetGroup() return Group.NEUTRAL return self.group def Update(self, dt): ### self.UpdatePosition(dt) self.CleanUpActiveEffects() self.life_hud.Update() if self.velocity.Length() > self.max_velocity: self.velocity = self.velocity * (self.max_velocity / self.velocity.Length()) def UpdatePosition(self, dt): pos = self.GetPos() pos = pos + (self.velocity * dt) self.last_velocity = self.velocity self.last_dt = dt if self.HandleMapBoundaries(pos) and not self.wraps_around_boundary: self.Delete() self.SetPos(pos) def GetDirection(self): if self.velocity.Length() == 0.0: return Vector2D(0.0, 1.0) return self.velocity.Normalize() def GetDamage(self, obj_type): # returns the amount of damage this object causes on collision with given obj_type print self.type, " GetDamage NOT IMPLEMENTED" def TakeDamage(self, damage): if damage < 0: return if self.invulnerable: return self.life -= damage if damage > 0: sound_name = self.hit_sounds[ randint(0, len(self.hit_sounds)-1) ] sound = Engine_reference().audio_manager().LoadSample(SOUND_PATH + sound_name) sound.Play() if self.life <= 0: self.Delete() #print self, "took %s damage, current life = %s [max life =%s]" % (damage, self.life, self.max_life) def Heal(self, amount): if amount < 0: return self.life += amount if self.life > self.max_life: self.life = self.max_life #print self, "has recovered %s life, current life = %s" % (amount, self.life) def ApplyVelocity(self, v): self.velocity = self.velocity + v def ApplyCollisionRollback(self): if self.is_destroyed: return pos = self.GetPos() v = self.last_velocity if not v: v = self.velocity pos = pos + (v * -self.last_dt) self.HandleMapBoundaries(pos) pos = pos + (self.velocity * self.last_dt) self.HandleMapBoundaries(pos) self.SetPos(pos) self.last_velocity = self.velocity
class LaserBeam(EntityInterface,Observer): def __init__(self, parent, velocity, beam_width, damage_per_sec): EntityInterface.__init__(self, 0, 0, 1.0) self.sprite = Sprite("laser", "animations/laser.gdd") self.sprite.SelectAnimation("BASIC_LASER") self.sprite.AddObserverToAnimation(self) self.node.set_drawable(self.sprite) self.node.set_zindex(-1.0) self.velocity = velocity self.beam_width = beam_width self.beam_length = Engine_reference().video_manager().video_size().Length() self.parent = parent self.damage_per_sec = damage_per_sec self.delta_t = 0.0 scaleX = self.beam_length / self.sprite.size().get_x() scaleY = self.beam_width / self.sprite.size().get_y() self.node.modifier().set_scale( Vector2D(scaleX, scaleY) ) self.node.modifier().set_rotation(pi/2.0) ### comment these functions to make the entity's node self.node.modifier().set_offset( Vector2D(0.0, -self.beam_length/2.0) ) ### be a child of the scene self.parent.node.AddChild(self.node) ### self.setupCollisionObject() def setupCollisionObject(self): self.collision_object = CollisionObject(getCollisionManager(), self) self.collision_object.InitializeCollisionClass("Beam") self.geometry = ConvexPolygon(self.GetVertices()) self.collision_object.set_shape(self.geometry) self.collision_object.AddCollisionLogic("Entity", BasicColLogic(self) ) self.collision_object.thisown = 0 def GetNode(self): return None ### comment these functions to make the entity's node def GetHUDNode(self): return None ### be a child of the scene def SetBeamLength(self, length): self.beam_length = length self.UpdateModifier() def SetBeamWidth(self, width): self.beam_width = width self.UpdateModifier() def GetVertices(self): pos = self.parent.GetPos() dir = self.GetDirection() sideDir = Vector2D(-dir.get_y(), dir.get_x()) sideDir = sideDir * (self.beam_width/2.0) v1 = pos + sideDir v4 = pos + (sideDir * -1) offset = dir * self.beam_length v2 = v1 + offset v3 = v4 + offset return Vector2DList([v1, v2, v3, v4]) def UpdateModifier(self): scaleX = self.beam_length / self.sprite.size().get_x() scaleY = self.beam_width / self.sprite.size().get_y() self.node.modifier().set_scale( Vector2D(scaleX, scaleY) ) self.node.modifier().set_offset( Vector2D(0.0, -self.beam_length/2.0) ) def UpdateVertices(self): self.geometry.set_vertices(self.GetVertices()) def Update(self, dt): if self.parent.is_destroyed: self.parent.node.RemoveChild(self.node) self.Delete() return self.delta_t = dt #self.node.modifier().set_rotation(self.GetDirection().Angle() + pi/2.0) ### uncomment these lines to make the entity's node #self.node.modifier().set_offset( self.parent.GetPos() + (self.GetDirection()*self.beam_length/2.0) ) ### be a child of the scene self.UpdateVertices() def GetDirection(self): if self.velocity.Length() == 0.0: return Vector2D(0.0, 1.0) return self.velocity.Normalize() def Tick(self): pass def createExplosionForTarget(self, target): pos = self.parent.GetPos() dir = self.GetDirection() * ( (target.GetPos() - pos).Length() - target.radius ) pos = pos + dir dir = target.GetPos() - pos pos = pos + (dir.Normalize() * self.beam_width/2.0) explosion = CreateExplosionAtLocation(pos, self.beam_width) AddNewObjectToScene(explosion) def HandleCollision(self, target): if hasattr(target, "GetGroup") and target.GetGroup() != self.parent.GetGroup() and target.GetGroup() != Group.NEUTRAL: target.TakeDamage(self.damage_per_sec * self.delta_t) self.createExplosionForTarget(target) elif target.CheckType("Planet"): target.TakeDamage(self.damage_per_sec * self.delta_t / 2.0) self.createExplosionForTarget(target)