THUAI8/interface/AvaloniaUI_debug_interface/debug_interface/Views/MapView.axaml.cs

396 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// MapView.axaml.cs - Fixed version
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Shapes;
using Avalonia.Media;
using Avalonia.VisualTree;
using debug_interface.Controls;
using debug_interface.Models;
using debug_interface.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace debug_interface.Views
{
public partial class MapView : UserControl
{
private Canvas? characterCanvas;
private Grid? mapGrid;
private Dictionary<string, Control> characterElements = new Dictionary<string, Control>();
private MainWindowViewModel? viewModel;
public MapView()
{
InitializeComponent();
this.AttachedToVisualTree += MapView_AttachedToVisualTree;
this.DataContextChanged += MapView_DataContextChanged;
}
private void MapView_DataContextChanged(object? sender, EventArgs e)
{
var mainWindow = this.FindAncestorOfType<MainWindow>();
if (mainWindow != null && mainWindow.DataContext is MainWindowViewModel vm)
{
SetupViewModel(vm);
}
}
private void MapView_AttachedToVisualTree(object? sender, VisualTreeAttachmentEventArgs e)
{
characterCanvas = this.FindControl<Canvas>("CharacterCanvas");
mapGrid = this.FindControl<Grid>("MapGrid"); // ÐÞ¸ÄÕâÀ¶ÔÓ¦XAML
var mainWindow = this.FindAncestorOfType<MainWindow>();
if (mainWindow != null && mainWindow.DataContext is MainWindowViewModel vm)
{
SetupViewModel(vm);
}
}
private void SetupViewModel(MainWindowViewModel vm)
{
if (viewModel != null)
{
viewModel.RedTeamCharacters.CollectionChanged -= RedTeamCharacters_CollectionChanged;
viewModel.BlueTeamCharacters.CollectionChanged -= BlueTeamCharacters_CollectionChanged;
}
viewModel = vm;
// ³õʼ»¯µØÍ¼Íø¸ñ
if (mapGrid != null && viewModel.MapVM != null)
{
// Ö±½ÓʹÓÃÏÖÓеÄmapGrid
MapHelper.InitializeMapGrid(mapGrid, viewModel.MapVM);
}
// ¼àÌý½ÇÉ«¼¯ºÏ±ä»¯
viewModel.RedTeamCharacters.CollectionChanged += RedTeamCharacters_CollectionChanged;
viewModel.BlueTeamCharacters.CollectionChanged += BlueTeamCharacters_CollectionChanged;
// ³õʼ»¯½ÇÉ«
RefreshCharacters();
InitializeRandomPositions();
// ¼àÌýµØÍ¼µ¥Ôª¸ñ±ä»¯£¨Èç¹ûÄ£ÐÍÌṩÁËÕâÖÖÄÜÁ¦£©
if (viewModel.MapVM != null)
{
// Èç¹ûMapCellÀàÐÍʵÏÖÁËINotifyPropertyChanged£¬Äú¿ÉÒÔÔÚÕâÀï¼àÌýÊôÐԱ仯
foreach (var cell in viewModel.MapVM.MapCells)
{
cell.PropertyChanged += (s, e) => {
if (s is MapCell mapCell)
{
if (e.PropertyName == nameof(MapCell.DisplayColor))
{
MapHelper.UpdateCellColor(mapCell.CellX, mapCell.CellY, mapCell.DisplayColor);
}
else if (e.PropertyName == nameof(MapCell.DisplayText))
{
MapHelper.UpdateCellText(mapCell.CellX, mapCell.CellY, mapCell.DisplayText);
}
}
};
}
}
}
private void RefreshCharacters()
{
if (characterCanvas == null || viewModel == null) return;
characterCanvas.Children.Clear();
characterElements.Clear();
InitializeCharacters(viewModel.RedTeamCharacters, Colors.Red);
InitializeCharacters(viewModel.BlueTeamCharacters, Colors.Blue);
}
private void InitializeRandomPositions()
{
if (viewModel == null) return;
Random rnd = new Random();
foreach (var character in viewModel.RedTeamCharacters)
{
// Only set position if it's still at default (0,0)
if (character.PosX == 0 && character.PosY == 0)
{
character.PosX = rnd.Next(1, 49);
character.PosY = rnd.Next(1, 49);
}
}
foreach (var character in viewModel.BlueTeamCharacters)
{
// Only set position if it's still at default (0,0)
if (character.PosX == 0 && character.PosY == 0)
{
character.PosX = rnd.Next(1, 49);
character.PosY = rnd.Next(1, 49);
}
}
}
private void InitializeCharacters<T>(System.Collections.ObjectModel.ObservableCollection<T> characters, Color color) where T : CharacterViewModel
{
if (characterCanvas == null) return;
//bool isRedTeam = color.Equals(Colors.Red);
//// ÐÎ×´Ñ¡Ôñ - ºì¶ÓʹÓÃÔ²ÐΣ¬À¶¶ÓʹÓÃÕý·½ÐÎ
//for (int i = 0; i < characters.Count; i++)
//{
// var character = characters[i];
// // ´´½¨ÈÝÆ÷ - ÓÃÓÚ¶¨Î»
// var container = new Canvas
// {
// Width = 16,
// Height = 16,
// Tag = character
// };
// Control characterShape;
// if (isRedTeam)
// {
// // ºì¶ÓʹÓÃÔ²ÐÎ
// characterShape = new Ellipse
// {
// Width = 14,
// Height = 14,
// Fill = new SolidColorBrush(color) { Opacity = 0.7 },
// Stroke = Brushes.White,
// StrokeThickness = 1
// };
// }
// else
// {
// // À¶¶ÓʹÓÃÕý·½ÐÎ
// characterShape = new Rectangle
// {
// Width = 14,
// Height = 14,
// Fill = new SolidColorBrush(color) { Opacity = 0.7 },
// Stroke = Brushes.White,
// StrokeThickness = 1
// };
// }
// // Ìí¼ÓÐÎ×´µ½ÈÝÆ÷
// Canvas.SetLeft(characterShape, 1);
// Canvas.SetTop(characterShape, 1);
// container.Children.Add(characterShape);
// // Ìí¼Ó±êʶ·û - ʹÓò»Í¬µÄ·½Ê½±êʶ¶ÓÎéÄÚ²¿µÄ½ÇÉ«
// var identifier = new TextBlock
// {
// Text = (i + 1).ToString(),
// FontSize = 8,
// Foreground = Brushes.White,
// HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center,
// VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
// };
// // Ϊ±êʶ·ûÌí¼Ó±³¾°ÒÔÔöÇ¿¿É¶ÁÐÔ
// var textContainer = new Border
// {
// Child = identifier,
// Width = 14,
// Height = 14,
// Background = Brushes.Transparent,
// HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center,
// VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center
// };
// Canvas.SetLeft(textContainer, 1);
// Canvas.SetTop(textContainer, 1);
// container.Children.Add(textContainer);
// // Ìí¼Ó¹¤¾ßÌáʾ£¬ÏÔʾÏêϸÐÅÏ¢
// var tooltip = new ToolTip
// {
// // ʹÓýÇÉ«µÄ·ºÐÍÊôÐÔ£¬È·±£¿ÉÒÔ·ÃÎÊ
// Content = new TextBlock { Text = $"{(isRedTeam ? "ºì¶Ó" : "À¶¶Ó")} ½ÇÉ« {i + 1}" }
// };
// ToolTip.SetTip(container, tooltip);
// // ½«ÈÝÆ÷Ìí¼Óµ½»­²¼
// characterCanvas.Children.Add(container);
// characterElements[character.Name] = container;
// // ³õʼ¶¨Î» - ÉÔºó»á¸üÐÂ
// Canvas.SetLeft(container, i*i * i*i);
// Canvas.SetTop(container, i*i * i * i );
//}
/////////////////////////////////////
/////////////////////////////////////
////////////////////////////////////
for (int i = 0; i < characters.Count; i++)
{
{
var character = characters[i];
var id = color == Colors.Red ? $"red_{i}" : $"blue_{i}";
// ´´½¨Ò»¸öGrid×÷ΪÈÝÆ÷£¬°üº¬±ß¿òºÍÎı¾/ͼ±ê
var grid = new Grid
{
Width = 15,
Height = 15,
};
// ´´½¨´øÑÕÉ«±ß¿òµÄÔ²ÐÎ
var borderellipse = new Ellipse
{
Width = 15,
Height = 15,
Fill = new SolidColorBrush(Colors.White), // °×É«±³¾°
Stroke = new SolidColorBrush(color), // ¶ÓÎéÑÕÉ«±ß¿ò
StrokeThickness = 2,
Tag = character.Name,
};
grid.Children.Add(borderellipse);
// ===== Ñ¡Ïî1: ÏÔʾÊý×Ö±àºÅ =====
// Èç¹û²»ÐèÒªÊý×Ö±àºÅ£¬×¢Ê͵ôÏÂÃæÕâ¶Î´úÂë
var textBlock = new TextBlock
{
Text = (i + 1).ToString(), // ʹÓñàºÅ(´Ó1¿ªÊ¼)
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center,
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
FontSize = 8,
Foreground = new SolidColorBrush(color), // Îı¾ÑÕÉ«Óë¶ÓÎéÑÕɫһÖÂ
FontWeight = FontWeight.Bold,
};
//grid.Children.Add(textBlock);
// ÉèÖÃÌáʾÐÅÏ¢
ToolTip.SetTip(grid, character.Name);
// ÉèÖóõʼλÖÃ
Canvas.SetLeft(grid, character.PosY * 15);
Canvas.SetTop(grid, character.PosX * 15);
characterCanvas.Children.Add(grid);
// ´æ´¢Gridµ½×ÖµäÖÐ
characterElements[id] = grid;
// ÉèÖÃÊôÐÔ¸ü¸Ä´¦ÀíÆ÷
character.PropertyChanged += (s, e) =>
{
if (e.PropertyName == nameof(CharacterViewModel.PosX) || e.PropertyName == nameof(CharacterViewModel.PosY))
{
// ¸üÐÂGridµÄλÖÃ
UpdateCharacterPosition(grid, character.PosX, character.PosY);
}
};
}
}
}
// ÐÞ¸ÄλÖøüз½·¨£¬½ÓÊÜÈκÎUIElement
private void UpdateCharacterPosition(Control element, int x, int y)
{
// ת»»Íø¸ñλÖÃΪÏñËØ
Canvas.SetLeft(element, y * 15);
Canvas.SetTop(element, x * 15);
}
private void RedTeamCharacters_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
// When collection changes, refresh all characters for simplicity
RefreshCharacters();
}
private void BlueTeamCharacters_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
// When collection changes, refresh all characters for simplicity
RefreshCharacters();
}
public void UpdateCharacterPosition(long characterId, int x, int y, bool isRedTeam, string name)
{
// ²éÕÒÏÖÓнÇÉ«±ê¼Ç»ò´´½¨Ð±ê¼Ç
var marker = FindCharacterMarker(characterId);
if (marker == null)
{
// ´´½¨Ð½ÇÉ«±ê¼Ç
marker = new Ellipse
{
Width = 10,
Height = 10,
Fill = new SolidColorBrush(isRedTeam ? Colors.Red : Colors.Blue),
Tag = characterId
};
// Ìí¼ÓÎı¾±êÇ©
var label1 = new TextBlock
{
Text = name,
FontSize = 8,
Foreground = new SolidColorBrush(Colors.White)
};
// Ìí¼Óµ½»­²¼
CharacterCanvas.Children.Add(marker);
CharacterCanvas.Children.Add(label1);
}
// ¸üÐÂλÖÃ
double cellWidth = CharacterCanvas.Bounds.Width / 50;
double cellHeight = CharacterCanvas.Bounds.Height / 50;
Canvas.SetLeft(marker, y * cellWidth + cellWidth / 2 - marker.Width / 2);
Canvas.SetTop(marker, x * cellHeight + cellHeight / 2 - marker.Height / 2);
// ¸üбêǩλÖÃ
var label = FindCharacterLabel(characterId);
if (label != null)
{
Canvas.SetLeft(label, y * cellWidth + cellWidth / 2 - label.Bounds.Width / 2);
Canvas.SetTop(label, x * cellHeight + cellHeight / 2 + marker.Height);
}
}
private Ellipse FindCharacterMarker(long characterId)
{
foreach (var child in CharacterCanvas.Children)
{
if (child is Ellipse ellipse && (long?)ellipse.Tag == characterId)
{
return ellipse;
}
}
return null;
}
private TextBlock FindCharacterLabel(long characterId)
{
var marker = FindCharacterMarker(characterId);
if (marker == null) return null;
int index = CharacterCanvas.Children.IndexOf(marker);
if (index >= 0 && index + 1 < CharacterCanvas.Children.Count &&
CharacterCanvas.Children[index + 1] is TextBlock label)
{
return label;
}
return null;
}
}
}