Silverlight: Mouse avoiding

Source: Internet
Author: User

I saw this effect on a foreign blog last night (from the domain name suffix pl I guess it should be Poland) (the mouse avoid evades the mouse), which was developed based on Flash/as3, this example combines multiple physics principles, such as elastic motion, friction, and accelerated motion, to produce a good interaction effect.


Online Demo

As3.0CodeAs follows:

Package {import flash. display. sprite; import flash. events. event; import flash. geom. point; public class mouseavoider extends sprite {private const spring: Number = 0.1; // elasticity coefficient private const friction: Number = 0.9; // friction coefficient private const fear_distance: Number = 150; // security distance (if the distance is smaller than this distance, the evasion behavior will occur) Private const max_avoid_force: uint = 10; // maximum escape speed private VaR _ destinationpoint: point; // target static point (when the mouse is away from the object, the object will eventually rest the coordinate point) Private VaR _ speed: Point = new point ); // speed vector (_ speed. X is equivalent to VX, _ speed. Y is equivalent to Vy) Public Function mouseavoider (): void {drawstuff ();} private function drawstuff (): void {// first draws a circle graphics with a radius of 10 by default. beginfill (math. random () * 0 xffffff); // graphics. beginfill (0 xffffff); graphics. drawcircle (0, 0, 5); graphics. endfill ();} // write only attributes (Set destination point) public function set destinationpoint (value: Point): void {_ destinationpoint = value; addeventlistener (event. enter_frame, enterframehandler);} protected function enterframehandler (E: Event): void {movetodestination (); // first move to the target point avoidmouse (); // dodge the mouse applyfriction (); // apply friction updateposition (); // update position} // move to the target point in auto motion mode private function movetodestination (): void {_ speed. X + = (_ destinationpoint. x-x) * spring; _ speed. Y + = (_ destinationpoint. y-y) * spring;} // Dodge mouse private function avoidmouse (): void {var currentposition: Point = new point (x, y ); // determine the current position var mouseposition: Point = new point (stage. mousex, stage. mousey); // specifies the mouse position var distance: uint = point. distance (currentposition, mouseposition); // calculate the distance between the mouse and the current position. // if the distance is lower than the safe distance, if (distance <fear_distance) {var force: number = (1-distance/fear_distance) * max_avoid_force; // calculate the escape distance (per unit of time)-that is, the escape rate var GAMMA: Number = math. atan2 (currentposition. y-mouseposition. y, currentposition. x-mouseposition. x); // calculates the angle between the mouse position and the current position. var avoidvector: Point = point. polar (force, gamma); // converts a polar coordinate to a normal (Cartesian) coordinate-in fact, it is equivalent to VX = force * Math. cos (gamma), Vy = force * Math. sin (gamma) // acceleration to escape _ speed. X + = avoidvector. x; _ speed. Y + = avoidvector. Y ;}}// application friction private function applyfriction (): void {_ speed. x * = friction; _ speed. y * = friction;} // The Final Update position. Private function updateposition (): void {x + = _ speed. x; y + = _ speed. Y ;}}}

test code:

Package {import flash. display. bitmap; import flash. display. bitmapdata; import flash. display. sprite; import flash. filters. blurfilter; import flash. geom. colortransform; import flash. geom. point; import flash. events. event; import flash. geom. rectangle ;/***... * @ author Andrzej korolczuk */[SWF (Height = "300", width = "400")] public class mouseavoidertest extends sprite {private var Background: bitmap; private var backgroundbitmapdata: bitmapdata; private var container: SPRITE = new sprite (); Private var bounds: rectangle; private var blur: blurfilter = new blurfilter (5, 5); Private var colortransform: colortransform = new colortransform (0.9, 0.9, 0.9); Public Function mouseavoidertest () {addeventlistener (event. added_to_stage, init);} private function Init (E: Event): void {bounds = new rectangle (0, 0, stage. stagewidth, stage. stageheight); addchild (container); backgroundbitmapdata = new bitmapdata (stage. stagewidth, stage. stageheight, true, 0xff000000); background = new Bitmap (backgroundbitmapdata); addchild (background); var I: uint = 7; while (I --) {addavoider ();} addeventlistener (event. enter_frame, enterframehandler);} // create the private function addavoider (): void {var Avoider: mouseavoider = new mouseavoider (); container. addchild (Avoider); // randomly sets the target point Avoider. destinationpoint = new point (100 + (stage. stageWidth-200) * Math. random (), 100 + (stage. stageHeight-200) * Math. random ();} private function enterframehandler (E: Event): void {backgroundbitmapdata. draw (container); // generates the bitmap data backgroundbitmapdata based on the contents of the container. applyfilter (backgroundbitmapdata, bounds, new point (0, 0), blur); // apply the fuzzy filter backgroundbitmapdata. colortransform (bounds, colortransform); // apply the color filter (R, G, and B color values are all changed to 90%) for (var I: uint = 0; I <container. numchildren; I ++) {var Avoider: mouseavoider = container. getchildat (I) As mouseavoider; // the offset of the three-color components of R, G, and B is set to a random number (which will flash continuously) Avoider. transform. colortransform = new colortransform (1, 1, 1, math. random () * 30, math. random () * 30, math. random () * 30 );}}}}

After reading the as3 code, I was thinking about how to port it to Silverlight. In the afternoon, I took the time to study it and basically restored it with Silverlight, however, due to the weak functionality of Silverlight in bitmap programming, there is no colortransform color transformation in Flash (or maybe I did not find the corresponding method in Silverlight), the effect is still a little different.
First define a control mouseavoider. XAML:

 
<Usercontrol X: class = "mouseavoider. mouseavoider "xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "xmlns: D =" http://schemas.microsoft.com/expression/blend/2008 "xmlns: MC =" http://schemas.openxmlformats.org/markup-compatibility/2006 "MC: ignorable =" D "D: designheight = "10" D: designwidth = "10"> <canvas> <ellipse width = "10" Height = "10" fill = "white" strokethickness = "0" X: name = "ball"> <ellipse. rendertransform> <scaletransform X: Name = "scale"> </scaletransform> </ellipse. rendertransform> </ellipse> </canvas> </usercontrol>

backend CS code:

Using system; using system. windows; using system. windows. controls; using system. windows. media; namespace mouseavoider {public partial class mouseavoider: usercontrol {private double _ spring = 0.1; private double _ friction = 0.92; private int _ fear_distance = 150; private int _ max_avoid_force = 10; private point _ destinationpoint; private point _ speed = new point (0, 0); Public mouseavoider () {initializecomponent (); this. loaded + = new routedeventhandler (mouseavoider_loaded);} void mouseavoider_loaded (Object sender, routedeventargs e) {// to implement color, enable the following code: // random RND = new random (); // system. threading. thread. sleep (5); // This. ball. fill = new solidcolorbrush (color. fromargb (255, (byte) RND. next (0,256), (byte) RND. next (0,256), (byte) RND. next (0,256);} public point destinationpoint {set {_ destinationpoint = value; compositiontarget. rendering + = new eventhandler (compositiontarget_rendering) ;}} private Double X {get {return (double) This. getvalue (canvas. leftproperty);} set {This. setvalue (canvas. leftproperty, value) ;}} private Double Y {get {return (double) This. getvalue (canvas. topproperty);} set {This. setvalue (canvas. topproperty, value) ;}} void compositiontarget_rendering (Object sender, eventargs e) {// move to the target point in auto-motion mode _ speed. X + = (_ destinationpoint. x-x) * _ spring; _ speed. Y + = (_ destinationpoint. y-y) * _ spring; // Dodge mouse point currentposition = new point (x, y); point mouseposition = (App. current. rootvisual as mainpage ). mouseposition; var dx = currentposition. x-mouseposition. x; var DY = currentposition. y-mouseposition. y; double distance = math. SQRT (dx * dx + dy * Dy); If (distance <_ fear_distance) {double force = (1-distance/_ fear_distance) * _ max_avoid_force; double Gamma = math. atan2 (dy, dx); point avoidvector = new point (force * Math. cos (gamma), force * Math. sin (gamma); _ speed. X + = avoidvector. x; _ speed. Y + = avoidvector. y;} // apply friction _ speed. x * = _ friction; _ speed. y * = _ friction; // update location X + = _ speed. x; y + = _ speed. Y ;}}}

Mainpage. XAML as a container

 
<Usercontrol X: class = "mouseavoider. mainpage "xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "xmlns: D =" http://schemas.microsoft.com/expression/blend/2008 "xmlns: MC =" http://schemas.openxmlformats.org/markup-compatibility/2006 "MC: ignorable =" D "D: designheight = "300" D: designwidth = "400"> <canvas X: name = "stage" width = "400" Height = "300" background = "black"> </canvas> </usercontrol>

Backend code:

Using system; using system. windows; using system. windows. controls; using system. windows. input; using system. windows. media; using system. windows. media. effects; namespace mouseavoider {public partial class mainpage: usercontrol {point _ mouseposition = new point (0, 0); Public mainpage () {initializecomponent (); this. loaded + = new routedeventhandler (mainpage_loaded);} void mainpage_loaded (Object sender, routedeventargs e) {stage. mousemove + = new mouseeventhandler (stage_mousemove); random RND = new random (); blureffect blur = new blureffect (); For (INT I = 0; I <7; I ++) {mouseavoider _ Avoider = new mouseavoider (); _ Avoider. destinationpoint = new point (stage. width/2-(RND. nextdouble () * 2-1) * 80, stage. height/2-(RND. nextdouble () * 2-1) * 80); stage. children. add (_ Avoider); _ Avoider. effect = blur;} compositiontarget. rendering + = new eventhandler (compositiontarget_rendering);} void compositiontarget_rendering (Object sender, eventargs e) {random RND = new random (); For (INT I = 0; I <stage. children. count; I ++) {mouseavoider _ item = stage. children [I] As mouseavoider; _ item. scale. scalex = _ item. scale. scaley = 1.0 + (RND. nextdouble () * 2-1) * 0.1;} void stage_mousemove (Object sender, mouseeventargs e) {_ mouseposition = E. getposition (this. stage) ;}/// <summary> /// obtain the current mouse position /// </Summary> Public point mouseposition {get {return _ mouseposition ;}}}}


Online Demo

Note: The colortransform method in Silverlight is not found, so it is replaced with white. At the same time, compared with the original flash version, there is no drag-and-Seek effect during motion. Thank you for your help.

Source File Download: http://files.cnblogs.com/yjmyzz/MouseAvoider.rar

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.