mirror of
https://github.com/Phantop/LADXHD.git
synced 2024-11-25 16:03:02 +00:00
184 lines
7.6 KiB
C#
184 lines
7.6 KiB
C#
using System;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using ProjectZ.InGame.GameObjects.Base;
|
|
using ProjectZ.InGame.GameObjects.Base.CObjects;
|
|
using ProjectZ.InGame.GameObjects.Base.Components;
|
|
using ProjectZ.InGame.Map;
|
|
using ProjectZ.InGame.SaveLoad;
|
|
using ProjectZ.InGame.Things;
|
|
|
|
namespace ProjectZ.InGame.GameObjects.Things
|
|
{
|
|
internal class ObjIslandBackground : GameObject
|
|
{
|
|
class Cloud
|
|
{
|
|
public int Index;
|
|
public float LiveCounter;
|
|
public float Transparency = 1;
|
|
public Vector2 Position;
|
|
|
|
public Cloud(int index, Vector2 position)
|
|
{
|
|
Index = index;
|
|
Position = position;
|
|
LiveCounter = Game1.RandomNumber.Next(5000, 50000);
|
|
}
|
|
}
|
|
|
|
private Rectangle[] cloudSourceRectangles = new Rectangle[3];
|
|
|
|
private Cloud[] _clouds;
|
|
|
|
private const int GradientHeight = 120;
|
|
|
|
private readonly Rectangle _waveSource;
|
|
private readonly Rectangle _topWaveSource;
|
|
|
|
private readonly Color _colorSky = new Color(65, 90, 255);
|
|
private readonly Color _colorOceanBright = new Color(66, 89, 255);
|
|
|
|
private readonly DictAtlasEntry _oceanGradient;
|
|
|
|
private const int LeftCloudPosition = -1300;
|
|
|
|
private int _topWaveFrame;
|
|
private int _topWaveSpeed = 250;
|
|
|
|
public ObjIslandBackground() : base("water_3") { }
|
|
|
|
public ObjIslandBackground(Map.Map map, int posX, int posY) : base(map)
|
|
{
|
|
_waveSource = Resources.SourceRectangle("water_3");
|
|
_waveSource.Width = 16;
|
|
_topWaveSource = Resources.SourceRectangle("water_12");
|
|
_topWaveSource.Width = 16;
|
|
|
|
cloudSourceRectangles[0] = Resources.SourceRectangle("cloud_0");
|
|
cloudSourceRectangles[1] = Resources.SourceRectangle("cloud_1");
|
|
cloudSourceRectangles[2] = Resources.SourceRectangle("cloud_2");
|
|
|
|
_clouds = new Cloud[50];
|
|
|
|
_oceanGradient = Resources.GetSprite("overworld_gradient");
|
|
|
|
// spawn the clouds
|
|
var positionX = LeftCloudPosition;
|
|
for (var i = 0; i < _clouds.Length; i++)
|
|
{
|
|
var index = Game1.RandomNumber.Next(0, cloudSourceRectangles.Length);
|
|
_clouds[i] = new Cloud(index, new Vector2(positionX, 32 - cloudSourceRectangles[index].Height));
|
|
positionX += cloudSourceRectangles[index].Width + Game1.RandomNumber.Next(1, 7) * 16;
|
|
}
|
|
|
|
AddComponent(UpdateComponent.Index, new UpdateComponent(Update));
|
|
AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerBackground, new CPosition(posX, posY, 0)));
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
// all the animations are in sync
|
|
_topWaveFrame = ((int)(Game1.TotalGameTime) % (4 * _topWaveSpeed)) / _topWaveSpeed;
|
|
|
|
// move the clouds
|
|
foreach (var cloud in _clouds)
|
|
{
|
|
var cloudSpeed = (Math.Sin(cloud.Position.X / 100) * 0.125 + 1) * 0.015 * Game1.TimeMultiplier;
|
|
cloud.Position.X -= (float)cloudSpeed;
|
|
|
|
// set the cloud to the right position
|
|
if (cloud.Position.X < LeftCloudPosition)
|
|
{
|
|
float rightPosition = 0;
|
|
foreach (var cloud1 in _clouds)
|
|
{
|
|
if (cloud1.Position.X > rightPosition)
|
|
rightPosition = cloud1.Position.X + cloudSourceRectangles[cloud1.Index].Width;
|
|
}
|
|
cloud.Position.X = rightPosition + Game1.RandomNumber.Next(1, 7) * 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Draw(SpriteBatch spriteBatch)
|
|
{
|
|
if (MapManager.Camera.Scale <= 0)
|
|
return;
|
|
|
|
var cameraRectangle = MapManager.Camera.GetCameraRectangle();
|
|
|
|
var left = (int)(cameraRectangle.X / _waveSource.Width / MapManager.Camera.Scale) - 1;
|
|
var right = (int)(cameraRectangle.Right / _waveSource.Width / MapManager.Camera.Scale) + 1;
|
|
var top = (int)(cameraRectangle.Y / _waveSource.Height / MapManager.Camera.Scale);
|
|
var bottom = (int)(cameraRectangle.Bottom / _waveSource.Height / MapManager.Camera.Scale) + 1;
|
|
|
|
if (cameraRectangle.X < 0)
|
|
{
|
|
left--;
|
|
right++;
|
|
}
|
|
if (cameraRectangle.Y < 0)
|
|
{
|
|
top--;
|
|
bottom++;
|
|
}
|
|
|
|
// draw the top waves
|
|
if (top <= 2 && bottom > 2)
|
|
for (var x = left; x < right + 1; x++)
|
|
{
|
|
spriteBatch.Draw(Resources.SprObjects, new Rectangle(
|
|
x * _topWaveSource.Width, 2 * _topWaveSource.Height, _topWaveSource.Width, _topWaveSource.Height),
|
|
new Rectangle(
|
|
_topWaveSource.X + _topWaveSource.Width * _topWaveFrame, _topWaveSource.Y,
|
|
_topWaveSource.Width, _topWaveSource.Height), Color.White);
|
|
}
|
|
|
|
// change context to have smooth gradient transition
|
|
spriteBatch.End();
|
|
ObjectManager.SpriteBatchBeginAnisotropic(spriteBatch, null);
|
|
|
|
if (top <= 10 && bottom >= 4)
|
|
DrawGradient(spriteBatch, left, right, 3, 10);
|
|
if (left < 1)
|
|
DrawGradient(spriteBatch, left, 2, Math.Max(3, top), Math.Min(bottom, GradientHeight + 3));
|
|
if (right > 16 * 10)
|
|
DrawGradient(spriteBatch, 16 * 10, right, Math.Max(3, top), Math.Min(bottom, GradientHeight + 3));
|
|
|
|
spriteBatch.End();
|
|
ObjectManager.SpriteBatchBegin(spriteBatch, null);
|
|
|
|
var oceanBottomTop = Math.Max(3 + GradientHeight, top);
|
|
var oceanBottomBottom = Math.Max(3 + GradientHeight, bottom);
|
|
|
|
spriteBatch.Draw(Resources.SprWhite, new Rectangle(
|
|
left * Values.TileSize, oceanBottomTop * Values.TileSize, (right - left + 1) * Values.TileSize, (oceanBottomBottom - oceanBottomTop + 1) * Values.TileSize), _colorOceanBright);
|
|
|
|
// draw the sky
|
|
if (top < 2)
|
|
{
|
|
spriteBatch.Draw(Resources.SprWhite, new Rectangle(
|
|
left * 16, (top - 1) * 16,
|
|
(right - left + 1) * 16, (-top + 3) * 16), _colorSky);
|
|
}
|
|
|
|
// draw the clouds
|
|
foreach (var cloud in _clouds)
|
|
{
|
|
DrawHelper.DrawNormalized(spriteBatch, Resources.SprObjects, cloud.Position, cloudSourceRectangles[cloud.Index], Color.White * cloud.Transparency);
|
|
}
|
|
}
|
|
|
|
private void DrawGradient(SpriteBatch spriteBatch, int left, int right, int top, int bottom)
|
|
{
|
|
spriteBatch.Draw(_oceanGradient.Texture, new Rectangle(
|
|
left * Values.TileSize, top * Values.TileSize, (right - left) * Values.TileSize, (bottom - top) * Values.TileSize),
|
|
new Rectangle(
|
|
_oceanGradient.ScaledRectangle.X,
|
|
_oceanGradient.ScaledRectangle.Y + (int)(_oceanGradient.ScaledRectangle.Height * ((top + 0) / (float)GradientHeight)),
|
|
_oceanGradient.ScaledRectangle.Width,
|
|
(int)(_oceanGradient.ScaledRectangle.Height * ((bottom - (top + 3)) / (float)GradientHeight))), Color.White);
|
|
}
|
|
}
|
|
} |