LADXHD/InGame/GameObjects/NPCs/ObjButterfly.cs

101 lines
4.2 KiB
C#
Raw Normal View History

2023-12-14 22:21:22 +00:00
using System;
using Microsoft.Xna.Framework;
using ProjectZ.InGame.GameObjects.Base;
using ProjectZ.InGame.GameObjects.Base.CObjects;
using ProjectZ.InGame.GameObjects.Base.Components;
using ProjectZ.InGame.SaveLoad;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.GameObjects.NPCs
{
internal class ObjButterfly : GameObject
{
private Animator _animator;
private readonly Vector2 _startPosition;
private Vector2 _direction;
private float _currentRotation;
private float _directionChange;
private float _currentSpeed;
private float _lastSpeed;
private float _speedGoal;
private float _flyCounter;
private int _flyTime;
private const int MinSpeed = 25;
private const int MaxSpeed = 45;
// the butterfly will stay around this distance from the start point
private int _startDistance;
public ObjButterfly() : base("butterfly") { }
public ObjButterfly(Map.Map map, int posX, int posY) : base(map)
{
_startPosition = new Vector2(posX, posY);
EntityPosition = new CPosition(posX + 8, posY + 8 + 15, 15);
EntitySize = new Rectangle(-4, -24, 8, 24);
_startDistance = Game1.RandomNumber.Next(25, 100);
_currentRotation = (Game1.RandomNumber.Next(0, 100) / 100f) * (float)(Math.PI * 2);
_currentSpeed = Game1.RandomNumber.Next(MinSpeed, MaxSpeed) / 100f;
_lastSpeed = _currentSpeed;
_speedGoal = Game1.RandomNumber.Next(MinSpeed, MaxSpeed) / 100f;
_animator = AnimatorSaveLoad.LoadAnimator("NPCs/butterfly");
_animator.Play("idle");
var sprite = new CSprite(EntityPosition);
var animationComponent = new AnimationComponent(_animator, sprite, Vector2.Zero);
AddComponent(UpdateComponent.Index, new UpdateComponent(Update));
AddComponent(BaseAnimationComponent.Index, animationComponent);
AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerTop));
}
public void Update()
{
_flyCounter -= Game1.DeltaTime;
if (_flyCounter < 0)
{
_flyTime = Game1.RandomNumber.Next(500, 1000);
_flyCounter += _flyTime;
// set a new speed goal
_lastSpeed = _speedGoal;
_speedGoal = Game1.RandomNumber.Next(MinSpeed, MaxSpeed) / 100f;
var startDifference = EntityPosition.Position - _startPosition;
var targetRotation = Math.Atan2(startDifference.Y, startDifference.X);
var randomDirection = ((Game1.RandomNumber.Next(0, 20) - 10) / 6f) * ((float)Math.PI / (60 * (_flyCounter / 1000f)));
var rotationDifference = (float)targetRotation - _currentRotation;
while (rotationDifference < 0)
rotationDifference += (float)Math.PI * 2;
rotationDifference = rotationDifference % (float)(Math.PI * 2);
rotationDifference -= (float)Math.PI;
var newRotation = rotationDifference / (60 * (_flyCounter / 1000f));
// calculate the new rotation direction of the butterfly
// the farther away it is from the start position the more likely it is to rotate to face the start position
_directionChange = MathHelper.Lerp(randomDirection, newRotation, startDifference.Length() / _startDistance);
}
// update the speed
_currentSpeed = MathHelper.Lerp(_speedGoal, _lastSpeed, _flyCounter / (float)_flyTime);
// update direction
_currentRotation += _directionChange * Game1.TimeMultiplier;
_currentRotation = _currentRotation % (float)(Math.PI * 2);
_direction = new Vector2((float)Math.Cos(_currentRotation), (float)Math.Sin(_currentRotation)) *
(_animator.CurrentFrameIndex == 0 ? _currentSpeed : _currentSpeed * 1.125f);
EntityPosition.Move(_direction);
}
}
}