LADXHD/InGame/GameObjects/Base/CObjects/CSprite.cs
2023-12-14 17:21:22 -05:00

117 lines
4.2 KiB
C#

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ProjectZ.InGame.Map;
using ProjectZ.InGame.SaveLoad;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.GameObjects.Base.CObjects
{
public class CSprite
{
public Texture2D SprTexture;
public CPosition Position;
public SpriteShader SpriteShader;
public SpriteEffects SpriteEffect;
public Rectangle SourceRectangle;
public Vector2 DrawOffset;
public Vector2 Center;
public Color Color = Color.White;
public float Scale = 1;
public float Rotation;
public bool IsVisible = true;
public CSprite(CPosition position)
{
Position = position;
}
public CSprite(Texture2D sprTexture, Rectangle sourceRectangle)
{
SprTexture = sprTexture;
SourceRectangle = sourceRectangle;
}
public CSprite(Texture2D sprTexture, CPosition position, Rectangle sourceRectangle, Vector2 drawOffset)
{
SprTexture = sprTexture;
Position = position;
SourceRectangle = sourceRectangle;
DrawOffset = drawOffset;
}
public CSprite(DictAtlasEntry sprite, CPosition position)
{
SetSprite(sprite);
Position = position;
}
public CSprite(string spriteId, CPosition position) : this(Resources.GetSprite(spriteId), position)
{ }
// @REMOVE: drawOffset should probably be the center in most cases?
public CSprite(DictAtlasEntry sprite, CPosition position, Vector2 drawOffset)
{
SetSprite(sprite);
Position = position;
DrawOffset = drawOffset;
}
// @REMOVE: drawOffset should probably be the center in most cases?
public CSprite(string spriteId, CPosition position, Vector2 drawOffset) :
this(Resources.GetSprite(spriteId), position, drawOffset)
{ }
public void SetSprite(DictAtlasEntry sprite)
{
SprTexture = sprite.Texture;
SourceRectangle = sprite.ScaledRectangle;
Scale = sprite.Scale;
Center = sprite.ScaledOrigin;
}
public void Draw(SpriteBatch spriteBatch)
{
if (!IsVisible)
return;
// this is used to align the sprite to avoid holes
var normX = (float)Math.Round((Position.X + DrawOffset.X) * MapManager.Camera.Scale) / MapManager.Camera.Scale;
var normY = (float)Math.Round((Position.Y + DrawOffset.Y - Position.Z) * MapManager.Camera.Scale) / MapManager.Camera.Scale;
// change the draw effect
if (SpriteShader != null)
{
spriteBatch.End();
ObjectManager.SpriteBatchBegin(spriteBatch, SpriteShader);
}
spriteBatch.Draw(SprTexture, new Vector2(normX, normY), SourceRectangle, Color, Rotation, Center * Scale, new Vector2(Scale), SpriteEffect, 0);
// change the draw effect
// this would not be very efficient if a lot of sprite used effects
if (SpriteShader != null)
{
spriteBatch.End();
ObjectManager.SpriteBatchBegin(spriteBatch, null);
}
}
public void DrawShadow(SpriteBatch spriteBatch, Color color, int offsetY, float height, float rotation)
{
if (!IsVisible)
return;
var normX = (float)Math.Round((Position.X + DrawOffset.X - Center.X) * MapManager.Camera.Scale) / MapManager.Camera.Scale;
var normY = (float)Math.Round((Position.Y + DrawOffset.Y - Center.Y - Position.Z * 0.5f + offsetY) * MapManager.Camera.Scale) / MapManager.Camera.Scale;
// TODO_OPT: this does currently not support FlipVertically
DrawHelper.DrawShadow(SprTexture, new Vector2(normX, normY),
SourceRectangle, SourceRectangle.Width, SourceRectangle.Height,
SpriteEffect == SpriteEffects.FlipHorizontally, height, rotation, color);
}
}
}