2012-12-03 7 views
8

मुझे a fun program मिला जो आपको overlay snowflakes over your desktop and windows पर अनुमति देता है। एक प्रोग्रामिंग चुनौती के रूप में मुझे यह समझने में दिलचस्पी है कि इसे स्वयं कैसे करें। उल्लेख नहीं है कि यह प्रोग्राम एक मेमोरी हॉग का थोड़ा सा है (यदि इसमें स्मृति रिसाव नहीं है)। मेरे पास शुरुआत है। मैं मूलभूत छवियों को एक छवि के साथ प्राप्त करने की कोशिश कर रहा हूं और फिर विस्तार करूंगा।गिरने वाले बर्फ फ्लेक जैसे तत्व ले जाएं

छवि को और अधिक आसानी से और स्वाभाविक रूप से स्थानांतरित करने के लिए मुझे वास्तव में क्या मदद मिलेगी।


संपादित करें:

मैं जवाब अनुभाग में नीचे नीचे एक समाधान तैनात लेकिन इसे और अधिक सीपीयू गहन जो मुझे पसंद नहीं होता है, किसी भी विचार?


WPF XAML कोड:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    AllowsTransparency="True" 
     WindowStyle="None" 
    Title="MainWindow" Height="350" Width="525" Background="Transparent" Topmost="True" WindowState="Maximized" ResizeMode="NoResize"> 
    <Grid Name="grid1"> 
     <Image Height="26" HorizontalAlignment="Left" Margin="{Binding flakeMargin}" Name="Image1" Stretch="Fill" VerticalAlignment="Top" Width="28" Source="/snowTest;component/Images/blue-pin-md.png" /> 
    </Grid> 
</Window> 

वीबी कोड:

Imports System.ComponentModel 

    Class MainWindow 
     Dim bw As BackgroundWorker = New BackgroundWorker 
     Dim flake0 As New flake 

     Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded 
      grid1.DataContext = flake0 
      AddHandler bw.DoWork, AddressOf backgroundMover 
      bw.RunWorkerAsync() 
     End Sub 

     Private Sub backgroundMover(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) 
      While (True) 
       flake0.move() 
       System.Threading.Thread.Sleep(100) 
      End While 
     End Sub 
    End Class 

परत वर्ग:

Imports System.ComponentModel 

Public Class flake 
    Implements INotifyPropertyChanged 

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

    Private Sub NotifyPropertyChanged(ByVal info As String) 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info)) 
    End Sub 

    Private Property startLeft As Integer = 300 
    Private Property left As Integer = left 
    Private Property top As Integer = 100 
    Private Property speed As Integer = 1 

    Public ReadOnly Property flakeMargin As Thickness 
     Get 
      Return New Thickness(left, top, 0, 0) 
     End Get 
    End Property 

    Public Sub move() 
     top += speed 
     left = (Math.Cos(top - 100)) * 6 + startLeft 
     NotifyPropertyChanged("flakeMargin") 
    End Sub 
End Class 
+6

सुनिश्चित नहीं हैं कि क्यों यह बंद कर दिया गया है, यह की तरह लगता है मेरे लिए एक असली सवाल है। मेरा उत्तरदाता होगा: चूंकि आप WPF में प्रति फ्रेम एनीमेशन करने की कोशिश कर रहे हैं, इसलिए आपको अपनी खुद की घड़ी के बजाय CompositionTarget.Redering ईवेंट का उपयोग करना चाहिए। प्रतिपादन ईवेंट पर आप अपना "ड्रा" कोड कह सकते हैं, जो छवि को चारों ओर ले जाना होगा। आप शायद ग्रिड के बजाय कैनवास का उपयोग करना चाहते हैं क्योंकि मेजबान तत्व –

उत्तर

1

क्यों आप इसे अपने आप को आगे बढ़ रहे हैं के रूप में एक एनीमेशन का उपयोग कर करने का विरोध किया ?

यदि आप डब्ल्यूपीएफ के एनीमेशन (जो अभिव्यक्ति मिश्रण में वास्तव में करना आसान है) का उपयोग करते हैं, तो मुझे लगता है कि आपको वह चिकनीता मिल जाएगी जो आप खोज रहे हैं और आप इसे और अधिक वास्तविक बनाते हुए आंदोलन में कुछ बदलाव प्राप्त कर सकते हैं।

WPF Expression Blend Videos

Basic Animation

+0

