/
karachi
/
KPO_CP_CrossyRoad
Обзор
Документация
Войти
/
karachi
/
KPO_CP_CrossyRoad
Код
Запросы
5
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
base
View/Game/Camera.cs
231 строка
8 KB
karachi-23
base
10 янв 2025, 23:55
10 янв 2025, 23:55
f5bd4ec
Код
Авторство
О чём код?
using Model.Game; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Text; using System.Threading.Tasks; using static Model.MathModel.MathFunc; namespace View.Game { /// <summary> /// Класс, отвечающий за отображаемую на экране область игры /// </summary> public abstract class Camera { /// <summary> /// Ширина отображаемой области игрового поля /// </summary> private float _cameraWidth; /// <summary> /// Высота отображаемой области игрового поля /// </summary> private float _cameraHeight; /// <summary> /// Ширина экрана /// </summary> private float _screenWidth; /// <summary> /// Высота экрана /// </summary> private float _screenHeight; /// <summary> /// Соотношение ширины экрана к его высоте /// </summary> private float _screenWidthToHeightRatio = 1; /// <summary> /// Смещение левого верхнего угла камеры относительно левого верхнего угла игрового поля по X-координате /// </summary> public float CameraOffsetX { get; protected set; } /// <summary> /// Смещение левого верхнего угла камеры относительно левого верхнего угла игрового поля по Y-координате /// </summary> public float CameraOffsetY { get; protected set; } /// <summary> /// Ширина отображаемой области игрового поля /// </summary> public float CameraWidth { get => _cameraWidth; protected set { _cameraWidth = value; _cameraHeight = _cameraWidth / ScreenWidthToHeightRatio; CameraToScreenScaleFactor = _cameraWidth / _screenWidth; } } /// <summary> /// Высота отображаемой области игрового поля /// </summary> public float CameraHeight { get => _cameraHeight; protected set { _cameraHeight = value; _cameraWidth = _cameraHeight * ScreenWidthToHeightRatio; CameraToScreenScaleFactor = _cameraWidth / _screenWidth; } } /// <summary> /// Коэффициент масштаба между одной из сторон камеры и соответствующей стороной экрана /// </summary> public float CameraToScreenScaleFactor { get; protected set; } /// <summary> /// Соотношение ширины экрана к его высоте /// </summary> protected float ScreenWidthToHeightRatio { get => _screenWidthToHeightRatio; set { float oldValue = _screenWidthToHeightRatio; _screenWidthToHeightRatio = value; /* автоматическое вычисление новых размеров области просмотра * так, чтобы зона видимости не уменьшалась*/ if (value > oldValue) CameraHeight = _cameraHeight; else CameraWidth = _cameraWidth; } } /// <summary> /// Ширина экрана /// </summary> public float ScreenWidth { get => _screenWidth; set { _screenWidth = value; } } /// <summary> /// Высота экрана /// </summary> public float ScreenHeight { get => _screenHeight; set { _screenHeight = value; } } /// <summary> /// Экземпляр игры /// </summary> protected CrossyRoadGame GameInstance { get; private set; } /// <summary> /// Игровое поле /// </summary> protected Map Map { get; private set; } /// <summary> /// Игрок, за которым следит камера /// </summary> protected Player? TrackedPlayer { get; set; } /// <summary> /// Инициализация камеры /// </summary> /// <param name="parGame">Экземпляр игры</param> public Camera(CrossyRoadGame parGame) { GameInstance = parGame; Map = parGame.Map; } /// <summary> /// Обновляет соотношение сторон экрана /// </summary> public void UpdateScreenWidthToHeightRatio() { ScreenWidthToHeightRatio = ScreenWidth / ScreenHeight; } /// <summary> /// Центрирует камеру на игроке, за которым она должна следить /// </summary> protected void CenterOnTrackedPlayer() { if (TrackedPlayer is null) return; Player player = TrackedPlayer; //CameraOffsetX = car.Position.X - CameraWidth / 2; CameraOffsetX = (Map.Width - CameraWidth) / 2; CameraOffsetY = player.Position.Y - CameraHeight + Map.Player.Length / 2; //CameraOffsetX = car.Position.X - CameraWidth / 2; //CameraOffsetY = (Map.Height - CameraHeight) / 2; } /// <summary> /// Обновление камеры /// </summary> public abstract void Update(); /// <summary> /// Получение прямоугольника, соответствующего области просмотра камеры /// </summary> /// <returns></returns> public Rectangle GetCameraRectangle() { return new() { X1 = CameraOffsetX, Y1 = CameraOffsetY, X2 = CameraOffsetX + CameraWidth, Y2 = CameraOffsetY + CameraHeight }; } /// <summary> /// Получение машин, которая попала в область просмотра камеры /// </summary> /// <returns>Машины, которые попали в область просмотра камеры</returns> public List<Car> GetCarsInViewport() { List<Car> carsInViewport = new(); Rectangle cameraRectangle = GetCameraRectangle(); foreach (Car elCar in Map.Cars) if (cameraRectangle.IsIntersect(elCar)) carsInViewport.Add(elCar); return carsInViewport; } /// <summary> /// Вычисление длины линии, чтобы отобразить её на экране в соответствии /// с текущими настройками камеры и параметрами экрана /// </summary> /// <param name="parLineLengthReal">Реальная длина линии</param> /// <returns>Длина линии в пикселях</returns> public float CalculateLineLengthInScreen(float parLineLengthReal) { return parLineLengthReal / CameraToScreenScaleFactor; } /// <summary> /// Вычисление положения точки на экране в соответствии с текущими настройками камеры /// и параметрами экрана /// </summary> /// <param name="parPoint">Точка в системе координат игрового поля</param> /// <returns>Координаты экрана, где должна быть нарисована эта точка</returns> public Vector2 CalculatePointPositionInScreen(Vector2 parPoint) { Vector2 result = new(parPoint.X - CameraOffsetX, parPoint.Y - CameraOffsetY); result.X /= CameraToScreenScaleFactor; result.Y /= CameraToScreenScaleFactor; return result; } } }