mirror of
https://github.com/Phantop/LADXHD.git
synced 2024-11-01 04:14:22 +00:00
241 lines
9.2 KiB
C#
241 lines
9.2 KiB
C#
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using ProjectZ.InGame.GameObjects;
|
|
using ProjectZ.InGame.SaveLoad;
|
|
using ProjectZ.InGame.Things;
|
|
|
|
namespace ProjectZ.InGame.Map
|
|
{
|
|
public class MapManager
|
|
{
|
|
public static Camera Camera;
|
|
public static ObjLink ObjLink;
|
|
|
|
public static BlendState LightBlendState = new BlendState();
|
|
|
|
public Map CurrentMap;
|
|
public Map NextMap;
|
|
|
|
public bool UpdateCameraX;
|
|
public bool UpdateCameraY;
|
|
|
|
private Matrix blurMatrix;
|
|
|
|
public MapManager()
|
|
{
|
|
CurrentMap = new Map();
|
|
NextMap = new Map();
|
|
Camera = new Camera();
|
|
|
|
LightBlendState.ColorBlendFunction = BlendFunction.Add;
|
|
LightBlendState.ColorDestinationBlend = Blend.InverseSourceAlpha;
|
|
LightBlendState.ColorSourceBlend = Blend.One;
|
|
|
|
LightBlendState.AlphaBlendFunction = BlendFunction.Max;
|
|
LightBlendState.AlphaDestinationBlend = Blend.One;
|
|
LightBlendState.AlphaSourceBlend = Blend.One;
|
|
}
|
|
|
|
public void Load()
|
|
{
|
|
ObjLink = new ObjLink();
|
|
}
|
|
|
|
public void Update(bool frozen)
|
|
{
|
|
// update the objects on the map
|
|
CurrentMap.Objects.Update(frozen);
|
|
|
|
CurrentMap.UpdateMapUpdateState();
|
|
|
|
UpdateCamera();
|
|
}
|
|
|
|
public void UpdateAnimation()
|
|
{
|
|
CurrentMap.Objects.UpdateAnimations();
|
|
}
|
|
|
|
public Vector2 GetCameraTarget()
|
|
{
|
|
// update the camera
|
|
if (CurrentMap.CameraTarget.HasValue)
|
|
return CurrentMap.CameraTarget.Value * Camera.Scale;
|
|
|
|
return GetCameraTargetLink();
|
|
}
|
|
|
|
public Vector2 GetCameraTargetLink()
|
|
{
|
|
return new Vector2(ObjLink.PosX, ObjLink.PosY - 4) * Camera.Scale;
|
|
}
|
|
|
|
public void UpdateCamera()
|
|
{
|
|
//if (!UpdateCameraX)
|
|
//centerPosition.Y -= ObjLink.EntityPosition.Z;
|
|
|
|
// center the map vertical if it is smaller than the screen
|
|
// not so sure about this
|
|
//if (CurrentMap.MapHeight * 16 * Camera.Scale < Game1.WindowHeight)
|
|
// centerPosition.Y = CurrentMap.MapHeight * 8 * Camera.Scale;
|
|
|
|
if (UpdateCameraX || UpdateCameraY)
|
|
Camera.Center(GetCameraTarget(), UpdateCameraX, UpdateCameraY);
|
|
|
|
UpdateCameraX = true;
|
|
UpdateCameraY = true;
|
|
}
|
|
|
|
public void Draw(SpriteBatch spriteBatch)
|
|
{
|
|
// draw the objects under the tilemap
|
|
CurrentMap.Objects.DrawBottom(spriteBatch);
|
|
|
|
//Game1.StopWatchTracker.Start("draw tile layers");
|
|
|
|
// draw the tile map
|
|
CurrentMap.TileMap.Draw(spriteBatch);
|
|
|
|
//Game1.StopWatchTracker.Stop();
|
|
|
|
// draw the objects draw over the tileset
|
|
CurrentMap.Objects.DrawMiddle(spriteBatch);
|
|
|
|
// draw the blured part of the tile map
|
|
DrawBlur(spriteBatch, Game1.GameManager.TempRT2, Game1.GameManager.TempRT0, Game1.GameManager.TempRT1);
|
|
|
|
// draw the objects
|
|
CurrentMap.Objects.Draw(spriteBatch);
|
|
|
|
spriteBatch.End();
|
|
}
|
|
|
|
public void DrawBegin(SpriteBatch spriteBatch, Effect spriteEffect)
|
|
{
|
|
if (!Game1.GameManager.UseShockEffect)
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null, spriteEffect, blurMatrix);
|
|
else
|
|
ObjectManager.SpriteBatchBegin(spriteBatch, null);
|
|
}
|
|
|
|
private void DrawBlur(SpriteBatch spriteBatch, RenderTarget2D blurRT0, RenderTarget2D blurRT1, RenderTarget2D blurRT2)
|
|
{
|
|
var matrixPosition = Vector2.Zero;
|
|
|
|
if (!Game1.GameManager.UseShockEffect)
|
|
{
|
|
Game1.Graphics.GraphicsDevice.SetRenderTarget(blurRT0);
|
|
Game1.Graphics.GraphicsDevice.Clear(Color.Transparent);
|
|
|
|
var cameraPosition = new Vector2(Camera.RoundX / Camera.Scale, Camera.RoundY / Camera.Scale);
|
|
// offset the position a little bit because we render a bigger region to avoid artefacts at the edges
|
|
matrixPosition = new Vector2((int)cameraPosition.X - 1, (int)cameraPosition.Y - 1);
|
|
|
|
blurMatrix = Matrix.CreateScale(1) *
|
|
Matrix.CreateTranslation(new Vector3(-matrixPosition.X, -matrixPosition.Y, 0)) *
|
|
Matrix.CreateTranslation(new Vector3(
|
|
(int)(Game1.GameManager.SideBlurRenderTargetWidth * 0.5f),
|
|
(int)(Game1.GameManager.SideBlurRenderTargetHeight * 0.5f), 0)) *
|
|
Matrix.CreateScale(new Vector3(
|
|
(float)blurRT0.Width / Game1.GameManager.SideBlurRenderTargetWidth,
|
|
(float)blurRT0.Height / Game1.GameManager.SideBlurRenderTargetHeight, 0));
|
|
}
|
|
|
|
DrawBegin(spriteBatch, null);
|
|
|
|
// draw object blur stuff
|
|
CurrentMap.Objects.DrawBlur(spriteBatch);
|
|
|
|
// blur tile maps
|
|
CurrentMap.TileMap.DrawBlurLayer(spriteBatch);
|
|
|
|
spriteBatch.End();
|
|
|
|
if (Game1.GameManager.UseShockEffect)
|
|
return;
|
|
|
|
Resources.BBlurEffectH.Parameters["pixelX"].SetValue(1.0f / blurRT1.Width);
|
|
Resources.BBlurEffectV.Parameters["pixelY"].SetValue(1.0f / blurRT1.Height);
|
|
|
|
// v blur
|
|
Game1.Graphics.GraphicsDevice.SetRenderTarget(blurRT1);
|
|
Game1.Graphics.GraphicsDevice.Clear(Color.Transparent);
|
|
// offset the render target so that we always sample at the same position
|
|
var blurX = -(matrixPosition.X % 2) / 2 + (blurRT1.Width % 2 * 0.5f);
|
|
var blurY = -(matrixPosition.Y % 2) / 2 + (blurRT1.Height % 2 * 0.5f);
|
|
spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BBlurEffectV, null);
|
|
spriteBatch.Draw(blurRT0, new Vector2(blurX, blurY),
|
|
new Rectangle(0, 0, blurRT0.Width, blurRT0.Height), Color.White, 0, Vector2.Zero, 0.5f, SpriteEffects.None, 0);
|
|
spriteBatch.End();
|
|
|
|
// h blur
|
|
Game1.Graphics.GraphicsDevice.SetRenderTarget(blurRT2);
|
|
Game1.Graphics.GraphicsDevice.Clear(Color.Transparent);
|
|
spriteBatch.Begin(SpriteSortMode.Immediate, null, SamplerState.AnisotropicClamp, null, null, Resources.BBlurEffectH, null);
|
|
spriteBatch.Draw(blurRT1, Vector2.Zero, Color.White);
|
|
spriteBatch.End();
|
|
|
|
Game1.GameManager.SetActiveRenderTarget();
|
|
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.AnisotropicClamp, null, null, null, Camera.TransformMatrix);
|
|
|
|
// calculate offset to make sure that the render target is at the correct position
|
|
var scale = new Vector2((float)Game1.GameManager.BlurRenderTargetWidth / blurRT1.Width * 2, (float)Game1.GameManager.BlurRenderTargetHeight / blurRT1.Height * 2);
|
|
spriteBatch.Draw(blurRT2, new Vector2(
|
|
matrixPosition.X + matrixPosition.X % 2 - (int)(Game1.GameManager.SideBlurRenderTargetWidth * 0.5f) - (int)(Game1.RenderWidth / (Camera.Scale * 2)) % 2,
|
|
matrixPosition.Y + matrixPosition.Y % 2 - (int)(Game1.GameManager.SideBlurRenderTargetHeight * 0.5f) - (int)(Game1.RenderHeight / (Camera.Scale * 2)) % 2),
|
|
new Rectangle(0, 0, blurRT2.Width, blurRT2.Height), Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, 0);
|
|
|
|
spriteBatch.End();
|
|
}
|
|
|
|
public void DrawLight(SpriteBatch spriteBatch)
|
|
{
|
|
Game1.Graphics.GraphicsDevice.Clear(CurrentMap.LightColor);
|
|
|
|
spriteBatch.Begin(SpriteSortMode.Deferred, LightBlendState, SamplerState.AnisotropicClamp, null, null, null, Camera.TransformMatrix);
|
|
|
|
CurrentMap.Objects.DrawLight(spriteBatch);
|
|
|
|
spriteBatch.End();
|
|
}
|
|
|
|
public void ReloadMap()
|
|
{
|
|
// @Hack
|
|
var tempTm = CurrentMap;
|
|
CurrentMap = NextMap;
|
|
NextMap = tempTm;
|
|
|
|
NextMap.Objects.ReloadObjects();
|
|
NextMap.Objects.SpawnObject(ObjLink);
|
|
|
|
// reset the hole map
|
|
SaveLoadMap.CreateEmptyHoleMap(NextMap.HoleMap, NextMap.MapWidth, NextMap.MapHeight);
|
|
|
|
ObjLink.MapInit();
|
|
|
|
tempTm = CurrentMap;
|
|
CurrentMap = NextMap;
|
|
NextMap = tempTm;
|
|
|
|
CurrentMap.Objects.TriggerKeyChange();
|
|
}
|
|
|
|
public void FinishLoadingMap(Map map)
|
|
{
|
|
ObjLink.Map.Objects.RemoveObject(ObjLink);
|
|
|
|
// set the player to the correct position
|
|
ObjLink.FinishLoadingMap(map);
|
|
|
|
// add the player to the map
|
|
map.Objects.SpawnObject(ObjLink);
|
|
|
|
// call key change event for the newly added objects
|
|
map.Objects.TriggerKeyChange();
|
|
}
|
|
}
|
|
}
|