Страницы

Поиск по вопросам

среда, 17 июля 2019 г.

Реализация программы Матричный дождь в WPF C#

На просторах интернета нашел реализацию Матричного дождя (падающие строки как в фильме Матрица). Реализация консольная и я решил попробовать перенести ее на WPF. В консоли символы дождя ставятся сразу в нужную позицию:
Console.SetCursorPosition(x, y);
Перед каждой вставкой может меняться цвет текста. Решил сделать через массив в который заносятся символы, а потом этот массив "печатается" в TextBox (реализация изменения цвета пока додумана, потом добавлю для каждого символа цвет и перейду на RichTextBox)
tb.Clear(); string s = ""; for (int i = 0; i < mh; i++) { for (int j = 0; j < mw; j++) { s += MatrixArray[i, j]; } s += "
"; tb.Text += s; }
В консоли было так:
public static void MatrixStep(int width, int height, int[] y, int[] l) {
int x; thistime = !thistime;
for (x = 0; x < width; ++x) {
if (x % 11 == 10) {
if (!thistime) continue;
Console.ForegroundColor = ConsoleColor.White; } else { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.SetCursorPosition(x, inBoxY(y[x] - 2 - (l[x] / 40 * 2), height)); Console.Write(R); Console.ForegroundColor = ConsoleColor.Green; } Console.SetCursorPosition(x, y[x]); Console.Write(R); y[x] = inBoxY(y[x] + 1, height); Console.SetCursorPosition(x, inBoxY(y[x] - l[x], height)); Console.Write(' '); // Основной фоновый символ в потоке }
Символы стразу выводились в консоль, а у меня сначала с массив. При выводе дождя наблюдается мерцание текста: Подскажите как можно оптимизировать данную задачу, или может есть более подходящий метод?
Воспользовался предложенным кодом с Canvas
private void PrintMatrix(int x, int y, char r) { this.Dispatcher.Invoke((Action)(() => { AddText(x, y, r); foreach (object myCanvasChild in cConsole.Children) { var tb = myCanvasChild as TextBlock; if (tb == null) return; var top = (double)tb.GetValue(Canvas.TopProperty); Canvas.SetTop(tb, top); } })); }
private void AddText(int x, int y, char r) { Rectangle rct = new Rectangle(); rct.Fill = Brushes.Black; rct.Height = 19; rct.Width = 17; Canvas.SetTop(rct, 21 * x + 4); Canvas.SetLeft(rct, 18 * y); cConsole.Children.Add(rct);
var txt = new TextBlock { Text = r.ToString(), Foreground = tc, FontSize = 18, FontWeight = FontWeights.Bold, FontFamily = new FontFamily("Courier New") }; Canvas.SetTop(txt, 21 * x + 5); Canvas.SetLeft(txt, 18 * y + 3); cConsole.Children.Add(txt); }
Но картинка на canvas подвисает:


Ответ

code behind:
using System; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media;
namespace matrix { ///

/// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { private readonly Random rnd = new Random();
public MainWindow() { InitializeComponent(); Task.Factory.StartNew(()=> { while (true) { Application.Current.Dispatcher.Invoke(()=> { AddText(); foreach (object myCanvasChild in MyCanvas.Children) { var tb = myCanvasChild as TextBlock; if (tb == null) return; var top = (double) tb.GetValue(Canvas.TopProperty); Canvas.SetTop(tb, top + 50); } }); Thread.Sleep(TimeSpan.FromMilliseconds(300)); } }); }
private void AddText() { var txt = new TextBlock { Text = $"some message value ={rnd.Next()}", Foreground = new SolidColorBrush(Colors.Green) }; Canvas.SetTop(txt, 0); MyCanvas.Children.Add(txt); } } }
XAML



PS надо бы еще почистить ненужные элементы

Комментариев нет:

Отправить комментарий