Вот оно:
Идея состоит в том, чтобы найти все элементы Stat, в которых Type является предпочитаемым_фотом
import xml.etree.ElementTree as ET
xml = '''<?xml version="1.0" encoding="UTF-8"?>
<SoccerFeed>
<SoccerDocument>
<Team>
<Founded>1919</Founded>
<Name>Angers</Name>
<Player uID="p40511">
<Name>Denis Petric</Name>
<Position>Goalkeeper</Position>
<Stat Type="first_name">Denis</Stat>
<Stat Type="last_name">Petric</Stat>
<Stat Type="preferred_foot">Left</Stat>
</Player>
<Player uID="p119744">
<Name>Mathieu Michel</Name>
<Position>Goalkeeper</Position>
<Stat Type="first_name">Mathieu</Stat>
<Stat Type="preferred_foot">Right</Stat>
</Player>
</Team>
</SoccerDocument>
</SoccerFeed>'''
root = ET.fromstring(xml)
prefered_foots = root.findall(".//Stat[@Type='preferred_foot']")
for foot in prefered_foots:
print(foot.text)
.
Эрих Мирабал >> Я попробовал HLSL, и мне было довольно интересно узнать что-то новое, но, как я, в целом Новичок Мне не удалось сделать размытие по Боксу / Гауссу ...
Во всяком случае, я нашел способ, который вообще не использует процессор.
Вместо того, чтобы перемещать Ellipse, я перемещаю их изображение.
Я генерирую PNG в памяти с классами RenderTargetBitmap и PngBitmapEncoder и перемещаю тезисы уже размытые и прозрачные изображения!
Большое спасибо всем за ответы!
На вашем месте я бы изучите использование встроенной в WPF системы анимации, а не обновляйте позиции вручную, используя обратный вызов, как вы это делаете. Например, возможно, стоит обратить внимание на класс Point3DAnimation
в пространстве имен System.Windows.Media.Animation
. С другой стороны, не похоже, что использование 3D-точек на самом деле вам что-то дает (насколько я могу судить, вы игнорируете значения Z при рендеринге эллипсов), поэтому вы можете захотеть перейти на простое использование Точка
s
Point3DAnimation
в пространстве имен System.Windows.Media.Animation
. С другой стороны, не похоже, что использование 3D-точек на самом деле вам что-то дает (насколько я могу судить, вы игнорируете значения Z при рендеринге эллипсов), поэтому вы можете захотеть перейти на простое использование Точка
s Встроенная система анимации вместо обновления позиций вручную с помощью обратного вызова, как вы делаете. Например, возможно, стоит обратить внимание на класс Point3DAnimation
в пространстве имен System.Windows.Media.Animation
. С другой стороны, не похоже, что использование 3D-точек на самом деле вам что-то дает (насколько я могу судить, вы игнорируете значения Z при рендеринге эллипсов), поэтому вы можете захотеть перейти на простое использование Точка
s Не думаю, что проблема в производительности. Приложение почти не привязывается к моему процессору, но частота кадров все еще не выглядит плавной.
Я бы посмотрел на две вещи. Как вы рассчитываете обновление вашей позиции и как часто вы запускаете событие для этого.
timer.Interval = TimeSpan.FromMilliseconds(10);
Это 100 кадров в секунду. Вместо этого выберите 30 кадров в секунду (каждое другое обновление на вашем мониторе) или 60 и т. Д. Вы должны попытаться синхронизировать обновления с монитором, как в видеоигре.
timer.Interval = TimeSpan.FromMilliseconds(33.33); // 30 fps
Одно это, вероятно, не решит проблему плавности. Вы также не должны предполагать, что время между событиями является фиксированным:
double elapsed = 0.1;
Когда вы запускаете таймер для обновления каждые 0,01 секунды, это не означает, что он фактически выполняется за единицу времени. Сборка мусора, планирование ОС, все, что может повлиять на количество времени, которое на самом деле требуется. Измерьте время, прошедшее с момента последнего обновления, и выполните расчеты на основе этого числа.
Удачи!
MSDN WPF имеет отличную демонстрацию Particle Effects. Кроме того, книга О'Рейли «Изучение XNA» посвящена тому, как использовать эффекты частиц с использованием XNA.
Thanks everyone for answering me.
I've taken into account each of your answers:
I've updated my source code :
The Particle class now only have the following properties:
public class Particle
{
public Point Velocity { get; set; } // Speed of move
public BlurEffect Blur { get; set; } // Blur effect
public Brush Brush { get; set; } // Brush (opacity)
}
The Window1.xaml did not change, but I changed his behind code:
public partial class Window1 : Window
{
DispatcherTimer timer = new DispatcherTimer();
Random random = new Random(DateTime.Now.Millisecond);
// Some general values
double MaxSize = 150;
double NumberOfParticles = 25;
double VerticalVelocity = 0.4;
double HorizontalVelocity = -2.2;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
for (int i = 0; i < NumberOfParticles; i++)
{
CreateParticle();
}
timer.Interval = TimeSpan.FromMilliseconds(33.33);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
// I control "particle" from their ellipse representation
foreach (Ellipse ellipse in ParticleHost.Children)
{
var p = ellipse.Tag as Particle;
var t = ellipse.RenderTransform as TranslateTransform;
// Update location
t.X += p.Velocity.X;
t.Y -= p.Velocity.Y;
// Check if the particle is too high
if (t.Y < -MaxSize)
{
t.Y = Height + MaxSize;
}
// Check if the particle has gone outside
if (t.X < -MaxSize || t.X > Width + MaxSize)
{
t.X = random.NextDouble() * Width;
t.Y = Height + MaxSize;
}
// Brush & Effect
ellipse.Fill = p.Brush;
// Comment this line to deactivate the Blur Effect
ellipse.Effect = p.Blur;
}
}
private void CreateParticle()
{
// Brush (White)
var brush = Brushes.White.Clone();
// Opacity (0.2 <= 1)
brush.Opacity = 0.2 + random.NextDouble() * 0.8;
// Blur effect
var blur = new BlurEffect();
blur.RenderingBias = RenderingBias.Performance;
// Radius (1 <= 40)
blur.Radius = 1 + random.NextDouble() * 39;
// Ellipse
var ellipse = new Ellipse();
// Size (from 15% to 95% of MaxSize)
ellipse.Width = ellipse.Height = MaxSize * 0.15 + random.NextDouble() * MaxSize * 0.8;
// Starting location of the ellipse (anywhere in the screen)
ellipse.RenderTransform = new TranslateTransform(random.NextDouble() * Width, random.NextDouble() * Height);
ellipse.Tag = new Particle
{
Blur = blur,
Brush = brush,
Velocity = new Point
{
X = HorizontalVelocity + random.NextDouble() * 4,
Y = VerticalVelocity + random.NextDouble() * 2
}
};
// Add the ellipse to the Canvas
ParticleHost.Children.Add(ellipse);
}
}
If you try this new version, you'll see that it's still not smooth.
But if you comment the line that affect the Blur effect, you'll see it going very smooth!
Any thoughts?
Я читал чей-то блог, который пытался сделать то же самое, но я не могу его найти ( Я буду продолжать искать это). Способ, которым он смог ускорить его применение, был путем повторного использования частиц. Каждый раз, когда вы создаете новую частицу, вы видите, как вы забираете память. Вы не можете позволить себе эту память, если у вас нет безумно хорошей системы, потому что .NET использует много памяти.
Решение: Повторно используйте частицы, как только частица больше не появляется на экране, или освободите ее память ( вероятно, не будет работать из-за GC) или переместить эту частицу внизу и использовать ее повторно.
Вы смотрели на выполнение ShaderEffect с использованием HLSL для рендеринга на GPU? Вы можете написать PixelShader . Вот некоторые другие примеры из одного анонса , и он также имеет несколько хороших ссылок. Это должно определенно быть гладким при рендеринге.
Не уверен, что это будет работать лучше, но кто-то собрал эмулятор Silverlight C64 , и техника, которую они используют, заключается в том, чтобы в основном отображать фильм с пользовательским источником (вашим кодом), который обеспечивает кадры.
Преимущество состоит в том, что вы получаете обратные вызовы, когда кадры отображаются, поэтому они могут адаптироваться к фактической скорости воспроизведения. Я не уверен, насколько хорошо это будет работать для более высоких разрешений, хотя пример C64 имеет только экран с низким разрешением для эмуляции.
Я решил вашу проблему, удалив строку ellipse.Effect и вместо этого добавил следующее в Window1.xaml
<Canvas x:Name="ParticleHost">
<Canvas.Effect>
<BlurEffect />
</Canvas.Effect>
</Canvas>
Конечно, у нее нет тот же вид, у каждого из них свой радиус размытия.