/// <summary> /// If the damage gets past Blob's armor, then the Blob is broken up into pices /// baised on the damage dealt to it (minus the armor) /// </summary> /// <param name="damage"></param> public override void DamageThis(float damage) { damage -= armor; if (damage > health) { base.DamageThis(damage + armor); } else if (damage > 0 && mergeTimer > -1) { int pieces = (int)(damage / 8f) + 2; if (pieces > 1) { //find the size of each new Blob by dividing the area of the old Blob by the number of //new Blobs, the calculating the new Blobs size from this area float area = (float)(scale.x * scale.x / 4 * System.Math.PI); area /= pieces; float theScale = (float)(System.Math.Sqrt(area * 4 / System.Math.PI)); //create each new Blob for (int i = 0; i < pieces; i++) { //make each new Blob and have them spread out from the old Blob's position float theAngle = i * 360.0f / pieces + angle; Blob current = (Blob)level.CreateObject("BlobPF", position + new Vector2(size.x / pieces, 0).Rotate(theAngle), angle, velocity + new Vector2(pieces, 0).Rotate(theAngle), angularVelocity + pieces, theScale); //give each new Blob an equal portion of the old Blob's healh, mass and behaviors current.mass = mass / pieces; current.health = health / pieces; current.maxHealth = maxHealth / pieces; foreach (BlobBehaviour item in behaviors) { BlobBehaviour temp = item.clone(); temp.magnitude /= pieces; current.behaviors.AddFirst(temp); } current.team = team; current.color = color; current.mergeTimer = (int)(mergeCooldownSecs * level.updatesPerSec); } //Destory the old Blob, since it is no longer needed. Make sure it dones't try to merge in the meantime. mergeTimer = -1; DestroyThis(); } else { base.DamageThis(damage + armor); } } }
public override bool Combine(BlobBehaviour other) { if (other.GetType() == typeof(PullOthers)) { PullOthers theOther = (PullOthers)other; float amountThis = magnitude / (magnitude + other.magnitude); magnitude += other.magnitude; pullSpeed = pullSpeed * amountThis + theOther.pullSpeed * (1 - amountThis); return(true); } else { return(false); } }
public override bool Combine(BlobBehaviour other) { if (other.GetType() == typeof(TowardsTarget)) { TowardsTarget theOther = (TowardsTarget)other; float amountThis = magnitude / (magnitude + other.magnitude); magnitude += other.magnitude; moveSpeed = moveSpeed * amountThis + theOther.moveSpeed * (1 - amountThis); updateTargetSecs = updateTargetSecs * amountThis + theOther.updateTargetSecs * (1 - amountThis); return(true); } else { return(false); } }
public override bool Combine(BlobBehaviour other) { if (other.GetType() == typeof(Shoot)) { Shoot theOther = (Shoot)other; float amountThis = magnitude / (magnitude + other.magnitude); magnitude += other.magnitude; shotSpeed = shotSpeed * amountThis + theOther.shotSpeed * (1 - amountThis); shotSize = shotSize * amountThis + theOther.shotSize * (1 - amountThis); shootTimeSecs = shootTimeSecs * amountThis + theOther.shootTimeSecs * (1 - amountThis); return(true); } else { return(false); } }
/// <summary> /// Combines the given BlobBehavior with this one if they are of the same type, /// adding their magnitudes and any other setting members. The combined /// BlobBehavior is this one, the other one can be deleted if the combine happened (this returned true). /// </summary> /// <param name="other">BlobBehavior to combine with this.</param> /// <returns>returns true if they combined, false if they didn't</returns> public abstract bool Combine(BlobBehaviour other);
/// <summary> /// Every so often, shoots a shotBlob from itself at closest enemy DestructableObject /// </summary> /// <param name="thisBlob">The Blob this behavior is attached to.</param> public override void Update(Blob thisBlob) { if (thisBlob.scale.x > shotSize) { shootTimer--; if (shootTimer <= 0) { //reset shootTimer shootTimer = (int)(shootTimeSecs * Level.current.updatesPerSec / magnitude / thisBlob.difficultyModifier); SpaceObject target = thisBlob.ClosestObject <SpaceObject>(Level.current.GetTypes(true, true, false, false), false); if (target != null) { thisBlob.TurnTowards(target); //find where the shotBlob should be shot to hit the target, given their current positions and velocities Vector3 aimAt = SpaceObject.IntersectPosTime(target, shotSpeed, thisBlob.position + new Vector2(0, thisBlob.scale.x * 3).Rotate(thisBlob.angle)); //if the taget cannot be hit, just shoot straight at its current position if (aimAt.z < 0) { aimAt = target.position; } //create the shotBlob with an the velocity to hit where it is being aimed at float theAngle = thisBlob.AngleToAbsolute(aimAt); Blob shotBlob = (Blob)Level.current.CreateObject("BlobPF", thisBlob.position + new Vector2(0, thisBlob.scale.x * 3).Rotate(thisBlob.angle), theAngle, new Vector2(0, shotSpeed).Rotate(theAngle), thisBlob.angularVelocity + magnitude, shotSize); float shotPortion = shotSize / thisBlob.scale.x; float thisPortion = 1 - shotPortion; //make the shotBlob's health, mass and Behaviors proportional to how much of thisBlob is it taking //also decrease thisBlob's behaviors baised on how much the shotBlob took from it shotBlob.mass = thisBlob.mass * shotPortion; shotBlob.health = thisBlob.health * shotPortion; foreach (BlobBehaviour item in thisBlob.behaviors) { BlobBehaviour temp = item.clone(); temp.magnitude *= shotPortion; shotBlob.behaviors.AddFirst(temp); item.magnitude *= thisPortion; } shotBlob.team = thisBlob.team; shotBlob.color = thisBlob.color; //find the new size of thisBlob baised on how much area the shotBlob took from it float area = (thisBlob.scale.x * thisBlob.scale.x / 4 * Mathf.PI); area -= (shotSize * shotSize / 4 * Mathf.PI); float theScale = Mathf.Sqrt(area * 4 / Mathf.PI); //decrease thisBlob's size, mass and health baised on how much the shotBlob took from it thisBlob.scale = new Vector2(theScale, theScale); thisBlob.mass *= thisPortion; thisBlob.health *= thisPortion; thisBlob.maxHealth -= shotBlob.health; } } } }
void Awake() { instance = this; }