几周后,我尝试为家庭聚会编写一个小图片拼图。
拼图应该如下所示:http ://www.welt.de/spiele/online-spiele/article2128160/Bilderraetsel.html (只需按“Spiel starten”即可查看演示)
我知道我现在的解决方案非常缓慢且丑陋..但作为第一步,它正在发挥作用。
我根据图像的大小动态创建了很多矩形(这很重要,因为我将拼图用于不同的图像)。
然后,每隔 X 秒,一个矩形将变得不可见(不透明度步长变为 0)。
问题是,在应用程序中,矩形行之间存在空格。
我用 StackPanel、WrapPanel 和 UniformGrid 进行了尝试。使用 UniformGrid,我得到了最好的结果。
最好的办法是,我会在内存中的整个图片大小上生成一个灰色图像,并在我的计时器中从这个内存图像中剪掉一些矩形。但我喜欢不透明效果,所以这是不可能的,不是吗?
这是我的 XAML:
<Window x:Class="PicturePuzzle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Width="525"
Height="420"
Loaded="WindowLoaded">
<Grid>
<Grid Height="300" VerticalAlignment="Top">
<Image x:Name="imgPicture"
Source="/PicturePuzzle;component/Images/Koala.jpg"
Stretch="Uniform" />
<UniformGrid x:Name="ugMask"
Width="{Binding ElementName=imgPicture,
Path=ActualWidth}"
Height="{Binding ElementName=imgPicture,
Path=ActualHeight}" />
</Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom">
<StackPanel Margin="0,0,0,10" Orientation="Horizontal">
<Button x:Name="btnStart"
Width="60"
Margin="0,0,5,0"
Click="BtnStartClick"
Content="Start" />
<Button x:Name="btnStop"
Width="60"
Click="BtnStopClick"
Content="Stop"
IsEnabled="False" />
<Button x:Name="btnSolution"
Margin="5,0,0,0"
Click="BtnSolutionClick"
Content="Lösung anzeigen" />
</StackPanel>
<Slider x:Name="slSpeed"
IsDirectionReversed="True"
Maximum="10"
Minimum="1"
ValueChanged="SlSpeedValueChanged"
Value="3" />
</StackPanel>
</Grid>
</Window>
我的代码隐藏:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace PicturePuzzle
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
public MainWindow()
{
_rectangles = new List<Rectangle>();
InitializeComponent();
_timer = new DispatcherTimer();
_generated = new List<int>();
_random = new Random();
}
private readonly List<Rectangle> _rectangles;
private readonly List<int> _generated;
private readonly DispatcherTimer _timer;
private readonly Random _random;
private void WindowLoaded(object sender, RoutedEventArgs e)
{
var size = imgPicture.RenderSize;
var columns = Convert.ToInt32(Math.Ceiling(size.Width/20));
var rows = Convert.ToInt32(Math.Ceiling(size.Height/20));
ugMask.Columns = columns;
ugMask.Rows = rows;
for (int y = 0; y < rows; y++)
{
for (int x = 0; x < columns; x++)
{
var rectangle = new Rectangle {Width = 20, Height = 20, Fill = Brushes.Gray};
_rectangles.Add(rectangle);
ugMask.Children.Add(rectangle);
}
}
}
private void BtnStartClick(object sender, RoutedEventArgs e)
{
btnStart.IsEnabled = false;
btnStop.IsEnabled = true;
_generated.Clear();
_rectangles.ForEach(a => a.Opacity = 1);
_timer.Interval = TimeSpan.FromSeconds(slSpeed.Value);
_timer.Tick += TimerTick;
_timer.Start();
}
private void TimerTick(object sender, EventArgs e)
{
if (_generated.Count >= _rectangles.Count)
{
_timer.Stop();
return;
}
var random = GetNext();
var alphaTimer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(0.1)};
alphaTimer.Tick += (o, args) =>
{
var rec = _rectangles[random];
if (rec.Opacity <= 0)
{
alphaTimer.Stop();
return;
}
rec.Opacity -= 0.1;
};
alphaTimer.Start();
}
private int GetNext()
{
int r;
do
{
r = _random.Next(0, _rectangles.Count);
} while (_generated.Contains(r));
_generated.Add(r);
return r;
}
private void BtnStopClick(object sender, RoutedEventArgs e)
{
btnStart.IsEnabled = true;
btnStop.IsEnabled = false;
_timer.Stop();
}
private void SlSpeedValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (_timer != null)
{
_timer.Interval = TimeSpan.FromSeconds((slSpeed.Value / 10));
}
}
private void BtnSolutionClick(object sender, RoutedEventArgs e)
{
btnStop.IsEnabled = false;
btnStart.IsEnabled = true;
_timer.Stop();
_rectangles.ForEach(a => a.Opacity = 0);
}
}
}
在这里你可以看到产生的结果:
欢迎每一个提示!谢谢。