/
Vagabond132
/
TerrariaCourse
Обзор
Документация
Войти
/
Vagabond132
/
TerrariaCourse
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
Windows
WpfView/Game/MapViewWpf.cs
235 строк
7 KB
Vagabond132
Комментарии добавлены
12 янв 2025, 15:06
12 янв 2025, 15:06
bb8abcd
Код
Авторство
О чём код?
using Model.Blocks.ImplementedBlocks; using Model.Blocks; using Model.GameComponents.Entities; using Model.GameComponents; using System.Windows.Controls; using System.Windows.Media.Imaging; using System.Windows.Media; using View.Game; using System.Windows.Shapes; using System.Windows; /// <summary> /// Представление карты для WPF /// </summary> public class MapViewWpf : MapView { /// <summary> /// Канвас /// </summary> private readonly Canvas _canvas; /// <summary> /// Размер блока /// </summary> public static readonly double _blockSize = 20; /// <summary> /// Высота окна /// </summary> private int _windowHeight; /// <summary> /// Ширина окна /// </summary> private int _windowWidth; /// <summary> /// Позиция екамеры Х /// </summary> private int _cameraX; /// <summary> /// Позиция камеры У /// </summary> private int _cameraY; /// <summary> /// Словарь кистей для блоков /// </summary> private readonly Dictionary<int, ImageBrush> _blockBrushes; /// <summary> /// Кисть для воздушных блоков /// </summary> private readonly Brush _airBrush = Brushes.DeepSkyBlue; /// <summary> /// Модель игрока /// </summary> private readonly PlayerModel _playerModel; /// <summary> /// Прямоугольники карты /// </summary> private readonly Rectangle[,] _blockRectangles; /// <summary> /// Фиксированное ли окно /// </summary> private bool _fixed; /// <summary> /// Позиция камеры Х /// </summary> public int CameraX { get => _cameraX; set => _cameraX = value; } /// <summary> /// Позиция камеры У /// </summary> public int CameraY { get => _cameraY; set => _cameraY = value; } /// <summary> /// Высота окна /// </summary> public int WindowHeight { get => _windowHeight; set => _windowHeight = value; } /// <summary> /// Ширина окна /// </summary> public int WindowWidth { get => _windowWidth; set => _windowWidth = value; } /// <summary> /// Фиксированное ли окно /// </summary> public bool Fixed { get => _fixed; set => _fixed = value; } /// <summary> /// Конструктор /// </summary> /// <param name="parMapModel">Модель карты</param> /// <param name="parPlayerModel">Модель игрока</param> /// <param name="parCanvas"></param> /// <param name="parWindowWidth">Ширина окна</param> /// <param name="parWindowHeight">Высота окна</param> public MapViewWpf(MapModel parMapModel, ref readonly PlayerModel parPlayerModel, Canvas parCanvas, int parWindowWidth, int parWindowHeight) : base(parMapModel) { Fixed = true; _canvas = parCanvas; _playerModel = parPlayerModel; WindowHeight = parWindowHeight; WindowWidth = parWindowWidth; // Предзагрузка текстур блоков _blockBrushes = new Dictionary<int, ImageBrush> { { BlockConstructor.getMudBlock().Sign, CreateBrush("../../../Assets/Dirt_Block.png") }, { BlockConstructor.getStoneBlock().Sign, CreateBrush("../../../Assets/Stone_Block.png") }, { BlockConstructor.getIronBlock().Sign, CreateBrush("../../../Assets/Iron_Block.png") }, { BlockConstructor.getDiamondBlock().Sign, CreateBrush("../../../Assets/Diamond_Block.png") }, { BlockConstructor.getGoldBlock().Sign, CreateBrush("../../../Assets/Gold_Block.png") } // Добавьте остальные типы блоков }; // Создание фиксированного набора прямоугольников int mapSizeXInBlocks = (int)(WindowWidth / _blockSize); int mapSizeYInBlocks = (int)(WindowHeight / _blockSize); _blockRectangles = new Rectangle[mapSizeYInBlocks, mapSizeXInBlocks]; for (int y = 0; y < mapSizeYInBlocks; y++) { for (int x = 0; x < mapSizeXInBlocks; x++) { var rect = new Rectangle { Width = _blockSize, Height = _blockSize, Fill = _airBrush // Изначально заполняем цветом воздуха }; Canvas.SetLeft(rect, x * _blockSize); Canvas.SetTop(rect, y * _blockSize); _blockRectangles[y, x] = rect; _canvas.Children.Add(rect); } } } /// <summary> /// Отрисовка карты /// </summary> public override void Draw() { int mapSizeXInBlocks = (int)Math.Ceiling(WindowWidth / _blockSize); int mapSizeYInBlocks = (int)Math.Ceiling(WindowHeight / _blockSize); // Центрируем камеру с учетом размеров блока и позиции игрока double playerX = _playerModel.Pos.X; double playerY = _playerModel.Pos.Y; CameraX = (int)Math.Max(0, playerX - (mapSizeXInBlocks / 2.0)); CameraY = (int)Math.Max(0, playerY - (mapSizeYInBlocks / 2.0)); if (playerX - (mapSizeXInBlocks / 2.0) <= 0 || playerY - (mapSizeYInBlocks / 2.0) <= 0 || Map.GetMap.GetLength(1) - mapSizeXInBlocks <= CameraX || Map.GetMap.GetLength(0) - mapSizeYInBlocks <= CameraY) { Fixed = false; } else { Fixed = true; } CameraX = Math.Min(CameraX, Map.GetMap.GetLength(1) - mapSizeXInBlocks); CameraY = Math.Min(CameraY, Map.GetMap.GetLength(0) - mapSizeYInBlocks+2); Application.Current.Dispatcher.Invoke(() => { for (int y = 0; y < mapSizeYInBlocks; y++) { for (int x = 0; x < mapSizeXInBlocks; x++) { int mapX = CameraX + x; int mapY = CameraY + y; var rect = _blockRectangles[y, x]; if (mapY < Map.GetMap.GetLength(0) && mapX < Map.GetMap.GetLength(1)) { var block = Map.GetMap[mapY, mapX]; rect.Fill = block != null ? GetBlockBrush(block) : _airBrush; } else { rect.Fill = _airBrush; // Пустое пространство за пределами карты } Canvas.SetLeft(rect, x * _blockSize); Canvas.SetTop(rect, y * _blockSize); } } }); } /// <summary> /// Получить кисть для блока /// </summary> /// <param name="parBlock"> блок для получения кисти</param> /// <returns></returns> private Brush GetBlockBrush(AbstractBlock parBlock) { if (parBlock.Name == BlockConstructor.getAirBlock().Name) { return _airBrush; } if (_blockBrushes.TryGetValue(parBlock.Sign, out var brush)) { return brush; } return _airBrush; } /// <summary> /// Создание кисти для карты /// </summary> /// <param name="parPath">путь до изображения</param> /// <returns></returns> private static ImageBrush CreateBrush(string parPath) { var image = new BitmapImage(new Uri(parPath, UriKind.Relative)); return new ImageBrush(image); } /// <summary> /// Перерисовка /// </summary> /// <exception cref="NotImplementedException"></exception> public override void Redraw() { Draw(); } }