<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SHAZAML! &#187; ParticlesBehavior</title>
	<atom:link href="http://www.shazaml.com/archives/tag/particlesbehavior/feed" rel="self" type="application/rss+xml" />
	<link>http://www.shazaml.com</link>
	<description>The Blog for Design &#38; Development Superheroes</description>
	<lastBuildDate>Wed, 28 Jul 2010 21:02:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Video: Creating a Silverlight 3 Casual Game using Blend 3 and Triggers, Actions, and Behaviors</title>
		<link>http://www.shazaml.com/archives/video-silverlight-casual-game</link>
		<comments>http://www.shazaml.com/archives/video-silverlight-casual-game#comments</comments>
		<pubDate>Mon, 09 Nov 2009 15:19:11 +0000</pubDate>
		<dc:creator>Mark Tucker</dc:creator>
				<category><![CDATA[Hidden Object Game]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Action]]></category>
		<category><![CDATA[Behavior]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[ChangePropertyAction]]></category>
		<category><![CDATA[ContinuousPlayMediaBehavior]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[GlobalCounterMinReachedTrigger]]></category>
		<category><![CDATA[GoToStateAction]]></category>
		<category><![CDATA[IncrementGlobalCounterAction]]></category>
		<category><![CDATA[InvokeCommandAction]]></category>
		<category><![CDATA[MagnifierOverBehavior]]></category>
		<category><![CDATA[MouseCursorBehavior]]></category>
		<category><![CDATA[ParticlesBehavior]]></category>
		<category><![CDATA[PlaySoundAction]]></category>
		<category><![CDATA[RemoveElementAction]]></category>
		<category><![CDATA[SetGlobalCounterAction]]></category>
		<category><![CDATA[SetInteractionPropertyAction]]></category>
		<category><![CDATA[ShowGlobalCounterBehavior]]></category>
		<category><![CDATA[Trigger]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[Visual State Manager]]></category>
		<category><![CDATA[VSM]]></category>

		<guid isPermaLink="false">http://www.shazaml.com/?p=333</guid>
		<description><![CDATA[Video presentation from Desert Code Camp 2009 - Silverlight 3 Casual Game]]></description>
			<content:encoded><![CDATA[<p>On Saturday, November 7, 2009 at 9:00am I presented at the Desert Code Camp in Phoenix, AZ. The topic of my presentation was Silverlight casual game development. In less than an hour I demonstrated how to use triggers, actions, and behaviors in Blend 3 to create a hidden object game. Because all code was contained in the TABs (Triggers, Actions, and Behaviors) there was no code behind for the main UserControl.</p>
<p>Here is a link to the <a title="Video - Creating a Silverlight 3 Casual Game using Blend 3 and Triggers, Actions, and Behaviors" href="http://www.shazaml.com/downloads/DesertCodeCamp2009-Silverlight3CasualGame.wmv">presentation video</a> in WMV format.</p>
<p>If you like you can see <a href="http://www.shazaml.com/archives/creating-a-hidden-object-game-in-silverlight-3">all the episodes</a> and follow along with the tutorial.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shazaml.com/archives/video-silverlight-casual-game/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
<enclosure url="http://www.shazaml.com/downloads/DesertCodeCamp2009-Silverlight3CasualGame.wmv" length="63294285" type="video/x-ms-wmv" />
		</item>
		<item>
		<title>Hidden Object: Episode 11 – Add Custom Shapes to the Particles Behavior</title>
		<link>http://www.shazaml.com/archives/hidden-object-episode-11</link>
		<comments>http://www.shazaml.com/archives/hidden-object-episode-11#comments</comments>
		<pubDate>Tue, 06 Oct 2009 00:05:27 +0000</pubDate>
		<dc:creator>Mark Tucker</dc:creator>
				<category><![CDATA[Hidden Object Game]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Behavior]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[ParticlesBehavior]]></category>

		<guid isPermaLink="false">http://www.shazaml.com/?p=292</guid>
		<description><![CDATA[Add sizzle to the Particles Behavior by allowing particle custom shapes.]]></description>
			<content:encoded><![CDATA[<p>This is episode 11 of <a href="http://www.shazaml.com/archives/creating-a-hidden-object-game-in-silverlight-3">Creating a Hidden Object Game is Silverlight 3</a>.</p>
<p>Growing up our family didn&#8217;t splurge on Lucky Charms cereal, but I remember the TV commercials with Lucky the leprechaun talking about all the fun marshmallow shapes: pink hearts, yellow moons, orange stars, green clovers, and blue diamonds. In later years other shapes appeared such as purple horseshoes, red balloons, rainbows, and pots of gold.</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/100609_0005_HiddenObjec1.jpg" alt="" /></p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/100609_0005_HiddenObjec2.jpg" alt="" /></p>
<p> </p>
<p>What does this have to do with our hidden object game? Currently the ParticleControl creates only one shape. Circles. Wouldn&#8217;t it be great if you could specify the shape of the particles? That&#8217;s what I thought and I knew it could easily be done once I saw this <a href="http://stringtopathgeometry.codeplex.com/Thread/View.aspx?ThreadId=66283">discussion post</a> on the <a href="http://www.codeplex.com/">CodePlex</a> site for the <a href="http://stringtopathgeometry.codeplex.com/">Silverlight String-To-PathGeometry Converter</a>.</p>
<p>To the existing ParticlesBehavior, we will add two dependency properties with corresponding property get/set blocks:</p>
<p> </p>
<pre class="brush: csharp; gutter: false;">
public static readonly DependencyProperty ParticleShapeProperty =
    DependencyProperty.Register(&quot;ParticleShape&quot;, typeof(ParticleShape),
    typeof(ParticlesBehavior), null);

public static readonly DependencyProperty CustomShapePathDataProperty =
    DependencyProperty.Register(&quot;CustomShapePathData&quot;, typeof(string),
    typeof(ParticlesBehavior), null);
</pre>
<p> </p>
<p>The ParticleShape property is an enum with a list of possible shapes and a custom option:</p>
<pre class="brush: csharp; gutter: false;">
public enum ParticleShape
{
    Circle,
    Square,
    Star4,
    Star5,
    Star8,
    Custom
}
</pre>
<p> </p>
<p>The CustomShapePathData property is a string that holds a special <a href="http://msdn.microsoft.com/en-us/library/ms752293.aspx">XAML Path markup syntax</a> and is used when the ParticleShape property is set to Custom. Here is an example of a path definition for a triangle:</p>
<p> </p>
<pre class="brush: xml; gutter: false;">
&lt;Path Data=&quot;F1 M 50,7.62939e-006L -1.02561e-005,100L 100,100L 50,7.62939e-006 Z &quot;/&gt;
</pre>
<p> </p>
<p>The value of the Data property is what is set on CustomShapePathData.</p>
<p> </p>
<p>The only other change we need to make to ParticlesBehavior is in the OnShowParticles method where we set the ParticleShape and CustomShapePathData on the instance of ParticleControl.</p>
<p> </p>
<p>In ParticleControl, we add the same two dependency properties for ParticleShape and CustomShapePathData with their corresponding property get and set.</p>
<p> </p>
<p>The Ellipse, Rectangle, and Path all inherit from the Shape base class. So we change all the methods in ParticleControl that worked on an Ellipse to a Shape. In the SpawnParticle method, we call the newly created CreateShape method:</p>
<p> </p>
<pre class="brush: csharp; gutter: false;">
private Shape CreateShape()
{
    string pathData = &quot;&quot;;

    switch (ParticleShape)
    {
        case ParticleShape.Circle:
            return new Ellipse();
 
        case ParticleShape.Square:
            return new Rectangle();

        case ParticleShape.Star4:
            pathData = star4;
            break;

        case ParticleShape.Star5:
            pathData = star5;
            break;

        case ParticleShape.Star8:
            pathData = star8;
            break;

        case ParticleShape.Custom:
            if (string.IsNullOrEmpty(CustomShapePathData))
                return new Ellipse();
            else
                pathData = CustomShapePathData;
            break;

        default:
            return new Ellipse();
    }

    string xamlPath = string.Format(&quot;&lt;Path xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' &quot; +
             &quot;xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' &quot; +
             &quot;Data='{0}' Stretch='Fill'/&gt;&quot;, pathData);

    Path path = (Path)System.Windows.Markup.XamlReader.Load(xamlPath);

    return path;
}
</pre>
<p> </p>
<p>If the ParticleShape property is set to Circle or Square, then a new Ellipse or Rectangle is created and returned. If the selected shape is a 4, 5, or 8-pointed star then a string constant containing the Path data syntax is set and a new Path is created using the XamlReader.Load method. If it is a custom shape, then the data is set based on the value of the CustomShapePathData property. If there is no custom path data, then an Ellipse is created.</p>
<p> </p>
<p>When we compile the project and open Blend, we will now see the additional properties:</p>
<p> </p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/100609_0005_HiddenObjec3.png" alt="" /></p>
<p> </p>
<p>Here is what the custom triangle particles look like as well as the built-in shapes:</p>
<p> </p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/100609_0005_HiddenObjec4.png" alt="" /></p>
<p> </p>
<p>One of the best ways to create these custom shapes is in Expression Design. Create a new document that is 100&#215;100 pixels. Use the Pen, Polygon, or Polyline tools to create a path to your desired shape. Or create multiple paths and use Path operations (Unite, Front Minus Back, etc.) to create a single path.</p>
<p> </p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/100609_0005_HiddenObjec5.png" alt="" /></p>
<p>Select the Path and on the Edit menu select Copy XAML. Paste the XAML into Notepad and copy the Data property string and paste it as the CustomShapePathData value:</p>
<p> </p>
<pre class="brush: xml; gutter: false;">
&lt;Canvas xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
    x:Name=&quot;Layer_1_4&quot; Width=&quot;100&quot; Height=&quot;100&quot; Canvas.Left=&quot;0&quot; Canvas.Top=&quot;0&quot;&gt;

    &lt;Path Width=&quot;99.7292&quot; Height=&quot;100.79&quot;
        Canvas.Left=&quot;-1.84403&quot; Canvas.Top=&quot;-1.13409&quot;
        Stretch=&quot;Fill&quot; StrokeLineJoin=&quot;Round&quot; Stroke=&quot;#FF000000&quot;

        Data=&quot;F1 M 31.5808,99.156C 34.4917,98.2985 37.4026,97.441 40.1509,96.3542C 42.8991,95.2675 45.4846,93.9515 47.874,92.4426C 50.2634,90.9336 52.4566,89.2317 54.4271,87.3777C 56.3976,85.5237 58.1453,83.5175 59.6511,81.4035C 61.1568,79.2895 62.4206,77.0676 63.4311,74.7844C 64.4415,72.5011 65.1986,70.1565 65.699,67.7977C 66.1994,65.439 66.4431,63.0661 66.6868,60.6933C 67.6642,61.334 68.6416,61.9748 69.581,62.7785C 70.5203,63.5821 71.4217,64.5487 72.2503,65.6721C 73.0789,66.7954 73.8349,68.0754 74.4845,69.4997C 75.1342,70.9239 75.6777,72.4923 76.0837,74.1863C 76.4897,75.8803 76.7583,77.6999 76.8615,79.6207C 76.9647,81.5416 76.9025,83.5637 76.6513,85.6577C 76.4,87.7517 75.9597,89.9176 75.5194,92.0835C 76.6639,89.273 77.8084,86.4624 78.6723,83.6362C 79.5361,80.81 80.1193,77.9681 80.4293,75.1592C 80.7393,72.3503 80.7762,69.5744 80.5552,66.8778C 80.3342,64.1813 79.8555,61.564 79.1415,59.0687C 78.4275,56.5734 77.4784,54.2 76.3232,51.9865C 75.1681,49.7729 73.8071,47.7191 72.2749,45.8572C 70.7427,43.9953 69.0395,42.3253 67.3363,40.6554C 68.4466,40.2907 69.557,39.926 70.771,39.6927C 71.985,39.4594 73.3028,39.3573 74.6976,39.4098C 76.0925,39.4624 77.5646,39.6695 79.0832,40.0495C 80.6018,40.4296 82.1669,40.9826 83.7444,41.7214C 85.322,42.4601 86.912,43.3846 88.4781,44.5016C 90.0443,45.6185 91.5865,46.9279 93.067,48.4299C 94.5475,49.9319 95.9663,51.6266 97.3851,53.3212C 95.9014,50.6741 94.4176,48.027 92.7466,45.5895C 91.0756,43.152 89.2173,40.9241 87.2145,38.9304C 85.2117,36.9367 83.0644,35.1771 80.8184,33.6686C 78.5723,32.1601 76.2276,30.9026 73.8315,29.905C 71.4354,28.9074 68.9881,28.1697 66.5372,27.6927C 64.0864,27.2156 61.632,26.9993 59.2211,27.0363C 56.8101,27.0733 54.4425,27.3637 52.075,27.6541C 52.4822,26.5587 52.8893,25.4632 53.4638,24.3686C 54.0383,23.2739 54.7801,22.18 55.6909,21.1222C 56.6017,20.0644 57.6814,19.0426 58.9254,18.0923C 60.1693,17.142 61.5775,16.2632 63.1387,15.4904C 64.6999,14.7176 66.414,14.0509 68.2638,13.5228C 70.1135,12.9948 72.0987,12.6054 74.1961,12.3844C 76.2935,12.1634 78.5031,12.1107 80.7127,12.058C 77.7179,11.5676 74.7232,11.0772 71.7757,10.8639C 68.8281,10.6506 65.9276,10.7144 63.1202,11.0372C 60.3127,11.36 57.5982,11.9418 55.0184,12.7573C 52.4386,13.5727 49.9936,14.6219 47.7197,15.8732C 45.4458,17.1245 43.3432,18.578 41.4421,20.1967C 39.5411,21.8155 37.8416,23.5994 36.3674,25.5075C 34.8931,27.4156 33.644,29.4477 32.3949,31.4798C 31.7923,30.4784 31.1897,29.4771 30.6921,28.3454C 30.1944,27.2137 29.8017,25.9518 29.5425,24.5802C 29.2834,23.2085 29.1577,21.7273 29.1903,20.1622C 29.223,18.5971 29.4138,16.9482 29.783,15.2458C 30.1522,13.5434 30.6997,11.7875 31.4402,10.0121C 32.1806,8.23676 33.114,6.44186 34.2489,4.66424C 35.3838,2.88662 36.7202,1.12626 38.0567,-0.634094C 35.8061,1.40149 33.5555,3.4371 31.5509,5.60862C 29.5464,7.78015 27.7879,10.0876 26.2898,12.4839C 24.7918,14.8801 23.5542,17.3651 22.5833,19.8904C 21.6124,22.4158 20.9082,24.9816 20.4687,27.5396C 20.0293,30.0976 19.8547,32.6477 19.935,35.1433C 20.0153,37.6388 20.3505,40.0798 20.9231,42.4221C 21.4956,44.7643 22.3056,47.0079 23.1156,49.2515C 21.957,49.0983 20.7984,48.9451 19.6033,48.6286C 18.4083,48.3121 17.1768,47.8323 15.9428,47.1797C 14.7089,46.5272 13.4724,45.7019 12.2692,44.7006C 11.0659,43.6993 9.89571,42.522 8.79491,41.1719C 7.69411,39.8218 6.66265,38.299 5.73625,36.6131C 4.80985,34.9273 3.9885,33.0785 3.3063,31.0828C 2.6241,29.0872 2.08106,26.9447 1.53801,24.8023C 1.72628,27.8311 1.91455,30.8598 2.36251,33.781C 2.81047,36.7021 3.51811,39.5156 4.45754,42.1809C 5.39696,44.8461 6.56816,47.3631 7.93723,49.6967C 9.30631,52.0304 10.8733,54.1807 12.5992,56.1191C 14.3251,58.0575 16.2101,59.784 18.2112,61.2772C 20.2124,62.7704 22.3298,64.0303 24.5181,65.043C 26.7063,66.0557 28.9654,66.8213 31.2246,67.5869C 30.3824,68.3972 29.5402,69.2075 28.5477,69.9445C 27.5551,70.6815 26.4122,71.3452 25.1326,71.903C 23.8531,72.4609 22.4369,72.913 20.9038,73.2295C 19.3707,73.546 17.7207,73.7268 15.9788,73.7457C 14.237,73.7646 12.4033,73.6215 10.5076,73.2947C 8.61196,72.9679 6.65438,72.4573 4.66878,71.7464C 2.68319,71.0355 0.669576,70.1243 -1.34403,69.2131C 1.14133,70.9543 3.62669,72.6955 6.18983,74.1666C 8.75297,75.6376 11.3939,76.8386 14.0634,77.7659C 16.7329,78.6932 19.4309,79.3468 22.1091,79.7314C 24.7872,80.116 27.4453,80.2316 30.037,80.0908C 32.6286,79.95 35.1537,79.5528 37.5688,78.9192C 39.9839,78.2856 42.2891,77.4156 44.4452,76.3362C 46.6014,75.2568 48.6085,73.9679 50.6156,72.6789C 50.724,73.8426 50.8324,75.0063 50.7898,76.2418C 50.7472,77.4773 50.5534,78.7847 50.1918,80.1329C 49.8302,81.4811 49.3007,82.8702 48.5923,84.2661C 47.8838,85.6621 46.9964,87.0649 45.9251,88.4385C 44.8539,89.8121 43.5987,91.1566 42.1613,92.4349C 40.7239,93.7132 39.1042,94.9254 37.3104,96.0345C 35.5166,97.1437 33.5487,98.1498 31.5808,99.156 Z &quot;/&gt;
&lt;/Canvas&gt;
</pre>
<p> </p>
<p>It&#8217;s that easy:</p>
<p> </p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/10/100609_0005_HiddenObjec6.png" alt="" /><br />
 <br />
<a href="http://www.shazaml.com/downloads/ClutteredCubeSource11.zip">Source code</a><br />
<a href="http://www.shazaml.com/hidden-object-episode-11-demo">Demo</a></p>
<p>In the <a href="http://www.shazaml.com/archives/hidden-object-episode-12">next episode</a>, we will create a custom mouse cursor and manage its use with a behavior.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shazaml.com/archives/hidden-object-episode-11/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hidden Object: Episode 4 – Adding Particles with a Behavior</title>
		<link>http://www.shazaml.com/archives/hidden-object-episode-4</link>
		<comments>http://www.shazaml.com/archives/hidden-object-episode-4#comments</comments>
		<pubDate>Fri, 18 Sep 2009 03:25:53 +0000</pubDate>
		<dc:creator>Mark Tucker</dc:creator>
				<category><![CDATA[Hidden Object Game]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Behavior]]></category>
		<category><![CDATA[Blend]]></category>
		<category><![CDATA[DebugEventTrigger]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[InvokeCommandAction]]></category>
		<category><![CDATA[ParticlesBehavior]]></category>
		<category><![CDATA[RemoveElementAction]]></category>
		<category><![CDATA[Trigger]]></category>

		<guid isPermaLink="false">http://www.shazaml.com/?p=80</guid>
		<description><![CDATA[Create ParticlesBehavior and make use of DebugEventTrigger, InvokeCommandAction, and RemoveElementAction]]></description>
			<content:encoded><![CDATA[<p>In the previous episodes of <a title="Creating a Hidden Object Game in Silverlight 3" href="http://www.shazaml.com/archives/creating-a-hidden-object-game-in-silverlight-3">Creating a Hidden Object Game in Silverlight 3</a> we spent all of our time in Blend. Now we are going to put on our developer hat and create our own custom behavior that will shoot particles when an item is clicked. This will give a nice visual effect that compliments marking the item off the list and the sound effect.</p>
<p>Click <a href="http://www.shazaml.com/hidden-object-episode-4-demo">here</a> to see a demo of what the game will look like after we finish this episode.</p>
<p>I want to make sure that I give tons of credit to Robby Ingebretsen from <a href="http://blog.nerdplusart.com/">nerdplusart</a> for his <a href="http://blog.nerdplusart.com/archives/silverlight-particle-generator">Silverlight Particle Generator</a>. If you haven&#8217;t had a chance to play with it before (and I do mean play) then take a few minutes to do so.</p>
<p><a href="http://labs.nerdplusart.com/particles/fullscreen.php"><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec1.png" border="0" alt="" /></a></p>
<p>The plan is to take the ParticleControl from that solution and wrap it in a ParticlesBehavior that will be triggered when the item&#8217;s path (ex: staplerPath) is clicked.</p>
<p>First we need to take a side-step into the differences between an action and a behavior and their relationship to triggers. We will start to see some patterns emerge. In the previous episodes we looked at two actions (ChangeProperyAction &amp; PlaySoundAction) and noticed that an action specifies what will happen and to which object. When the action will occur is specified by a trigger. There are two main types of actions (TriggerAction &amp; TargetedTriggerAction). The first allows us to attach to an object and invoke some code when a trigger is fired whereas the second does that <em>and</em> defines a target for the action that is different from the object that the action is associated with. Both of these actions can only be called by a single trigger. A behavior in some ways appears simpler than an action because there is no direct connection to a trigger and therefore no <em>Invoke</em> method to be called. All we get are overrides for OnAttached and OnDetaching. But behaviors are powerful, can hold state, and can do various things based on <em>many</em> triggers.</p>
<p>For a class diagram of the Action and Behavior base classes as well as some great sample behaviors, check out the <a href="http://www.silverlightshow.net/items/Behaviors-and-Triggers-in-Silverlight-3.aspx">Behaviors and Triggers in Silverlight 3</a> article on SilverlightShow.</p>
<p>Hint: We will use the MagnifierOverBehavior in the next episode.</p>
<p>Enough talking lets open Blend and get coding. In the Projects panel, create a folder called Interactivity and under it a folder called ParticlesBehavior. Interactivity seems to be the term Microsoft uses to talk about both actions and behaviors and by the time we are done with this tutorial we will have created both types. I am doing this in Blend, because it has a template to create a basic behavior.</p>
<p>Right-click the ParticlesBehavior folder, pick Add New Item, select Behavior, and enter the name: ParticlesBehavior.</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec2.png" alt="" /></p>
<p>Click OK to create the behavior.</p>
<p>After saving all the files, open the solution concurrently in Visual Studio 2008 so that you can switch back and forth between Visual Studio and Blend as needed.</p>
<p>Go to the <a href="http://blog.nerdplusart.com/archives/silverlight-particle-generator">Silverlight Particle Generator</a> page and download the source code. Copy the following files into the Interactivity\ParticlesBehavior folder and include them in the project:</p>
<ul style="margin-left: 38pt">
<li>ParticleControl.xaml</li>
<li>ParticleControl.xaml.cs</li>
<li>LICENSE.TXT</li>
</ul>
<p>The quick idea behind the ParticlesBehavior is that it will be attached to the LayoutRoot canvas. The behavior will handle the canvas&#8217;s MouseMove event and store the current mouse position. When the ParticlesBehavior is notified that it should show particles, it creates an instance of the ParticleControl and positions it by setting the OffsetX and OffsetY properties.</p>
<p>We start by changing the class declaration so that ParticlesBehavior inherits from Behavior&lt;Canvas&gt;. Now throughout code, AssociatedObject will be of type Canvas. This also means that this behavior can only be attached to objects of type Canvas. In the OnAttached method an event handler is created for the canvas&#8217; MouseMove event whereas in the OnDetaching method the event handler is removed. When the mouse is moved, the current position is recorded.</p>
<pre class="brush: csharp; gutter: false;">
public class ParticlesBehavior : Behavior&lt;Canvas&gt;
{
private Point currentMousePosition;

protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.MouseMove += new MouseEventHandler(AssociatedObject_MouseMove);
}

protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.MouseMove -= new MouseEventHandler(AssociatedObject_MouseMove);
}

void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
{
currentMousePosition = e.GetPosition(null);
}
}
</pre>
<p>Now we need a way to trigger when the control will be shown or hidden. This is achieved by adding a command to ParticlesBehavior called ShowParticles. In the constructor, instantiate a new ActionCommand and pass it an Action delegate. The method that you use can have no parameters or one parameter (of type object). Later when triggers are associated with this behavior you can set the value of the CommandParameter. If you have a method that passes an object parameter, you can get access to the parameter.</p>
<p>This command then creates and sets properties on the ParticleControl and adds it to the Children collection of LayoutRoot. Update the ParticlesBehavior class to include this code:</p>
<pre class="brush: csharp; gutter: false; highlight: [5,6,7,8,27,28,29,30,31,33,34,35,36,37,38,39,40,41];">
public class ParticlesBehavior : Behavior&lt;Canvas&gt;
{
    private Point currentMousePosition;

    public ParticlesBehavior()
    {
        this.ShowParticles = new ActionCommand(this.OnShowParticles);
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.MouseMove += new MouseEventHandler(AssociatedObject_MouseMove);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.MouseMove -= new MouseEventHandler(AssociatedObject_MouseMove);
    }

    void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
    {
        currentMousePosition = e.GetPosition(null);
    }

    public ICommand ShowParticles
    {
        get;
        private set;
    }

    private void OnShowParticles()
    {
        ParticleControl p = new ParticleControl();

        p.OffsetX = currentMousePosition.X;
        p.OffsetY = currentMousePosition.Y;

        AssociatedObject.Children.Add(p);
    }

}
</pre>
<p>If you compile the project, you will now see the ParticlesBehavior in the Assets panel. Drag and drop it on LayoutRoot. The properties panel will have a ShowParticles group created for the ShowParticles Command and an empty Triggers list:</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec3.png" alt="" /></p>
<p>Click the plus sign to the right of Triggers and pick EventTrigger and set the SourceName (staplerPath) and EventName (MouseLeftButtonDown):</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec4.png" alt="" /></p>
<p>What this is saying is that when the staplerPath object is clicked then it will call the ShowParticles command on this behavior. You could also specify a CommandParameter which you then could use if OnShowParticles had an object parameter defined. When you click the plus sign next to Triggers again, you can specify another EventTrigger to be called when idolPath is clicked. Repeat this for all the paths.</p>
<p>Run the game now and click on an item. You should see lots of particles flowing from that location. Find another object and click it and there will be a second stream of particles. The ParticleControl currently doesn&#8217;t have a way to stop the particles from flowing. We will take care of that in a minute. But let&#8217;s first try to figure out what is happening between the triggers and the behavior. The command defined on the behavior is an ICommand, it knows nothing about triggers. And triggers just know when something is going to happen. How does it know to call a command on the behavior? The answer is the InvokeCommandAction that is created behind the scenes. This can be seen in a diagram from the Expression Blend SDK User Guide:</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec5.png" alt="" /></p>
<p>It might be a good learning opportunity to intercept the trigger before it calls InvokeCommandAction and see it doing the work of connecting the trigger to the behavior. Let&#8217;s create a trigger that we can use and debug. In a new folder under Interactivity called DebugEventTrigger, create a class called DebugEventTrigger.cs:</p>
<pre class="brush: csharp; gutter: false;">
public class DebugEventTrigger : System.Windows.Interactivity.EventTrigger
{
    public DebugEventTrigger() : base() {}

    public DebugEventTrigger(string eventName) : base(eventName) {}

    protected override void OnEvent(EventArgs eventArgs)
    {
        base.OnEvent(eventArgs);
    }
}
</pre>
<p>We derive the class from EventTrigger so we can use it just list the triggers we have already used. Compile the project and in Blend, add this trigger to the triggers collection on the ParticlesBehavior and select the SourceName and EventName. Switch back to Visual Studio and set a breakpoint in the OnEvent method. Run the app in debug mode from Visual Studio. When the breakpoint is hit, look at the Locals window and you will see that the trigger has a single action, InvokeCommandAction, the CommandName is &#8220;ShowParticles&#8221; and the AssociatedObject is ParticlesBehavior.</p>
<p><a href="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec6.png"><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec6.png" alt="" width="503" height="279" /></a></p>
<p>Back to the issue of the never-ending particles. To fix this, we need just one set of changes to ParticleControl. The UpdateParticles method is the heart of the control and is called each time the Silverlight rendering process renders a frame. It updates existing particles, creates new particles, and removes expired particles. The particles are created 10 at a time until the particles collection reaches the MaxParticleCount. But because particles are also being removed from this collection the result is a never-ending flow of particles. Change <strong>this.particles.Count</strong> to <strong>totalParticlesCreated</strong> and define it as a private field at the top of the class definition as type int. At the end of the SpawnParticle method, increment the totalParticlesCreated value by one. Now the control will create particles until MaxParticleCount is reach and stop.</p>
<p>We have a fully-functioning ParticlesBehavior.</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec7.png" alt="" /></p>
<p>The last thing I did was add the dependency properties from ParticleControl (StartColor, EndColor, Fuzziness, MaxParticleCount, OriginVariance, Speed, ParticleSize, ParticleSizeVariance, Life, and LifeVariance) to ParticlesBehavior and set the values for each created instance of the ParticleControl. This gives a nice design-time experience to configure the particles. I changed a few values to better time the particles with the length of the sound played when an item is clicked:</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec8.png" alt="" /></p>
<p>There is one final thing we need to do when an item is clicked. Right now you can click on an item multiple times and it will play a sound and generate particles each time. To solve this, we can use the RemoveElementAction. This action removes the targeted element from its parent control. Drag the RemoveElementAction onto the staplerPath object. Since the trigger defaults to EventTrigger and MouseLeftButtonDown and the TargetName defaults to the AssociatedObject then we don&#8217;t have to change anything:</p>
<p><img src="http://www.shazaml.com/wp-content/uploads/2009/09/091809_0325_HiddenObjec9.png" alt="" /></p>
<p>When we click on the staplerPath then it will:</p>
<ul>
<li>Change the opacity of its corresponding TextBlock (ChangePropertyAction)</li>
<li>Play a sound (PlaySoundAction)</li>
<li>Spray particles (ParticlesBehavior)</li>
<li>Be removed from its parent control (RemoveElementAction)</li>
</ul>
<p>Download the <a href="http://www.shazaml.com/downloads/ClutteredCubeSource4.zip">source</a> for this episode.</p>
<p>In our <a href="http://www.shazaml.com/archives/hidden-object-episode-5">next episode</a>, we will use a magnifer pixel shader effect wrapped in a behavior to allow the user to zoom in on portions of the image.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.shazaml.com/archives/hidden-object-episode-4/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
