LADXHD/InGame/Screens/IntroScreen.cs
2023-12-14 17:21:22 -05:00

868 lines
36 KiB
C#

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using ProjectZ.InGame.Controls;
using ProjectZ.InGame.GameObjects.Base;
using ProjectZ.InGame.SaveLoad;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.Screens
{
public class IntroScreen : Screen
{
private Texture2D _sprOcean;
private Texture2D _sprRain;
private Texture2D _sprIntro;
private Texture2D _sprWaves;
private Texture2D _sprCloud;
private Animator _loadingAnimator;
private Animator _marinAnimator;
private Animator _linkAnimator;
private Animator _lightAnimation;
private Animator _linkBoatAnimator;
private Animator[] _thunder = new Animator[2];
private Vector2[] _thunderPositions = new Vector2[2];
private float[] _thunderCounts = { 1000, 2000 };
private enum States
{
OceanCamera,
OceanPicture,
OceanThunder,
StrandFading,
StrandCamera,
StrandMarin,
StrandLogo
};
private States _currentState;
private int _scale = 1;
private Vector2 _cameraCenter;
private Matrix TransformMatrix =>
Matrix.CreateTranslation(new Vector3(
-(float)(Math.Round(_cameraCenter.X * _scale) / _scale),
-(float)(Math.Round(_cameraCenter.Y * _scale) / _scale), 0)) *
Matrix.CreateScale(_scale) *
Matrix.CreateTranslation(new Vector3((int)(Game1.WindowWidth * 0.5f), (int)(Game1.WindowHeight * 0.5f), 0)) * Game1.GetMatrix;
private float _cameraState;
private Vector2 _cameraStart;
private Vector2 _cameraTarget;
private enum MarinState
{
WalkSlow,
Walk,
Run,
Stand,
Hold,
Push,
End
};
private MarinState marinState;
private MarinState[] _marinStates =
{
MarinState.WalkSlow, MarinState.Stand, MarinState.Run, MarinState.Stand, MarinState.Walk, MarinState.Stand, MarinState.Walk, MarinState.Stand, MarinState.Walk, MarinState.Stand,
MarinState.Hold, MarinState.Push, MarinState.Hold, MarinState.Push, MarinState.Hold, MarinState.Push, MarinState.Hold, MarinState.Push, MarinState.End,
};
private int[] _marinTimes = {
1000, 1100, 900, 1300, 200, // stand times
2000, 500, 2100, 200, 400, 200, 250, 750 // push hold times
};
private Vector2[] _marinGoalPositions =
{
new Vector2(-150, 219), new Vector2(-94, 219), new Vector2(-72, 219), new Vector2(-64, 219),
new Vector2(-18, 219)
};
private float _marinStateCounter;
private int _marinIndex;
private int _marinWalkIndex;
private int _marinTimeIndex;
private readonly Rectangle _oceanCloudRectangle = new Rectangle(0, 0, 32, 32);
private int _thunderIndex;
private float _thunderCount = 250;
private float _thunderTransition;
private readonly Rectangle _ocean0Rectangle = new Rectangle(0, 288, 32, 16);
private readonly Rectangle _ocean1Rectangle = new Rectangle(0, 304, 32, 16);
private readonly Rectangle _ocean2Rectangle = new Rectangle(0, 320, 32, 16);
private readonly Rectangle _oceanRectangle = new Rectangle(0, 144, 32, 32);
private DictAtlasEntry _spriteOceanBoat;
private Vector2 _oceanBoatPosition;
private Vector2 _oceanPosition0;
private Vector2 _oceanPosition1;
private Vector2 _oceanPosition2;
private Vector2 _oceanPosition3;
private readonly int[] _thunderFrame = { 1, 0, 1, 2, 1, 0, 1, 2, 1, 0, 1, 2, 1, 0 };
private Color[] _oceanColor = { new Color(0, 32, 168), new Color(32, 32, 168), new Color(96, 96, 232) };
private DictAtlasEntry _spriteBackground;
private DictAtlasEntry _spriteMountain;
private DictAtlasEntry _spriteLogo0;
private DictAtlasEntry _spriteLogo1;
private readonly Rectangle _treesRectangle = new Rectangle(0, 320, 32, 46);
private readonly Rectangle _sandRectangle = new Rectangle(0, 364, 32, 16);
private readonly Rectangle _waveRectangle = new Rectangle(0, 0, 32, 24);
private Vector2 _logoPosition;
private float _logoState;
private float _logoCounter;
private Vector2 _ligthPosition;
private Vector2[] _lightPositions =
{
new Vector2(7, 0),
new Vector2(41, 0),
new Vector2(2, 19),
new Vector2(0, 56),
new Vector2(34, 9),
new Vector2(55, 9),
new Vector2(72, 9),
new Vector2(96, 9),
new Vector2(34, 47),
new Vector2(55, 47),
new Vector2(72, 47),
new Vector2(90, 47),
new Vector2(119, 47),
};
private int _lightIndex;
private Vector2 _treePosition;
private Vector2 _mountainRightPosition;
private Vector2 _mountainLeftPosition;
private Vector2 _cloundLeftPosition;
private Vector2 _wavePosition;
private Vector2 _marinPosition;
private Vector2 _marinGoal;
private int _currentFrame;
private float _waveCounter;
private int _oceanFrameIndex;
private float _oceanShoreCounter = 2000;
private int _screenWidth = 160;
private int _screenHeight = 144;
private float StrandFadeTime = 600;
private float _strandFadeCount;
private float _loadingTransparency = 0.75f;
private const int Slow = 500;
private const int Fast = 200;
private readonly int[] _waveTimes = { Slow, Fast, Fast, Fast, Slow, Fast, Fast, Fast, Fast, Fast };
private bool _loaded;
public IntroScreen(string screenId) : base(screenId) { }
public override void Load(ContentManager content)
{
if (_loaded)
return;
_loaded = true;
_spriteOceanBoat = Resources.GetSprite("intro_boat");
_spriteBackground = Resources.GetSprite("intro_background");
_spriteMountain = Resources.GetSprite("intro_mountain");
_spriteLogo0 = Resources.GetSprite("intro_logo_0");
_spriteLogo1 = Resources.GetSprite("intro_logo_1");
_mountainLeftPosition.X = -_spriteBackground.SourceRectangle.Width / 2 - _spriteMountain.SourceRectangle.Width;
_mountainLeftPosition.Y = 0;
_mountainRightPosition.X = _spriteBackground.SourceRectangle.Width / 2;
_mountainRightPosition.Y = 0;
_treePosition.X = 0;
_treePosition.Y = _spriteBackground.SourceRectangle.Height - 16;
_wavePosition.X = _treePosition.X;
_wavePosition.Y = _treePosition.Y + _treesRectangle.Height + 16;
_logoPosition.X = -_spriteBackground.SourceRectangle.Width / 2 + 16;
_logoPosition.Y = 3;
_sprOcean = Resources.GetTexture("ocean.png");
_sprRain = Resources.GetTexture("rain.png");
_sprIntro = Resources.GetTexture("intro.png");
_sprCloud = Resources.GetTexture("cloud.png");
_sprWaves = Resources.GetTexture("waves.png");
_loadingAnimator = AnimatorSaveLoad.LoadAnimator("Intro/loading");
_loadingAnimator.Play("idle");
_thunder[0] = AnimatorSaveLoad.LoadAnimator("Intro/thunder");
_thunder[1] = AnimatorSaveLoad.LoadAnimator("Intro/thunder");
_linkBoatAnimator = AnimatorSaveLoad.LoadAnimator("Intro/link_boat");
_marinAnimator = AnimatorSaveLoad.LoadAnimator("Intro/maria");
_linkAnimator = AnimatorSaveLoad.LoadAnimator("Intro/link");
_lightAnimation = AnimatorSaveLoad.LoadAnimator("Intro/light");
}
public override void OnLoad()
{
Init();
}
private void Init()
{
_linkAnimator.Play("idle");
_marinAnimator.Play("walk");
_lightAnimation.Stop();
_currentState = States.OceanCamera;
_cameraCenter = new Vector2(-220, 55);
// start playing the prologue music
Game1.GameManager.ResetMusic();
Game1.GameManager.StopMusic();
Game1.GameManager.SetMusic(25, 0);
Game1.GbsPlayer.SetVolumeMultiplier(1.0f);
Game1.GbsPlayer.Play();
// play track for 52sec
#if WINDOWS
Game1.GbsPlayer.SoundGenerator.SetStopTime(48.75f);
#endif
}
public override void Update(GameTime gameTime)
{
if (Game1.FinishedLoading && Game1.LoadFirstSave)
{
Game1.LoadFirstSave = false;
if (SaveManager.FileExists(Values.PathSaveFolder + "/" + SaveGameSaveLoad.SaveFileName + "0"))
{
// change to the game screen
Game1.ScreenManager.ChangeScreen(Values.ScreenNameGame);
// load the save
Game1.GameManager.LoadSaveFile(0);
}
}
#if WINDOWS
if (Game1.GbsPlayer.SoundGenerator.WasStopped && Game1.GbsPlayer.SoundGenerator.FinishedPlaying())
{
Game1.GameManager.SetMusic(0, 0);
Game1.GbsPlayer.Play();
}
#endif
if (Game1.FinishedLoading &&
(ControlHandler.ButtonPressed(CButtons.A) || ControlHandler.ButtonPressed(CButtons.Start)))
Game1.ScreenManager.ChangeScreen(Values.ScreenNameMenu);
if (!Game1.FinishedLoading)
_loadingAnimator.Update();
if (Game1.FinishedLoading)
_loadingTransparency = AnimationHelper.MoveToTarget(_loadingTransparency, 0, 0.125f * Game1.TimeMultiplier);
UpdateOcean();
UpdateBeach();
_scale = MathHelper.Clamp(Math.Min(Game1.WindowWidth / _screenWidth, Game1.WindowHeight / _screenHeight), 1, 10);
}
private void UpdateOcean()
{
if (_currentState == States.OceanCamera)
{
// move the camera to the center
var goalPosition = new Vector2(0, 55);
var direction = goalPosition - _cameraCenter;
if (direction.Length() < Game1.TimeMultiplier * 0.25f)
{
_currentState = States.OceanPicture;
_linkBoatAnimator.Stop();
_linkBoatAnimator.Play("run");
}
else
{
direction.Normalize();
_cameraCenter += direction * Game1.TimeMultiplier * 0.25f;
}
_thunderIndex = 0;
for (var i = 0; i < _thunder.Length; i++)
{
_thunder[i].Update();
if (_thunder[i].IsPlaying)
UpdateThunderIndex(_thunder[i].FrameCounter);
_thunderCounts[i] -= Game1.DeltaTime;
if (_thunderCounts[i] <= 0)
{
var animation = Game1.RandomNumber.Next(0, 4);
_thunder[i].Play("thunder" + animation);
_thunderCounts[i] = Game1.RandomNumber.Next(2000, 4000);
// play sound effect
Game1.GameManager.PlaySoundEffect("D378-12-0C", true);
var randomX = (int)_cameraCenter.X - 150 + Game1.RandomNumber.Next(0, 300);
if (animation < 2)
_thunderPositions[i] = new Vector2(randomX, 28);
else
_thunderPositions[i] = new Vector2(randomX, 14);
}
}
_oceanPosition0 = new Vector2(_cameraCenter.X * 0.1f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500) * 1));
_oceanPosition1 = new Vector2(_cameraCenter.X * 0.05f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500 + 0.1) * 2));
_oceanPosition2 = new Vector2(-_cameraCenter.X * 0.05f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500 + 0.2) * 3));
_oceanPosition3 = new Vector2(-_cameraCenter.X * 0.25f, 60 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500 + 0.2) * 3));
_oceanBoatPosition = new Vector2(-16 + _cameraCenter.X * 0.05f, 47 + (int)Math.Round(Math.Sin(Game1.TotalTime / 500) * 2.5));
}
else if (_currentState == States.OceanPicture)
{
_cameraCenter = new Vector2(0, 0);
_linkBoatAnimator.Update();
if (_oceanFrameIndex != _linkBoatAnimator.CurrentFrameIndex &&
(_linkBoatAnimator.CurrentFrameIndex == 1 || _linkBoatAnimator.CurrentFrameIndex == 10))
{
Game1.GameManager.PlaySoundEffect("D378-12-0C", true);
}
_oceanFrameIndex = _linkBoatAnimator.CurrentFrameIndex;
// transition to next state
if (!_linkBoatAnimator.IsPlaying)
{
_currentState = States.OceanThunder;
_thunderTransition = 0;
_thunderCount = 250;
_thunder[0].Play("null");
}
}
else if (_currentState == States.OceanThunder)
{
if (_thunderCount < 0)
{
_thunder[0].Play("thunderboat");
var counter = _thunder[0].FrameCounter;
UpdateThunderIndex(counter);
if (counter > 500)
{
_thunderTransition = ((float)counter - 500) / 700f;
if (_thunderTransition >= 1)
{
InitBeach();
return;
}
}
}
else
_thunderCount -= Game1.DeltaTime;
_thunder[0].Update();
// center the camera
_cameraCenter = new Vector2(0, 55);
_oceanPosition0 = new Vector2(_cameraCenter.X * 0.1f, 60);
_oceanPosition1 = new Vector2(_cameraCenter.X * 0.05f, 60);
_oceanPosition2 = new Vector2(-_cameraCenter.X * 0.05f, 60);
_oceanPosition3 = new Vector2(-_cameraCenter.X * 0.25f, 60);
_oceanBoatPosition = new Vector2(-16 + _cameraCenter.X * 0.05f, 47);
_thunderPositions[0] = new Vector2(-2, -17);
}
}
private void UpdateThunderIndex(double time)
{
var index = (int)(time / (2000 / 60.0));
if (index < _thunderFrame.Length)
_thunderIndex = _thunderFrame[index];
}
private void InitBeach()
{
_currentState = States.StrandFading;
_cameraCenter = new Vector2(-400, 210);
_marinPosition = new Vector2(-250, 219);
_marinAnimator.Play("stand");
_marinAnimator.SpeedMultiplier = 1.0f;
_logoState = 0;
_strandFadeCount = 3700 + StrandFadeTime;
_marinIndex = 0;
_marinWalkIndex = 0;
_marinTimeIndex = 0;
NextState();
}
private void UpdateBeach()
{
if (_currentState != States.StrandFading && _currentState != States.StrandCamera &&
_currentState != States.StrandMarin && _currentState != States.StrandLogo)
return;
if (_currentState == States.StrandFading)
{
_strandFadeCount -= Game1.DeltaTime;
if (_strandFadeCount < StrandFadeTime)
{
UpdateMarin();
}
if (_strandFadeCount <= 0)
{
_strandFadeCount = 0;
_currentState = States.StrandCamera;
}
}
// move camera to marin
else if (_currentState == States.StrandCamera)
{
UpdateMarin();
// reached marin?
if (_cameraCenter.X >= _marinPosition.X + 18)
{
_currentState = States.StrandMarin;
}
}
// camera follows marin directly
else if (_currentState == States.StrandMarin)
{
UpdateMarin();
if (_marinIndex == _marinStates.Length - 1)
{
_cameraState = 0;
_cameraStart = _cameraCenter;
_cameraTarget = new Vector2(_cameraCenter.X, _logoPosition.Y + _spriteLogo0.ScaledRectangle.Height + 5);
_logoCounter = 0;
_currentState = States.StrandLogo;
}
}
else if (_currentState == States.StrandLogo)
{
if (!MoveCamera(0.65f))
{
_logoCounter += Game1.DeltaTime;
if (_logoCounter > 750 && _logoState != 1)
{
_logoState = AnimationHelper.MoveToTarget(_logoState, 1, 0.05f * Game1.TimeMultiplier);
if (_logoState == 1)
Game1.GameManager.PlaySoundEffect("D378-25-19");
}
if (_logoCounter > 1500)
{
if (!_lightAnimation.IsPlaying)
{
_lightAnimation.Play("idle");
_lightIndex = (_lightIndex + Game1.RandomNumber.Next(1, _lightPositions.Length)) % _lightPositions.Length;
_ligthPosition = _lightPositions[_lightIndex];
}
}
}
}
else
{
_oceanShoreCounter -= Game1.DeltaTime;
if (_oceanShoreCounter <= 0)
{
_oceanShoreCounter += 3500;
Game1.GameManager.PlaySoundEffect("D378-15-0F");
}
}
if (_currentState != States.StrandLogo && _strandFadeCount < StrandFadeTime)
{
UpdateCamera(new Vector2(_marinPosition.X + 18, 210), _currentState == States.StrandMarin ? 1.0f : 0.75f);
}
_marinAnimator.Update();
_linkAnimator.Update();
_lightAnimation.Update();
_cloundLeftPosition = new Vector2(-_sprCloud.Width, 47);
// update wave animation
_waveCounter += Game1.DeltaTime;
if (_waveCounter > _waveTimes[_currentFrame])
{
_waveCounter -= _waveTimes[_currentFrame];
_currentFrame = (_currentFrame + 1) % 10;
}
}
private void UpdateCamera(Vector2 tragetPosition, float maxSpeed)
{
var direction = tragetPosition - _cameraCenter;
if (direction != Vector2.Zero)
{
var distance = direction.Length();
if (distance <= 0.1f * Game1.TimeMultiplier)
_cameraCenter = tragetPosition;
else
{
var speedMult = Math.Clamp(CameraFunction(distance / 12.5f), 0, maxSpeed);
direction.Normalize();
var cameraSpeed = direction * speedMult * Game1.TimeMultiplier;
_cameraCenter += cameraSpeed;
}
}
}
private float CameraFunction(float x)
{
var y = MathF.Atan(x);
if (x > 2)
y += (x - 2) / 2;
return y + 0.1f;
}
private bool MoveCamera(float speed)
{
if (_cameraCenter == _cameraTarget)
return false;
_cameraState += 0.005f * Game1.TimeMultiplier;
_cameraState = Math.Clamp(_cameraState, 0, 1);
_cameraCenter = Vector2.Lerp(_cameraStart, _cameraTarget, 0.5f + MathF.Sin(-MathF.PI * 0.5f + _cameraState * MathF.PI) * 0.5f);
return true;
}
private void UpdateMarin()
{
if (marinState == MarinState.Stand)
{
_marinAnimator.Play("stand");
_marinStateCounter -= Game1.DeltaTime;
if (_marinStateCounter <= 0)
NextState();
}
else if (marinState == MarinState.Walk || marinState == MarinState.WalkSlow)
{
_marinAnimator.Play("move");
if (_marinPosition.X < _marinGoal.X)
{
_marinPosition.X += Game1.TimeMultiplier * (marinState == MarinState.Walk ? 0.5f : 0.25f);
}
else
{
_marinPosition = _marinGoal;
NextState();
}
}
else if (marinState == MarinState.Run)
{
_marinAnimator.SpeedMultiplier = 2.0f;
_marinAnimator.Play("move");
if (_marinPosition.X < _marinGoal.X)
{
_marinPosition.X += Game1.TimeMultiplier * 1.0f;
}
else
{
_marinPosition = _marinGoal;
_marinAnimator.SpeedMultiplier = 1.0f;
NextState();
}
}
else if (marinState == MarinState.Hold)
{
_marinAnimator.Play("hold");
_linkAnimator.Play("idle");
_marinStateCounter -= Game1.DeltaTime;
if (_marinStateCounter <= 0)
NextState();
}
else if (marinState == MarinState.Push)
{
_marinAnimator.Play("push");
_linkAnimator.Play("pushed");
_marinStateCounter -= Game1.DeltaTime;
if (_marinStateCounter <= 0)
NextState();
}
}
private void NextState()
{
marinState = _marinStates[_marinIndex];
_marinIndex++;
if (marinState == MarinState.Stand || marinState == MarinState.Hold || marinState == MarinState.Push)
{
_marinStateCounter = _marinTimes[_marinTimeIndex];
_marinTimeIndex++;
}
else if (marinState == MarinState.Walk || marinState == MarinState.WalkSlow || marinState == MarinState.Run)
{
_marinGoal = _marinGoalPositions[_marinWalkIndex];
_marinWalkIndex++;
}
}
public override void Draw(SpriteBatch spriteBatch)
{
Game1.Graphics.GraphicsDevice.Clear(_currentState == States.OceanPicture ? Color.Black : new Color(104, 96, 248));
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, TransformMatrix);
DrawOcean(spriteBatch);
DrawBeach(spriteBatch);
spriteBatch.End();
// draw the loading animation
if (_loadingTransparency > 0)
{
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, null, Game1.GetMatrix);
_loadingAnimator.DrawBasic(spriteBatch, new Vector2(
Game1.WindowWidth - 2 * _scale, Game1.WindowHeight - 2 * _scale), Color.White * _loadingTransparency, _scale);
spriteBatch.End();
}
}
private void DrawOcean(SpriteBatch spriteBatch)
{
if (_currentState != States.OceanCamera && _currentState != States.OceanPicture && _currentState != States.OceanThunder)
return;
var screenLeft = (int)Math.Floor(_cameraCenter.X) - (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0);
var screenRight = (int)Math.Ceiling(_cameraCenter.X) + (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0);
var screenTop = (int)Math.Floor(_cameraCenter.Y) - (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0);
var screenBottom = (int)Math.Ceiling(_cameraCenter.Y) + (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0);
var width = screenRight - screenLeft + 2;
var height = screenBottom - screenTop + 2;
var cloudOffset = _cameraCenter.X * 0.05f;
if (_currentState == States.OceanCamera || _currentState == States.OceanThunder)
{
// draw the dark cloud
spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, screenTop, width, -screenTop), new Color(24, 56, 40));
// draw the clouds
spriteBatch.Draw(_sprOcean,
new Rectangle(screenLeft, 0, width, _oceanCloudRectangle.Height),
new Rectangle(_oceanCloudRectangle.X + screenLeft - (int)cloudOffset,
_oceanCloudRectangle.Y + _thunderIndex * (_oceanCloudRectangle.Height + 16), width,
_oceanCloudRectangle.Height),
Color.White, 0, new Vector2(1 - cloudOffset % 1, 0), SpriteEffects.None, 0);
// draw the dark sky
spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, _oceanCloudRectangle.Height, width, 64), _oceanColor[_thunderIndex]);
// draw the ocean top
var oceanAnimationOffset = _thunderIndex * 64;
spriteBatch.Draw(_sprOcean,
new Rectangle(screenLeft, (int)_oceanPosition0.Y, width, _ocean0Rectangle.Height),
new Rectangle(_ocean0Rectangle.X + screenLeft - (int)_oceanPosition0.X,
_ocean0Rectangle.Y + oceanAnimationOffset, width, _ocean0Rectangle.Height),
Color.White, 0, new Vector2(1 - _oceanPosition0.X % 1, 0), SpriteEffects.None, 0);
// draw the ocean middle
spriteBatch.Draw(_sprOcean,
new Rectangle(screenLeft, (int)_oceanPosition1.Y, width, _ocean1Rectangle.Height),
new Rectangle(_ocean1Rectangle.X + screenLeft - (int)_oceanPosition1.X,
_ocean1Rectangle.Y + oceanAnimationOffset, width, _ocean1Rectangle.Height),
Color.White, 0, new Vector2(1 - _oceanPosition1.X % 1, 0), SpriteEffects.None, 0);
// draw the boat
DrawHelper.DrawNormalized(spriteBatch, _spriteOceanBoat, _oceanBoatPosition, Color.White);
// draw the ocean middle
spriteBatch.Draw(_sprOcean,
new Rectangle(screenLeft, (int)_oceanPosition2.Y, width, _ocean2Rectangle.Height),
new Rectangle(_ocean2Rectangle.X + screenLeft - (int)_oceanPosition2.X,
_ocean2Rectangle.Y + oceanAnimationOffset, width, _ocean2Rectangle.Height),
Color.White, 0, new Vector2(1 - _oceanPosition2.X % 1, 0), SpriteEffects.None, 0);
// draw the ocean
spriteBatch.Draw(_sprOcean,
new Rectangle(screenLeft, (int)_oceanPosition3.Y + 16, width, _oceanRectangle.Height),
new Rectangle(_oceanRectangle.X + screenLeft - (int)_oceanPosition3.X,
_oceanRectangle.Y + _thunderIndex * (_oceanRectangle.Height + 16), width, _oceanRectangle.Height),
Color.White, 0, new Vector2(1 - _oceanPosition3.X % 1, 0), SpriteEffects.None, 0);
// draw the dark ocean
spriteBatch.Draw(Resources.SprWhite,
new Rectangle(screenLeft, (int)_oceanPosition3.Y + 48, width,
screenBottom - ((int)_oceanPosition3.Y + 48)), new Color(16, 0, 104));
}
if (_currentState == States.OceanPicture)
{
_linkBoatAnimator.Draw(spriteBatch, Vector2.Zero, Color.White);
}
// draw the rain
var rainOffset = new Vector2((float)(Game1.TotalTime / 2.5f + Math.Sin(Game1.TotalTime / 500) * 5), (float)Game1.TotalTime / 2.3f);
spriteBatch.Draw(_sprRain,
new Rectangle(screenLeft, screenTop, width, height),
new Rectangle(screenLeft - (int)rainOffset.X, screenTop - (int)rainOffset.Y, width, height),
Color.White, 0, new Vector2(1 - rainOffset.X % 1, 1 - rainOffset.Y % 1), SpriteEffects.None, 0);
if (_currentState == States.OceanCamera)
{
// draw the thunder
for (var i = 0; i < _thunder.Length; i++)
_thunder[i].DrawBasic(spriteBatch, _thunderPositions[i] + new Vector2(cloudOffset, 0), Color.White);
}
else if (_currentState == States.OceanThunder)
{
// draw the thunder on top of the boat
_thunder[0].DrawBasic(spriteBatch, _thunderPositions[0] + new Vector2(cloudOffset, 0), Color.White);
if (_thunderTransition > 0)
{
var white = MathHelper.Clamp(_thunderTransition * 1.5f, 0, 1);
spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, screenTop, width, height), Color.White * white);
// draw the boat
var boatWhite = MathHelper.Clamp(1.5f - _thunderTransition * 1.5f, 0, 1);
DrawHelper.DrawNormalized(spriteBatch, _spriteOceanBoat, _oceanBoatPosition, Color.White * boatWhite);
}
}
//spriteBatch.Draw(Resources.SprWhite, new Rectangle(-2, 72, 4, 4), Color.Red);
}
private void DrawBeach(SpriteBatch spriteBatch)
{
if (_currentState != States.StrandFading && _currentState != States.StrandCamera &&
_currentState != States.StrandMarin && _currentState != States.StrandLogo)
return;
var screenLeft = (int)Math.Floor(_cameraCenter.X) - (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0);
var screenRight = (int)Math.Ceiling(_cameraCenter.X) + (int)Math.Ceiling(Game1.WindowWidth / (double)_scale / 2.0);
var screenTop = (int)Math.Floor(_cameraCenter.Y) - (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0);
var screenBottom = (int)Math.Ceiling(_cameraCenter.Y) + (int)Math.Ceiling(Game1.WindowHeight / (double)_scale / 2.0);
var width = screenRight - screenLeft + 2;
var height = screenBottom - screenTop + 1;
// draw the sky white
spriteBatch.Draw(Resources.SprWhite, new Rectangle(
screenLeft, screenTop, width, -screenTop + 47), new Color(248, 248, 248));
var mountainOffset = new Vector2((float)(Math.Round(_cameraCenter.X * 0.5f * _scale) / _scale), 0);
// draw the clouds on the left
var cloudLeft = -_spriteBackground.ScaledRectangle.Width / 2;
if (screenLeft < cloudLeft + (int)mountainOffset.X)
spriteBatch.Draw(_sprCloud,
new Rectangle(screenLeft, (int)_cloundLeftPosition.Y, (cloudLeft + (int)mountainOffset.X) - screenLeft, _sprCloud.Height),
new Rectangle(screenLeft - (int)mountainOffset.X, 0, (cloudLeft + (int)mountainOffset.X) - screenLeft, _sprCloud.Height),
Color.White, 0, new Vector2(-mountainOffset.X % 1, 0), SpriteEffects.None, 0);
// draw the clouds on the right
var cloudRight = _spriteBackground.ScaledRectangle.Width / 2;
if (cloudRight + (int)mountainOffset.X < screenRight)
spriteBatch.Draw(_sprCloud,
new Rectangle(cloudRight + (int)mountainOffset.X, (int)_cloundLeftPosition.Y, screenRight - (cloudRight + (int)mountainOffset.X), _sprCloud.Height),
new Rectangle(0, 0, screenRight - (cloudRight + (int)mountainOffset.X), _sprCloud.Height),
Color.White, 0, new Vector2(-mountainOffset.X % 1, 0), SpriteEffects.None, 0);
// draw the top of the mountain
spriteBatch.Draw(_sprIntro, new Vector2(-_spriteBackground.ScaledRectangle.Width / 2, 0) + mountainOffset, _spriteBackground.ScaledRectangle, Color.White);
// draw the left side of the mountain
spriteBatch.Draw(_sprIntro, _mountainLeftPosition + mountainOffset, _spriteMountain.SourceRectangle,
Color.White, 0, Vector2.Zero, 1, SpriteEffects.FlipHorizontally, 0);
// draw the right side of the mountain
spriteBatch.Draw(_sprIntro, _mountainRightPosition + mountainOffset, _spriteMountain.SourceRectangle, Color.White);
// draw the trees
var treeOffset = new Vector2(_cameraCenter.X * 0.075f, 0);
spriteBatch.Draw(_sprWaves,
new Rectangle(screenLeft, (int)_treePosition.Y, width, _treesRectangle.Height),
new Rectangle(_treesRectangle.X + screenLeft - (int)treeOffset.X, _treesRectangle.Y, width, _treesRectangle.Height),
Color.White, 0, new Vector2(1 - treeOffset.X % 1, 0), SpriteEffects.None, 0);
// draw the strand
var strandOffset = new Vector2(-_cameraCenter.X * 0.025f, 0);
spriteBatch.Draw(_sprWaves,
new Rectangle(screenLeft, (int)_treePosition.Y + _treesRectangle.Height, width, _sandRectangle.Height),
new Rectangle(_sandRectangle.X + screenLeft - (int)strandOffset.X, _sandRectangle.Y, width, _sandRectangle.Height),
Color.White, 0, new Vector2(1 - strandOffset.X % 1, 0), SpriteEffects.None, 0);
// draw the waves
spriteBatch.Draw(_sprWaves,
new Rectangle(screenLeft, (int)_wavePosition.Y, width, _waveRectangle.Height),
new Rectangle(_waveRectangle.X + screenLeft - (int)strandOffset.X, _waveRectangle.Y + _currentFrame * 32, width, _waveRectangle.Height),
Color.White, 0, new Vector2(1 - strandOffset.X % 1, 0), SpriteEffects.None, 0);
// draw marin
_marinAnimator.DrawBasic(spriteBatch, _marinPosition, Color.White);
// draw link
_linkAnimator.DrawBasic(spriteBatch, new Vector2(-8, 225), Color.White);
// draw the logo
{
var logoHeight = (int)(_spriteLogo0.SourceRectangle.Height * (MathF.Sin(_logoState * MathF.PI - MathF.PI / 2) * 0.5f + 0.5f));
logoHeight += logoHeight % 2;
spriteBatch.Draw(_spriteLogo0.Texture,
new Rectangle((int)_logoPosition.X, (int)_logoPosition.Y + _spriteLogo0.SourceRectangle.Height / 2 - logoHeight / 2,
_spriteLogo0.SourceRectangle.Width, logoHeight), _spriteLogo0.ScaledRectangle, Color.White);
var textTransparency = Math.Clamp((_logoState - 0.5f) * 2, 0, 1);
DrawHelper.DrawNormalized(spriteBatch, _spriteLogo1, _logoPosition, Color.White * textTransparency);
}
var lightPosition = _logoPosition + _ligthPosition;
// draw the light around the logo
if (_lightAnimation.IsPlaying)
_lightAnimation.DrawBasic(spriteBatch, lightPosition, Color.White);
// draw the white forground for the fadein
if (_strandFadeCount > 0)
{
var white = MathHelper.Clamp(_strandFadeCount / StrandFadeTime, 0, 1);
spriteBatch.Draw(Resources.SprWhite, new Rectangle(screenLeft, screenTop, width, height), Color.White * white);
}
}
}
}