इस अनुशंसा के लिए धन्यवाद। इस अभ्यास के माध्यम से मैंने अभिव्यक्ति मिश्रण के अस्तित्व की खोज की है। हालांकि यह साफ दिखता है, मैं इस समय सॉफ्टवेयर खरीदने में विशेष रूप से रूचि नहीं रखता हूं। मैं अभिव्यक्ति मिश्रण के बिना डब्ल्यूपीएफ एनीमेशन कैसे करना है, इस बारे में कुछ शोध करूँगा लेकिन निश्चित रूप से किसी भी सुझाव के लिए आभारी होंगे। – volderArt

+0

ब्लेंड में आप जो भी कर सकते हैं, आप शुद्ध एक्सएएमएल में भी कर सकते हैं इसलिए ब्लेंड खरीदने की कोई ज़रूरत नहीं है, यह एक्सएएमएल को नजरअंदाज करने के लिए सिर्फ एक जीयूआई है ... –

+0

हाँ, आपको या तो अभिव्यक्ति मिश्रण खरीदना होगा या यदि आप भाग्यशाली हैं तो आपको अपने काम के माध्यम से एमएसडीएन (या अल्टीमेट) के साथ विजुअल स्टूडियो प्रीमियम मिलता है। अभी के लिए, आप परीक्षण का उपयोग कर सकते हैं। वीडियो का पालन करने और xaml सीखने के लिए परीक्षण का उपयोग करने के लिए यह पूरी तरह से लायक है। – Rhyous

2

यहाँ मेरी वर्तमान में प्रस्तावित समाधान है: क्या किया जा रहा है सबसे बड़ी को सही कारक थे कि मैं कैनवास है, जो मुझे गैर पूर्णांक वेतन वृद्धि में ले जाने की अनुमति का इस्तेमाल किया और मैं भी इस्तेमाल किया समाप्त कॉस अधिक प्रभावी ढंग से काम करता है। यह अधिक सीपीयू गहन है जितना मैं चाहूंगा (25-30%)। क्या किसी के पास सीपीयू पर प्रभाव को कम करने के बारे में कोई विचार है?

WPF/XAML:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    AllowsTransparency="True" 
     WindowStyle="None" 
    Title="MainWindow" Height="350" Width="525" Background="Transparent" Topmost="True" WindowState="Maximized" ResizeMode="NoResize"> 
    <Canvas Name="canvas1"> 

    </Canvas> 
</Window> 

VB.NET मुख्य विंडो:

Imports System.ComponentModel 

Class MainWindow 

    Dim bw As New BackgroundWorker 
    Dim flakes(17) As flake 

    Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded 
     For i = 0 To flakes.Count - 1 
      flakes(i) = New flake 
      flakes(i).image.DataContext = flakes(i) 
      flakes(i).image.SetBinding(Canvas.LeftProperty, "left") 
      flakes(i).image.SetBinding(Canvas.TopProperty, "top") 
      canvas1.Children.Add(flakes(i).image) 
     Next 

     AddHandler bw.DoWork, AddressOf backgroundMover 
     bw.RunWorkerAsync() 
    End Sub 


    Private Sub backgroundMover() 
     While (True) 
      For Each f In flakes 
       f.move() 
      Next 
      System.Threading.Thread.Sleep(50) 
     End While 
    End Sub 
End Class 

VB.Net परत वर्ग:

Imports System.ComponentModel 

Public Class flake 
    Implements INotifyPropertyChanged 

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged 

    Private Sub NotifyPropertyChanged(ByVal info As String) 
     RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info)) 
    End Sub 

    Private Property startLeft As Double 
    Private Property _left As Double 
    Private Property _top As Double 
    Private Property speed As Double 
    Private Property amplitude As Double 
    Private Property period As Double 
    Public Property image As New Image 
    Private Shared Property r As New Random 

    Public Sub New() 
     _image.Width = 28 
     _image.Height = 26 
     _image.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/snowTest;component/Images/blue-pin-md.png", UriKind.Relative)) 
     startFresh() 
    End Sub 

    Public ReadOnly Property left As Double 
     Get 
      Return _left 
     End Get 
    End Property 

    Public ReadOnly Property top As Double 
     Get 
      Return _top 
     End Get 
    End Property 

    Public Sub startFresh() 
     _top = -30 
     amplitude = r.Next(5, 35) 
     period = 1/r.Next(20, 60) 
     speed = r.Next(15, 25)/10 
     startLeft = r.Next(0, System.Windows.SystemParameters.PrimaryScreenWidth) 
    End Sub 

    Public Sub move() 
     If _top > System.Windows.SystemParameters.PrimaryScreenHeight Then 
      startFresh() 
     Else 
      _top += speed 
      _left = amplitude * Math.Cos(period * _top) + startLeft 
     End If 

     NotifyPropertyChanged("top") 
     NotifyPropertyChanged("left") 
    End Sub 
End Class 
संबंधित मुद्दे