using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Audio; namespace SuperPolarity { class MainShip : Ship { public static Color BlueColor; public static Color RedColor; protected bool Shooting; protected int ShotCooldown; protected float CurrentImmortalTime; protected float MaxImmortalTime; protected bool Flashing; protected SoundEffect PolarityChange; protected SoundEffect ShootSound; protected SoundEffect Hit; // Aura stuff protected Texture2D AuraPoint; protected double AuraRadius; protected double AuraAmplitude; protected double AuraFrequency; protected double AuraSubAmplitude; protected double AuraWaveSize; protected double AuraSubPhase; protected double AuraSubFrequency; public double[] EnemyModifications; public double MaxEnemyModification; public double EnemyModificationSpread; public MainShip(SuperPolarity newGame) : base(newGame) {} ~MainShip() { } public override void Initialize(Texture2D texture, Vector2 position) { base.Initialize(texture, position); MainShip.BlueColor = new Color(71, 182, 226); MainShip.RedColor = new Color(235, 160, 185); AuraPoint = CreateCircle (2); AuraRadius = 75; AuraAmplitude = 7; AuraFrequency = 3; AuraSubAmplitude = 7; AuraWaveSize = 3; AuraSubPhase = 0; AuraSubFrequency = 9 * Math.PI / 180; MaxEnemyModification = 20; EnemyModificationSpread = 10; EnemyModifications = new double[360]; for ( int i = 0; i < EnemyModifications.Length; i++ ) { EnemyModifications[i] = 0; } PolarityChange = game.Content.Load("Sound\\polaritychange"); ShootSound = game.Content.Load("Sound\\bullet"); Hit = game.Content.Load("Sound\\hit"); SetPolarity(Polarity.Positive); ActVelocity = 2.5f; ShotCooldown = 50; MaxImmortalTime = 1500; BoxDimensions.X = 2; BoxDimensions.Y = 2; BoxDimensions.W = 2; BoxDimensions.Z = 2; InitBox(); BindInput(); } void BindInput() { InputController.Bind("moveX", HandleHorizontalMovement); InputController.Bind("moveY", HandleVerticalMovement); InputController.Bind("changePolarity", HandleChangePolarity); InputController.Bind("shoot", HandleShot); } protected void HandleShot(float value) { Shooting = true; Timer t = new Timer(new TimerCallback(UnlockShot)); t.Change(ShotCooldown, Timeout.Infinite); if (Children.Count > 10) { return; } var bullet = ActorFactory.CreateBullet(Position, Angle); Children.Add(bullet); bullet.Parent = this; ShootSound.Play(); } protected void UnlockShot(object state) { InputController.Unlock("shoot"); Shooting = false; } protected void HandleChangePolarity(float value) { SwitchPolarity(); } public void HandleHorizontalMovement(float value) { if (value >= -0.5 && value <= 0.5) { value = 0; } Velocity.X = value * MaxVelocity; } public void HandleVerticalMovement(float value) { if (value >= -0.5 && value <= 0.5) { value = 0; } Velocity.Y = value * MaxVelocity; } public override void SwitchPolarity() { base.SwitchPolarity(); PolarityChange.Play(); game.Player.ResetMultiplier(); } public override void SetPolarity(Polarity newPolarity) { base.SetPolarity(newPolarity);; } public override void Update(GameTime gameTime) { base.Update(gameTime); ConstrainToEdges(); UpdateImmortality(gameTime); } public void ResetEnemyModification() { for ( int i = 0; i < EnemyModifications.Length; i++ ) { EnemyModifications[i] = 0; } } public void UpdateImmortality(GameTime gameTime) { if (Immortal) { CurrentImmortalTime += gameTime.ElapsedGameTime.Milliseconds; if (Flashing) { Color = new Color(255, 255, 255, 128); } else { Color = Color.White; } Flashing = !Flashing; if (CurrentImmortalTime > MaxImmortalTime) { Immortal = false; Color = Color.White; } } } public override void Move(GameTime gameTime) { var VelocityLimit = MaxVelocity; var SavedVelocity = new Vector2(Velocity.X, Velocity.Y); if (Shooting) { VelocityLimit = ActVelocity; } if (SavedVelocity.X > VelocityLimit) { SavedVelocity.X = VelocityLimit; } if (SavedVelocity.X < -VelocityLimit) { SavedVelocity.X = -VelocityLimit; } if (SavedVelocity.Y > VelocityLimit) { SavedVelocity.Y = VelocityLimit; } if (SavedVelocity.Y < -VelocityLimit) { SavedVelocity.Y = -VelocityLimit; } Position.X = Position.X + SavedVelocity.X; Position.Y = Position.Y + SavedVelocity.Y; } public override void Magnetize(Ship ship, float distance, float angle) { } protected void ConstrainToEdges() { if (Position.X < 0) { Position.X = 0; if (Velocity.X < 0) { Velocity.X = 0; } } if (Position.X > game.GraphicsDevice.Viewport.Width) { Position.X = game.GraphicsDevice.Viewport.Width; if (Velocity.X > 0) { Velocity.X = 0; } } if (Position.Y < 0) { Position.Y = 0; if (Velocity.Y < 0) { Velocity.Y = 0; } } if (Position.Y > game.GraphicsDevice.Viewport.Height) { Position.Y = game.GraphicsDevice.Viewport.Height; if (Velocity.Y < 0) { Velocity.Y = 0; } } } public void UpdateEnemyModification(Ship enemy) { var dx = enemy.Position.X - Position.X; var dy = enemy.Position.Y - Position.Y; var angleInDegrees = ((360 + Math.Round (Math.Atan2 (dy, dx) * 180 / Math.PI)) % 360); for (var i = -EnemyModificationSpread; i < EnemyModificationSpread; i++) { var strength = MaxEnemyModification - Math.Abs (i * MaxEnemyModification / EnemyModificationSpread); var index = (int)((360 + angleInDegrees + i) % 360); if (enemy.CurrentPolarity == CurrentPolarity) { EnemyModifications[index] -= strength; } else { EnemyModifications[index] += strength; } if (EnemyModifications[index] > MaxEnemyModification) { EnemyModifications[index] = MaxEnemyModification; } if (EnemyModifications[index] < -MaxEnemyModification) { EnemyModifications[index] = -MaxEnemyModification; } } } public override void Draw(SpriteBatch spriteBatch) { DrawCircle (spriteBatch); base.Draw(spriteBatch); //spriteBatch.Draw(BoxTexture, Box, new Color(255, 0, 255, 25)); } protected void DrawCircle(SpriteBatch spriteBatch) { var j = AuraWaveSize; var subWaveRadius = 0.0; var randomPosition = 0.0; for (var i = 0; i < 360; i++) { var angle = i * Math.PI / 180; if (j == AuraWaveSize) { subWaveRadius = AuraSubAmplitude * Math.Sin (randomPosition + AuraSubPhase); randomPosition -= (2 * Math.PI / 8); j = 0; } j++; var radius = EnemyModifications[i] + subWaveRadius + AuraRadius + AuraAmplitude * Math.Sin (i / AuraFrequency); var x = Position.X + radius * Math.Cos (angle); var y = Position.Y + radius * Math.Sin (angle); x = Math.Round (x); y = Math.Round (y); var pointPosition = new Vector2 ((float)x, (float)y); if (CurrentPolarity == Polarity.Positive) { spriteBatch.Draw (AuraPoint, pointPosition, RedColor); } else { spriteBatch.Draw (AuraPoint, pointPosition, BlueColor); } } AuraSubPhase += AuraSubFrequency; /* var r = 50; var wave = 5; var frequency = 1.4; var randomFactor = 5; var randomAreaSize = 4; var j = AuraWaveSize; var rand = 0; var randomPosition = 0; AuraSubPhase = 0; for (var i = 0; i < 360; i++) { var rad = Math.radians(i); if (j == AuraWaveSize) { //rand = Math.random() * 2 * AuraSubAmplitude - AuraSubAmplitude; rand = AuraSubAmplitude * Math.sin(AuraSubPhase + offset); AuraSubPhase -= (2 * Math.PI / 8); j = 0; } j++; var radius = polarityModifications[i] + rand + AuraRadius + AuraAmplitude * Math.sin(i / AuraFrequency); var x = Position.x + radius * Math.cos(rad); var y = Position.y + radius * Math.sin(rad); x = Math.round(x); y = Math.round(y); draw //console.log(i, rad, x, y, dataStart); }); ctx.putImageData(imgData, 0, 0);*/ } protected Texture2D CreateCircle(int radius) { int outerRadius = radius * 2 + 2; Texture2D texture = new Texture2D (game.GraphicsDevice, outerRadius, outerRadius); Color[] data = new Color[outerRadius * outerRadius]; for (int i = 0; i < data.Length; i++) { data [i] = Color.Transparent; } double angleStep = 1f / radius; for (double angle = 0; angle < Math.PI * 2; angle += angleStep) { int x = (int)Math.Round (radius + radius * Math.Cos (angle)); int y = (int)Math.Round (radius + radius + Math.Sin (angle)); data [y * outerRadius + x + 1] = Color.White; } texture.SetData (data); return texture; } public override void Collide(Actor other, Rectangle collision) { if (other.GetType().IsAssignableFrom(typeof(StandardShip)) && !Immortal) { Die(); } } protected override void Die() { game.Player.Lives = game.Player.Lives - 1; game.Player.ResetMultiplier(); if (game.Player.Lives < 0) { Dying = true; game.GameOver(); } else { Hit.Play(); Immortal = true; CurrentImmortalTime = 0; } } public override void CleanUp() { base.CleanUp(); InputController.Unbind("moveX", HandleHorizontalMovement); InputController.Unbind("moveY", HandleVerticalMovement); InputController.Unbind("changePolarity", HandleChangePolarity); InputController.Unbind("shoot", HandleShot); } } }