mirror of
https://github.com/Phantop/LADXHD.git
synced 2024-11-01 04:14:22 +00:00
147 lines
4.9 KiB
C#
147 lines
4.9 KiB
C#
using System;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using ProjectZ.InGame.Things;
|
|
|
|
namespace ProjectZ.InGame.Map
|
|
{
|
|
public class Camera
|
|
{
|
|
public Matrix TransformMatrix => Matrix.CreateScale(Scale) *
|
|
Matrix.CreateTranslation(new Vector3(-RoundX, -RoundY, 0)) *
|
|
Matrix.CreateTranslation(new Vector3((int)(_viewportWidth * 0.5f), (int)(_viewportHeight * 0.5f), 0)) *
|
|
Game1.GameManager.GetMatrix;
|
|
public Vector2 Location;
|
|
public Vector2 MoveLocation;
|
|
|
|
// this is needed so there is no texture bleeding while rendering the game
|
|
public float RoundX => (int)Math.Round(Location.X + ShakeOffsetX * Scale, MidpointRounding.AwayFromZero);
|
|
public float RoundY => (int)Math.Round(Location.Y + ShakeOffsetY * Scale, MidpointRounding.AwayFromZero);
|
|
|
|
public float Scale = 4;
|
|
public float ShakeOffsetX;
|
|
public float ShakeOffsetY;
|
|
public float CameraFollowMultiplier = 1;
|
|
|
|
public int X => (int)Math.Round(Location.X + ShakeOffsetX * Scale);
|
|
public int Y => (int)Math.Round(Location.Y + ShakeOffsetY * Scale);
|
|
|
|
private Vector2 _cameraDistance;
|
|
|
|
private int _viewportWidth;
|
|
private int _viewportHeight;
|
|
|
|
public void SetBounds(int viewportWidth, int viewportHeight)
|
|
{
|
|
_viewportWidth = viewportWidth;
|
|
_viewportHeight = viewportHeight;
|
|
}
|
|
|
|
public Rectangle GetCameraRectangle()
|
|
{
|
|
var rectangle = new Rectangle(
|
|
(int)RoundX - _viewportWidth / 2,
|
|
(int)RoundY - _viewportHeight / 2,
|
|
_viewportWidth, _viewportHeight);
|
|
|
|
return rectangle;
|
|
}
|
|
|
|
public Rectangle GetGameView()
|
|
{
|
|
var rectangle = new Rectangle(
|
|
(int)(RoundX / Scale) - (int)(_viewportWidth / 2 / Scale),
|
|
(int)(RoundY / Scale) - (int)(_viewportHeight / 2 / Scale),
|
|
(int)(_viewportWidth / Scale), (int)(_viewportHeight / Scale));
|
|
|
|
return rectangle;
|
|
}
|
|
|
|
public Rectangle GetGameViewBig()
|
|
{
|
|
var rectangle = new Rectangle(
|
|
(int)(RoundX / Scale) - Values.MinWidth,
|
|
(int)(RoundY / Scale) - Values.MinHeight,
|
|
Values.MinWidth * 2, Values.MinHeight * 2);
|
|
|
|
return rectangle;
|
|
}
|
|
|
|
public void Center(Vector2 position, bool moveX, bool moveY)
|
|
{
|
|
if (!GameSettings.SmoothCamera)
|
|
{
|
|
Location = position;
|
|
return;
|
|
}
|
|
|
|
var direction = position - MoveLocation;
|
|
|
|
if (direction != Vector2.Zero)
|
|
{
|
|
var distance = direction.Length() / Scale * CameraFollowMultiplier;
|
|
var speedMult = CameraFunction(distance / 12.5f);
|
|
|
|
direction.Normalize();
|
|
var cameraSpeed = direction * speedMult * Scale * Game1.TimeMultiplier;
|
|
|
|
if (moveX)
|
|
MoveLocation.X += cameraSpeed.X;
|
|
if (moveY)
|
|
MoveLocation.Y += cameraSpeed.Y;
|
|
|
|
if (distance <= 0.1f * Game1.TimeMultiplier)
|
|
MoveLocation = position;
|
|
}
|
|
|
|
// this is needed so the player does not wiggle around while the camera is following him
|
|
if (moveX)
|
|
_cameraDistance.X = position.X - MoveLocation.X;
|
|
if (moveY)
|
|
_cameraDistance.Y = position.Y - MoveLocation.Y;
|
|
|
|
Location = new Vector2((int)Math.Round(position.X), (int)Math.Round(position.Y)) - _cameraDistance;
|
|
}
|
|
|
|
private float CameraFunction(float x)
|
|
{
|
|
var y = MathF.Atan(x);
|
|
|
|
if (x > 2)
|
|
y += (x - 2) / 2;
|
|
|
|
return y + 0.1f;
|
|
}
|
|
|
|
public void ForceUpdate(Vector2 lockPosition)
|
|
{
|
|
MoveLocation = lockPosition;
|
|
Location = lockPosition;
|
|
}
|
|
|
|
public void SoftUpdate(Vector2 position)
|
|
{
|
|
MoveLocation = position - _cameraDistance;
|
|
Location = position;
|
|
}
|
|
|
|
public void OffsetCameraDistance(Vector2 offset)
|
|
{
|
|
_cameraDistance += offset;
|
|
}
|
|
|
|
public void Draw(SpriteBatch spriteBatch)
|
|
{
|
|
if (!Game1.DebugMode)
|
|
return;
|
|
|
|
var size = 10;
|
|
spriteBatch.Draw(Resources.SprWhite, new Rectangle(
|
|
Game1.WindowWidthEnd / 2 - (int)(size * Scale),
|
|
Game1.WindowHeightEnd / 2 - (int)(size * Scale),
|
|
(int)(size * Scale * 2),
|
|
(int)(size * Scale * 2)), Color.Pink * 0.25f);
|
|
}
|
|
}
|
|
}
|