public MirrorPlayer(GameController game) : base(game) { this.game = game; // Model this.colorDefault = Constants.noColor; this.color = colorDefault; this.texturename = null; this.modelname = Constants.model_fish; getSizeRatioAndTransformation(); this.type = GameObjectType.MirrorPlayer; // Stats hp = game.player.hp; mass = hp / size_ratio; maxAttackDelay = 0; maxHitDelay = 0; maxRotationSpeed = Constants.playerRotationSpeed; attackingAngle = Constants.attackingAngle; timeInBetweenShots = 100; this.pos = game.player.pos; this.movementSpeed = game.player.movementSpeed; this.acceleration = game.player.acceleration; this.accX = acceleration * ((float)Math.Cos(game.player.rotationAngle)); this.accY = acceleration * ((float)Math.Sin(game.player.rotationAngle)); this.pos_offset_x = ((float)game.random.NextDouble() * this.mass * 10 - this.mass*5); this.pos_offset_y = ((float)game.random.NextDouble() * this.mass * 10 - this.mass * 5); this.pos.X = game.player.pos.X + pos_offset_x; this.pos.Y = game.player.pos.Y + pos_offset_y; this.damage = game.player.damage/2; // Gamelogic isCollidable = false; refreshModel(color); // Follow a target target = null; game.Add(this); }
// Handle a collision with a specific object public void rebound(float timeDelta, GameObject obj) { if (!this.colossal) { float vtx = accX * timeDelta * Constants.bounciness; float vty = accY * timeDelta * Constants.bounciness; this.velX -= vtx * obj.mass / (this.mass + obj.mass) * Constants.elasticModulus; this.velY -= vty * obj.mass / (this.mass + obj.mass) * Constants.elasticModulus; } }
// Check if a specific object is within attack region public bool isFacing(GameObject obj) { // Get the angle between the two objects float angle = Methods.getAngle(this.pos, obj.pos); float[] diff = new float[2]; diff[0] = Methods.absDiff(angle, this.rotationAngle); diff[1] = Methods.absDiff(angle + (float)Math.PI * 2, this.rotationAngle); if (diff[0] < attackingAngle || diff[1] < attackingAngle) { return true; } else { return false; } }
// Calculate the squared distance from a specific object public float getCollisionDistanceSquared(GameObject obj) { float this_weighted_radius = this.mass / 2f * this.size_ratio / Constants.size_ratio_cube; float obj_weighted_radius = obj.mass / 2f * obj.size_ratio / Constants.size_ratio_cube; float sumRadiusSquared = (this_weighted_radius + obj_weighted_radius) * (this_weighted_radius + obj_weighted_radius); float collisionDistance = Methods.lengthSquared3(this.pos, obj.pos) - sumRadiusSquared; return collisionDistance; }
// Check collision with a specific object and update the collision state public void checkCollision(GameObject obj, float timeDelta) { float collisionDistance = getCollisionDistanceSquared(obj); //float mag = Math.Min(Methods.magnitudeSquared(velX * timeDelta, velY * timeDelta), Methods.magnitudeSquared(obj.velX * timeDelta, obj.velY * timeDelta)); if (collisionDistance < 0) { collisionState = CollisionState.Overlapping; } //else if (collisionDistance < mag) //{ // collisionState = CollisionState.Touching; //} else { collisionState = CollisionState.None; } }
// Attack a specific object, amount is the percentage damage dealt (1 = 100%) public void attack(GameObject obj, float amount) { if (this == game.player) game.scoreController.addToScore(Constants.score_attacks); //game.soundController.PlaySound("hit1.wav", 0.7); float addedHp; // Will need to recreate models since hp has changed modelNeedsRefresh = true; obj.modelNeedsRefresh = true; // Update attack delay and hit delay counters attackDelayCounter = maxAttackDelay; obj.hitDelayCounter = obj.maxHitDelay; if (obj.hp - (damage * amount) <= 0) // Remove victim if its hp reaches 0 { addedHp = obj.hp; // Add victim's remaining hp to attacker obj.hp = 0; obj.kill(); } else { addedHp = damage * amount; // Otherwise add hp to attacker equal to attacker's damage obj.hp -= addedHp; // Remove HP from victim obj.damage -= addedHp * Constants.added_damage_ratio; // decrease victim's damage } // HP and Damage addition is not applicable for survival units or projectiles if (this.type != GameObjectType.EnemySurvival && this.type != GameObjectType.ProjectilePlayer && this.type != GameObjectType.ProjectileEnemy && this.type != GameObjectType.FieldPlayer) { hp += addedHp * Constants.added_hp_ratio; // Update hp, survival units can't gain hp damage += addedHp * Constants.added_damage_ratio; // Increase attack's damage } // Limit how low a unit's damage can go if (obj.damage < Constants.minimumDamage) obj.damage = Constants.minimumDamage; }
public void applyVortex(GameObject target, float range) { accX = 0; accY = 0; if (target.isAlive) { float diffX = pos.X - target.pos.X; float diffY = pos.Y - target.pos.Y; if (diffX < range + target.mass && diffY < range + target.mass) { if (diffX >= 0) accX = -Constants.vortexAccel; else accX = Constants.vortexAccel; if (diffY >= 0) accY = -Constants.vortexAccel; else accY = Constants.vortexAccel; } } }
public Projectile(GameObject obj, GameController game, float variance, Vector4 color, float damage, bool randomDirection, bool homing) : base(game) { this.pos = obj.pos; this.game = game; if (obj.type == GameObjectType.Player || obj.type == GameObjectType.MirrorPlayer) { this.type = GameObjectType.ProjectilePlayer; } else { this.type = GameObjectType.ProjectileEnemy; } // Model // projectile color - default blue, otherwise copies the shooter's color if (obj.colorDefault == Constants.noColor) this.colorDefault = Constants.blue; else this.colorDefault = obj.colorDefault; // Init values this.colorDefault = color; this.color = colorDefault; this.texturename = null; this.modelname = Constants.model_projectile; getSizeRatioAndTransformation(); this.showLighting = false; // Stats hp = Constants.projectile_base_size + obj.hp/10; // Here HP and MASS just determines size of the projectile mass = hp / size_ratio; this.damage = damage; this.maxRotationSpeed = Constants.projectileRotationSpeed; // Set base speed and accel this.movementSpeed = Constants.projectile_speed; this.acceleration = Constants.projectile_accel; // Initial accel and velocity is in the direction of the shooter this.accX = acceleration * ((float)Math.Cos(obj.rotationAngle)); this.accY = acceleration * ((float)Math.Sin(obj.rotationAngle)); this.velX = obj.velX; this.velY = obj.velY; // Random projectile direction if applicable if (randomDirection) { accX = accX + ((float)game.random.NextDouble() * variance * 2 - variance); accY = accY + ((float)game.random.NextDouble() * variance * 2 - variance); } this.pos.X += ((float)Math.Cos(obj.rotationAngle)) * obj.mass / 2f; this.pos.Y += ((float)Math.Sin(obj.rotationAngle)) * obj.mass / 2f; // Gamelogic isCollidable = false; isAffectedByVortex = false; this.homing = homing; if (homing) lifeTime = Constants.projectile_lifetime + 400; else lifeTime = Constants.projectile_lifetime; refreshModel(color); game.Add(this); }
public void seekTarget() { accX = 0; accY = 0; float diffX = 10000; float diffY = 10000; if (target == null) { foreach (var obj in game.gameObjects) { if (type == GameObjectType.ProjectilePlayer) { if (obj.type == GameObjectType.Enemy || obj.type == GameObjectType.Boss || obj.type == GameObjectType.EnemySurvival) { float x = pos.X - obj.pos.X; float y = pos.Y - obj.pos.Y; if (Math.Abs(diffX) > Math.Abs(x)) { diffX = x; target = obj; } if (Math.Abs(diffY) > Math.Abs(y)) { diffY = y; target = obj; } } } else { if (obj.type == GameObjectType.Player || obj.type == GameObjectType.MirrorPlayer) { float x = pos.X - obj.pos.X; float y = pos.Y - obj.pos.Y; if (Math.Abs(diffX) > Math.Abs(x)) { diffX = x; target = obj; } if (Math.Abs(diffY) > Math.Abs(y)) { diffY = y; target = obj; } } } } } else { diffX = pos.X - target.pos.X; diffY = pos.Y - target.pos.Y; } if (diffX >= 0) accX = -acceleration; else accX = acceleration; if (diffY <= 0) accY = acceleration; else accY = -acceleration; }
public void keepNearPlayer() { float diffX = pos.X - game.player.pos.X; float diffY = pos.Y - game.player.pos.Y; if (Math.Abs(diffX) > 5 && Math.Abs(diffY) > 5) { target = game.player; } else { if (target == game.player) target = null; } }
public void moveTowardsEnemy() { accX = 0; accY = 0; float diffX = 10000; float diffY = 10000; if (target == null) { foreach (var obj in game.gameObjects) { if (obj.type == GameObjectType.Enemy || obj.type == GameObjectType.Boss) { float x = pos.X - obj.pos.X; float y = pos.Y - obj.pos.Y; if (Math.Abs(diffX) > Math.Abs(x)) { diffX = x; target = obj; } if (Math.Abs(diffY) > Math.Abs(y)) { diffY = y; target = obj; } } } } else { diffX = pos.X - target.pos.X; diffY = pos.Y - target.pos.Y; } if (Math.Abs(diffX) < Constants.mirrorImageRange && Math.Abs(diffY) < Constants.mirrorImageRange) { if (diffX >= 0) accX = -acceleration; else accX = acceleration; if (diffY <= 0) accY = acceleration; else accY = -acceleration; } }