LADXHD/InGame/GameObjects/Things/ObjSmallStone.cs
2023-12-14 17:21:22 -05:00

102 lines
4.2 KiB
C#

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.Things;
namespace ProjectZ.InGame.GameObjects.Things
{
internal class ObjSmallStone : GameObject
{
private readonly BodyComponent _bodyComponent;
private readonly BodyDrawShadowComponent _shadowComponent;
private readonly CSprite _sprite;
private float _despawnCounter;
private readonly int _fadeOutTime = 75;
private readonly int _despawnTime = 150;
private readonly bool _blueStone;
public ObjSmallStone(Map.Map map, int posX, int posY, int posZ, Vector3 velocity, bool flipSprite = false, int despawnTime = 0) : base(map)
{
EntityPosition = new CPosition(posX, posY + 8, posZ);
EntitySize = new Rectangle(-4, -24, 8, 24);
if (despawnTime > 0)
_despawnTime = despawnTime;
else
_despawnTime = Game1.RandomNumber.Next(225, 275);
_bodyComponent = new BodyComponent(EntityPosition, -4, -8, 8, 8, 8)
{
CollisionTypes = Values.CollisionTypes.None,
Bounciness = 0.75f,
Gravity = -0.15f,
Gravity2D = 0.1f,
Drag = 0.5f,
DragAir = 1.0f,
MaxJumpHeight = 8,
IsGrounded = false, // this is needed for the MaxJumpHeight to work
Velocity = velocity,
MoveCollision = OnCollision
};
_blueStone = posZ > 32;
var sourceRectangle = Resources.SourceRectangle(_blueStone ? "stone_particle_1" : "stone_particle");
_sprite = new CSprite(Resources.SprObjects, EntityPosition, sourceRectangle, new Vector2(-4, -8));
_sprite.Color = Color.White;
_sprite.SpriteEffect = flipSprite ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
AddComponent(BodyComponent.Index, _bodyComponent);
if (_blueStone)
AddComponent(UpdateComponent.Index, new UpdateComponent(UpdateBounceDespawn));
else
AddComponent(UpdateComponent.Index, new UpdateComponent(Update));
AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, _blueStone ? Values.LayerPlayer : Values.LayerTop));
AddComponent(DrawShadowComponent.Index, _shadowComponent = new BodyDrawShadowComponent(_bodyComponent, _sprite));
}
private void OnCollision(Values.BodyCollision collision)
{
// jump in a random direction
if (_blueStone && (collision & Values.BodyCollision.Floor) != 0)
{
_bodyComponent.Velocity.X = Game1.RandomNumber.Next(0, 11) / 5f - 1.0f;
_bodyComponent.Velocity.Y = Game1.RandomNumber.Next(0, 11) / 5f - 1.0f;
if (_bodyComponent.Velocity.Z > 2.0f)
_bodyComponent.Velocity.Z = 2.0f;
}
// reflect of a wall
if ((collision & Values.BodyCollision.Horizontal) != 0)
_bodyComponent.Velocity.X = -_bodyComponent.Velocity.X * 0.25f;
if ((collision & Values.BodyCollision.Vertical) != 0)
_bodyComponent.Velocity.Y = -_bodyComponent.Velocity.Y * 0.25f;
}
private void UpdateBounceDespawn()
{
if (_bodyComponent.Velocity.Z == 0 && _bodyComponent.IsGrounded)
{
Map.Objects.DeleteObjects.Add(this);
}
}
private void Update()
{
_despawnCounter += Game1.DeltaTime;
var transparency = (1 - (_despawnCounter - _despawnTime) / _fadeOutTime);
_sprite.Color = Color.White * transparency;
_shadowComponent.Transparency = transparency;
// delete the object
if (_despawnCounter >= _despawnTime + _fadeOutTime)
Map.Objects.DeleteObjects.Add(this);
}
}
}