fff
This commit is contained in:
parent
0e8c41fb61
commit
ec46f3799c
@ -2,6 +2,8 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.Views"
|
||||
xmlns:conv="clr-namespace:Wpf_AiSportsMicrospace.Converter"
|
||||
|
||||
StartupUri="Views/Main.xaml">
|
||||
|
||||
<!--StartupUri="Views/JumpRope/GroupJumpRope.xaml">-->
|
||||
@ -10,6 +12,8 @@
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="./Resoures/Fonts/myFontFamily"/>
|
||||
</Style>
|
||||
<conv:DotColorConverter x:Key="DotColorConverter"/>
|
||||
<!--<conv:SpacingConverter x:Key="SpacingConverter"/>-->
|
||||
</Application.Resources>
|
||||
|
||||
</Application>
|
||||
|
||||
24
Wpf_AiSportsMicrospace/Converter/DotColorConverter.cs
Normal file
24
Wpf_AiSportsMicrospace/Converter/DotColorConverter.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using Wpf_AiSportsMicrospace.MyUserControl;
|
||||
|
||||
namespace Wpf_AiSportsMicrospace.Converter
|
||||
{
|
||||
public class DotColorConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is bool b && b)
|
||||
return Brushes.Red;
|
||||
return Brushes.Green;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
=> throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
29
Wpf_AiSportsMicrospace/MyUserControl/BeatScrollDots.xaml
Normal file
29
Wpf_AiSportsMicrospace/MyUserControl/BeatScrollDots.xaml
Normal file
@ -0,0 +1,29 @@
|
||||
<UserControl x:Class="Wpf_AiSportsMicrospace.MyUserControl.BeatScrollDots"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.Converter"
|
||||
mc:Ignorable="d"
|
||||
Height="100" Width="400">
|
||||
<UserControl.Resources>
|
||||
<local:DotColorConverter x:Key="DotColorConverter"/>
|
||||
</UserControl.Resources>
|
||||
|
||||
<ScrollViewer x:Name="scrollViewer" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled" Opacity="0.5">
|
||||
<ItemsControl ItemsSource="{Binding Dots, ElementName=root}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Ellipse Width="20" Height="20"
|
||||
Margin="{Binding ElementName=root, Path=DotSpacing}"
|
||||
Fill="{Binding IsSelected, Converter={StaticResource DotColorConverter}}"/>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
136
Wpf_AiSportsMicrospace/MyUserControl/BeatScrollDots.xaml.cs
Normal file
136
Wpf_AiSportsMicrospace/MyUserControl/BeatScrollDots.xaml.cs
Normal file
@ -0,0 +1,136 @@
|
||||
using Emgu.CV.Flann;
|
||||
using HandyControl.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
{
|
||||
public partial class BeatScrollDots : UserControl
|
||||
{
|
||||
public ObservableCollection<DotItem> Dots { get; set; } = new ObservableCollection<DotItem>();
|
||||
|
||||
public BeatScrollDots()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
public int DotCount
|
||||
{
|
||||
get => (int)GetValue(DotCountProperty);
|
||||
set => SetValue(DotCountProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DotCountProperty =
|
||||
DependencyProperty.Register(nameof(DotCount), typeof(int), typeof(BeatScrollDots),
|
||||
new PropertyMetadata(0, OnDotCountChanged));
|
||||
|
||||
private static void OnDotCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is BeatScrollDots ctrl)
|
||||
ctrl.GenerateDots();
|
||||
}
|
||||
|
||||
private void GenerateDots()
|
||||
{
|
||||
Dots.Clear();
|
||||
for (int i = 0; i < DotCount; i++)
|
||||
Dots.Add(new DotItem { IsSelected = false });
|
||||
}
|
||||
|
||||
public void SetSelected(int index, bool selected)
|
||||
{
|
||||
if (index >= 0 && index < Dots.Count)
|
||||
Dots[index].IsSelected = selected;
|
||||
}
|
||||
|
||||
public Thickness DotSpacing
|
||||
{
|
||||
get => (Thickness)GetValue(DotSpacingProperty);
|
||||
set => SetValue(DotSpacingProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty DotSpacingProperty =
|
||||
DependencyProperty.Register(nameof(DotSpacing), typeof(Thickness), typeof(BeatScrollDots), new PropertyMetadata(new Thickness(5, 0, 5, 0)));
|
||||
|
||||
public void ScrollToDotCenter(int index, bool mirror = false)
|
||||
{
|
||||
if (scrollViewer == null || Dots.Count == 0) return;
|
||||
|
||||
double step = 20 + DotSpacing.Left + DotSpacing.Right;
|
||||
double totalWidth = Dots.Count * step;
|
||||
double dotCenter = index * step + step / 2;
|
||||
|
||||
double targetOffset = !mirror
|
||||
? dotCenter - scrollViewer.ActualWidth / 2
|
||||
: totalWidth - dotCenter - scrollViewer.ActualWidth / 2;
|
||||
|
||||
targetOffset = System.Math.Max(0, System.Math.Min(targetOffset, scrollViewer.ScrollableWidth));
|
||||
scrollViewer.ScrollToHorizontalOffset(targetOffset);
|
||||
}
|
||||
|
||||
public void UpdateSpacingForCount(int count)
|
||||
{
|
||||
if (count <= 0) count = 1;
|
||||
double spacing = (ActualWidth / count) - 20;
|
||||
if (spacing < 2) spacing = 2;
|
||||
DotSpacing = new Thickness(spacing / 2, 0, spacing / 2, 0);
|
||||
}
|
||||
public Dictionary<int, List<double>> MusicBeatsDic
|
||||
{
|
||||
get => (Dictionary<int, List<double>>)GetValue(MusicBeatsDicProperty);
|
||||
set => SetValue(MusicBeatsDicProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MusicBeatsDicProperty =
|
||||
DependencyProperty.Register(nameof(MusicBeatsDic), typeof(Dictionary<int, List<double>>), typeof(BeatScrollDots),
|
||||
new PropertyMetadata(null, OnMusicBeatsDicChanged));
|
||||
|
||||
private static void OnMusicBeatsDicChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is BeatScrollDots ctrl)
|
||||
{
|
||||
// 可选:根据第一个 key 初始化 DotCount
|
||||
if (ctrl.MusicBeatsDic != null && ctrl.MusicBeatsDic.Any())
|
||||
{
|
||||
int firstKey = ctrl.MusicBeatsDic.Keys.Min();
|
||||
ctrl.DotCount = ctrl.MusicBeatsDic[firstKey].Count;
|
||||
ctrl.UpdateSpacingForCount(ctrl.DotCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DotItem : INotifyPropertyChanged
|
||||
{
|
||||
private bool _isSelected;
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
set
|
||||
{
|
||||
if (_isSelected != value)
|
||||
{
|
||||
_isSelected = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
}
|
||||
}
|
||||
@ -35,28 +35,18 @@
|
||||
TextAlignment="Center"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid x:Name="BottomBeatPanel" VerticalAlignment="Bottom" Height="200" Panel.ZIndex="100">
|
||||
<Grid x:Name="BottomBeatPanel" VerticalAlignment="Bottom" Height="200">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="600"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 左边滚动条 -->
|
||||
<ScrollViewer x:Name="BeatScrollLeft" Width="660" Height="80"
|
||||
HorizontalScrollBarVisibility="Hidden"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
Grid.Column="0">
|
||||
<Canvas x:Name="beatCanvasLeft" Height="100"/>
|
||||
</ScrollViewer>
|
||||
<!-- 左控件 -->
|
||||
<local:BeatScrollDots x:Name="LeftBeats" Grid.Column="0" Background="Gray"/>
|
||||
|
||||
<!-- 右边滚动条 -->
|
||||
<ScrollViewer x:Name="BeatScrollRight" Width="660" Height="80"
|
||||
HorizontalScrollBarVisibility="Hidden"
|
||||
VerticalScrollBarVisibility="Disabled"
|
||||
Grid.Column="2">
|
||||
<Canvas x:Name="beatCanvasRight" Height="100"/>
|
||||
</ScrollViewer>
|
||||
<!-- 右控件 -->
|
||||
<local:BeatScrollDots x:Name="RightBeats" Grid.Column="2" Background="Gray"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@ -6,6 +6,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
@ -37,7 +38,7 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||
private readonly object _updateLock = new object();
|
||||
private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>();
|
||||
private MusicJumpRopeContext _musicJumpRopeContext;
|
||||
|
||||
public Dictionary<int, List<double>> _musicBeatsDic;
|
||||
private GameState _currentGameState = GameState.NotStarted;
|
||||
|
||||
List<RankItem> RankingItemList = new();
|
||||
@ -70,7 +71,7 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||
|
||||
// 容忍时间(节拍误差)
|
||||
public double _beatTolerance = 0.15; // ±150ms
|
||||
|
||||
private int _totalDots = 0;
|
||||
// 滚动显示的节拍点集合
|
||||
public ObservableCollection<BeatItem> BeatDisplayLeft { get; set; } = new();
|
||||
public ObservableCollection<BeatItem> BeatDisplayRight { get; set; } = new();
|
||||
@ -81,9 +82,17 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||
Loaded += UserControl_Loaded;
|
||||
Unloaded += UserControl_Unloaded;
|
||||
_musicJumpRopeContext = new MusicJumpRopeContext();
|
||||
_musicBeatsDic = _musicJumpRopeContext.MusicBeatsDic;
|
||||
|
||||
// 初始化节拍点数据
|
||||
InitBeatDots();
|
||||
_totalDots = _musicJumpRopeContext.MusicBeats["1"].Count();
|
||||
|
||||
// 左控件
|
||||
LeftBeats.DotCount = _totalDots;
|
||||
LeftBeats.MusicBeatsDic = _musicBeatsDic;
|
||||
|
||||
// 右控件
|
||||
RightBeats.DotCount = _totalDots;
|
||||
RightBeats.MusicBeatsDic = _musicBeatsDic;
|
||||
}
|
||||
|
||||
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
|
||||
@ -234,11 +243,10 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||
private DateTime _lastUpdateTime = DateTime.Now;
|
||||
private void StartCountdown(int start = 3)
|
||||
{
|
||||
_mainWin.ShowCountDownAnimation();
|
||||
//_currentCountdown = start;
|
||||
//countdownText.Text = _currentCountdown.ToString();
|
||||
//countdownGrid.Visibility = Visibility.Visible;
|
||||
//_lastUpdateTime = DateTime.Now;
|
||||
_currentCountdown = start;
|
||||
countdownText.Text = _currentCountdown.ToString();
|
||||
countdownGrid.Visibility = Visibility.Visible;
|
||||
_lastUpdateTime = DateTime.Now;
|
||||
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
|
||||
}
|
||||
|
||||
@ -492,30 +500,29 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||
userItem.ImageState = "2";
|
||||
|
||||
var currentTime = Utils.GetMusicCurrentTime();
|
||||
var beats = _musicJumpRopeContext.MusicBeats["1"];
|
||||
int currentSecond = (int)Math.Floor(currentTime);
|
||||
|
||||
for (int j = 0; j < beats.Count; j++)
|
||||
{
|
||||
int indexCopy2 = j; // 复制一份当前循环索引
|
||||
if (Math.Abs(beats[indexCopy2] - currentTime) <= _beatTolerance)
|
||||
// 判断是否命中节拍
|
||||
var beats = _musicJumpRopeContext.MusicBeats["1"];
|
||||
bool hit = beats.Any(b => Math.Abs(b - currentTime) <= _beatTolerance);
|
||||
if (hit)
|
||||
{
|
||||
_musicJumpRopeContext.UserBeatSyncList[indexCopy]++;
|
||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
if (indexCopy == 0)
|
||||
{
|
||||
((Ellipse)beatCanvasLeft.Children[indexCopy2]).Fill = Brushes.Red;
|
||||
}
|
||||
else
|
||||
{
|
||||
((Ellipse)beatCanvasRight.Children[indexCopy2]).Fill = Brushes.Red;
|
||||
}
|
||||
_musicBeatTextBlock[indexCopy].Text = $"卡点 x{_musicJumpRopeContext.UserBeatSyncList[indexCopy]}";
|
||||
});
|
||||
|
||||
if (indexCopy == 0)
|
||||
LeftBeats.SetSelected(currentSecond, true);
|
||||
else
|
||||
RightBeats.SetSelected(currentSecond, true);
|
||||
|
||||
//Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
//{
|
||||
// if (indexCopy == 0)
|
||||
// LeftBeats.SetSelected(currentSecond, true);
|
||||
// else
|
||||
// RightBeats.SetSelected(currentSecond, true);
|
||||
//});
|
||||
}
|
||||
}
|
||||
// 滚动条跳跃到当前点附近
|
||||
UpdateBeatScrollSudden(currentTime);
|
||||
};
|
||||
|
||||
sport.Start();
|
||||
@ -523,30 +530,6 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBeatScrollSudden(double currentTime)
|
||||
{
|
||||
int maxVisible = 5; // 最多显示 5 个点
|
||||
var beats = _musicJumpRopeContext.MusicBeats["1"];
|
||||
|
||||
// 找到最近的点索引
|
||||
int currentIndex = beats.FindIndex(bt => bt >= currentTime);
|
||||
if (currentIndex == -1) currentIndex = beats.Count - 1;
|
||||
|
||||
// 取前后最多 5 个点
|
||||
int startIndex = Math.Max(0, currentIndex - maxVisible / 2);
|
||||
int endIndex = Math.Min(beats.Count - 1, startIndex + maxVisible - 1);
|
||||
|
||||
// 左侧 ScrollViewer
|
||||
double leftCenterX = BeatDisplayLeft[currentIndex].X - BeatScrollLeft.ViewportWidth / 2;
|
||||
leftCenterX = Math.Max(0, Math.Min(leftCenterX, beatCanvasLeft.Width - BeatScrollLeft.ViewportWidth));
|
||||
BeatScrollLeft.ScrollToHorizontalOffset(leftCenterX);
|
||||
|
||||
// 右侧 ScrollViewer
|
||||
double rightCenterX = BeatDisplayRight[currentIndex].X - BeatScrollRight.ViewportWidth / 2;
|
||||
rightCenterX = Math.Max(0, Math.Min(rightCenterX, beatCanvasRight.Width - BeatScrollRight.ViewportWidth));
|
||||
BeatScrollRight.ScrollToHorizontalOffset(rightCenterX);
|
||||
}
|
||||
|
||||
private void UpdateCircleCounts(List<Human> humans)
|
||||
{
|
||||
double radiusNormX = 0.07;
|
||||
@ -673,82 +656,37 @@ namespace Wpf_AiSportsMicrospace.Views.JumpRope
|
||||
|
||||
return userItem;
|
||||
}
|
||||
private List<TextBlock> leftDots = new();
|
||||
private List<TextBlock> rightDots = new();
|
||||
public double BeatPanelWidth { get; set; }
|
||||
private void InitBeatDots()
|
||||
{
|
||||
BeatDisplayLeft.Clear();
|
||||
BeatDisplayRight.Clear();
|
||||
beatCanvasLeft.Children.Clear();
|
||||
beatCanvasRight.Children.Clear();
|
||||
|
||||
var beats = _musicJumpRopeContext.MusicBeats["1"];
|
||||
double lastX = 0;
|
||||
double scale = 300; // 间隔放大系数,可调
|
||||
for (int i = 0; i < beats.Count; i++)
|
||||
{
|
||||
double interval = i == 0 ? beats[0] : beats[i] - beats[i - 1];
|
||||
lastX += interval * scale;
|
||||
}
|
||||
double totalWidth = lastX + 50;
|
||||
|
||||
// 左侧点
|
||||
lastX = 0;
|
||||
for (int i = 0; i < beats.Count; i++)
|
||||
{
|
||||
double interval = i == 0 ? beats[0] : beats[i] - beats[i - 1];
|
||||
double xPos = lastX + interval * scale;
|
||||
lastX = xPos;
|
||||
|
||||
var leftItem = new BeatItem { X = xPos, Color = Brushes.Black };
|
||||
BeatDisplayLeft.Add(leftItem);
|
||||
|
||||
var leftEllipse = new Ellipse { Width = 8, Height = 8, Fill = leftItem.Color };
|
||||
Canvas.SetLeft(leftEllipse, leftItem.X);
|
||||
Canvas.SetTop(leftEllipse, 40);
|
||||
beatCanvasLeft.Children.Add(leftEllipse);
|
||||
}
|
||||
beatCanvasLeft.Width = totalWidth;
|
||||
|
||||
// 右侧点(倒序排列,但间隔顺序保持一致)
|
||||
lastX = 0;
|
||||
for (int i = 0; i < beats.Count; i++)
|
||||
{
|
||||
double interval = i == 0 ? beats[0] : beats[i] - beats[i - 1];
|
||||
double xPos = lastX + interval * scale;
|
||||
lastX = xPos;
|
||||
|
||||
// 倒序显示
|
||||
double rightX = totalWidth - xPos;
|
||||
var rightItem = new BeatItem { X = rightX, Color = Brushes.Black };
|
||||
BeatDisplayRight.Add(rightItem);
|
||||
|
||||
var rightEllipse = new Ellipse { Width = 8, Height = 8, Fill = rightItem.Color };
|
||||
Canvas.SetLeft(rightEllipse, rightItem.X);
|
||||
Canvas.SetTop(rightEllipse, 40);
|
||||
beatCanvasRight.Children.Add(rightEllipse);
|
||||
}
|
||||
beatCanvasRight.Width = totalWidth;
|
||||
|
||||
}
|
||||
private DispatcherTimer _beatScrollTimer;
|
||||
private double totalTime = 108.455; // 音乐总时长
|
||||
private int _lastSecond = -1; // 上一次已经处理的秒数
|
||||
private void StartBeatScrollTimer()
|
||||
{
|
||||
if (_beatScrollTimer != null) _beatScrollTimer.Stop();
|
||||
|
||||
_beatScrollTimer = new DispatcherTimer();
|
||||
_beatScrollTimer.Interval = TimeSpan.FromMilliseconds(1000);
|
||||
_beatScrollTimer.Interval = TimeSpan.FromMilliseconds(500); // 每秒一次
|
||||
|
||||
int lastSecond = -1;
|
||||
|
||||
_beatScrollTimer.Tick += (s, e) =>
|
||||
{
|
||||
double currentTime = Utils.GetMusicCurrentTime();
|
||||
int currentSecond = (int)Math.Floor(currentTime)+1;
|
||||
|
||||
double progress = currentTime / totalTime;
|
||||
double maxOffsetLeft = beatCanvasLeft.Width - BeatScrollLeft.ViewportWidth;
|
||||
double maxOffsetRight = beatCanvasRight.Width - BeatScrollRight.ViewportWidth;
|
||||
BeatScrollLeft.ScrollToHorizontalOffset(progress * (beatCanvasLeft.Width - BeatScrollLeft.ViewportWidth));
|
||||
BeatScrollRight.ScrollToHorizontalOffset((1 - progress) * (beatCanvasRight.Width - BeatScrollRight.ViewportWidth));
|
||||
if (currentSecond <= lastSecond) return;
|
||||
lastSecond = currentSecond;
|
||||
// 左控件
|
||||
if (_musicBeatsDic.TryGetValue(currentSecond, out var leftBeats))
|
||||
{
|
||||
LeftBeats.SetSelected(currentSecond, true);
|
||||
LeftBeats.ScrollToDotCenter(currentSecond, mirror: true);
|
||||
}
|
||||
|
||||
// 右控件
|
||||
if (_musicBeatsDic.TryGetValue(currentSecond, out var rightBeats))
|
||||
{
|
||||
RightBeats.SetSelected(currentSecond, true);
|
||||
RightBeats.ScrollToDotCenter(currentSecond, mirror: false);
|
||||
}
|
||||
};
|
||||
_beatScrollTimer.Start();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user