使用Silverlight制作简单的小游戏—Jewellery (Part 3)

上一篇:使用Silverlight制作简单的小游戏—Jewellery (Part 2)

 

实现Jewel类。Jewel类是继承于虚类JewelBase的,让我们先来看一下当前JewelBase的定义。

    public abstract class JewelBase

    {

        #region Properties



        public double Width { get; set; }

        public double Height { get; set; }

        public int IndexX { get; set; }

        public int IndexY { get; set; }

        public int Kind { get; set; }



        #endregion



        public event EventHandler Click;



        #region Abstract Methods



        public abstract void Initialize(Canvas panel);



        public abstract void MoveTo(int x, int y);



        public abstract void Destroy();



        #endregion

    }

动画过程用Storyboard来实现,在每次动画结束后,通知JewelEvent类。改进一下JewelBase中的abstract方法,如下:

        public virtual void MoveTo(int x, int y)

        {

            Storyboard board = this.GetMoveAnimation(x, y);

            board.Completed += new EventHandler(moveBoard_Completed);

            board.Begin();

        }



        private void moveBoard_Completed(object sender, EventArgs e)

        {

            JewelEvent.Add(JewelEventNames.Moved, this);  // move finish

        }



        public virtual void Destroy()

        {

            Storyboard board = this.GetDestroyAnimation();

            board.Completed += new EventHandler(destroyBoard_Completed);

            board.Begin();

        }



        private void destroyBoard_Completed(object sender, EventArgs e)

        {

            JewelEvent.Add(JewelEventNames.Destroy, this);  // destroy finish

        }



        #region Abstract Methods



        public abstract void Initialize(Canvas panel);



        protected abstract Storyboard GetMoveAnimation(int x, int y);



        protected abstract Storyboard GetDestroyAnimation();



        #endregion

好了,接下来就是在Jewel中实现这3个abstract方法。

这里使用SL中的Image显示图片,在Initialize方法中,主要是初始化Image的位置、大小,以及根据Kind选择图片源,并绑定Image的MouseLeftButtonDown事件,转化为JewelBase的Click事件,这样Jewel就可以响应用户的点击事件了。对于Jewel的Size,这里使用ScaleTransform来控制,所以要在Initialize中恢复Jewel的Size。

        public override void Initialize(Canvas canvas)

        {

            if (this.image == null)

            {

                this.image = new Image();

                this.image.Width = this.Width;

                this.image.Height = this.Height;



	        // use ScaleTransform to control Jewel's size

                this.image.RenderTransform = new ScaleTransform()

                {

                    CenterX = this.Width / 2,

                    CenterY = this.Height / 2,

                    ScaleX = 1.0,

                    ScaleY = 1.0

                };

                this.image.MouseLeftButtonDown += new MouseButtonEventHandler(rect_MouseLeftButtonDown);



                canvas.Children.Add(this.image);

            }



            Canvas.SetLeft(this.image, this.IndexX * this.Width);

            Canvas.SetTop(this.image, this.IndexY * this.Height);

            

            // reset

            ScaleTransform st = (ScaleTransform)this.image.RenderTransform;

            st.ScaleX = 1.0;

            st.ScaleY = 1.0;



            switch (this.Kind)

            {

                // set Image.Source

            }

        }

GetMoveAnimation方法和GetDestroyAnimation方法类似,就是构建并返回一个Storyboard实例。看下代码就好了。:)

        #region GetMoveAnimation Method



        protected override Storyboard GetMoveAnimation(int x, int y)

        {

            Storyboard board = new Storyboard();



            DoubleAnimation animation = new DoubleAnimation()

            {

                From = Canvas.GetLeft(this.image),

                To = x * this.Width,

                Duration = new Duration(TimeSpan.FromMilliseconds(speed))

            };

            Storyboard.SetTarget(animation, this.image);

            Storyboard.SetTargetProperty(animation, new PropertyPath("(Canvas.Left)"));

            board.Children.Add(animation);



            animation = new DoubleAnimation()

            {

                From = Canvas.GetTop(this.image),

                To = y * this.Height,

                Duration = new Duration(TimeSpan.FromMilliseconds(speed))

            };

            Storyboard.SetTarget(animation, this.image);

            Storyboard.SetTargetProperty(animation, new PropertyPath("(Canvas.Top)"));

            board.Children.Add(animation);



            return board;

        }



        #endregion



        #region GetDestroyAnimation Method



        protected override Storyboard GetDestroyAnimation()

        {

            Storyboard board = new Storyboard();



            DoubleAnimation animation = new DoubleAnimation()

            {

                From = 1.0,

                To = 0.0,

                Duration = new Duration(TimeSpan.FromMilliseconds(moveSpeed))

            };

            Storyboard.SetTarget(animation, this.image.RenderTransform);

            Storyboard.SetTargetProperty(animation, new PropertyPath("(ScaleX)"));

            board.Children.Add(animation);



            animation = new DoubleAnimation()

            {

                From = 1.0,

                To = 0.0,

                Duration = new Duration(TimeSpan.FromMilliseconds(moveSpeed))

            };

            Storyboard.SetTarget(animation, this.image.RenderTransform);

            Storyboard.SetTargetProperty(animation, new PropertyPath("(ScaleY)"));

            board.Children.Add(animation);



            return board;

        }



        #endregion

这就是整个Jewel类,再运行一下程序,我们会看到一个布满Jewel的Canvas,并且已经可以运行了。不过,这里还差一个部分要说,就是实现IJewelSelector接口,使得用户在点击Jewel时,可以看到一个闪烁的外框。这里利用动态变化的虚线框,来实现一个被选择的效果。在Selected方法中显示,在Unselected中隐藏。这里只贴出来动画的实现,具体的实现请看本文最后附加的源代码。

this.selectedLine = new Rectangle();

this.selectedLine.StrokeThickness = 2;

this.selectedLine.Stroke = new SolidColorBrush(Colors.Orange);

DoubleCollection dc = new DoubleCollection() { 1, 2 };

this.selectedLine.StrokeDashArray = dc;

this.selectedLine.StrokeDashOffset = 0;

this.selectedLine.StrokeDashCap = PenLineCap.Round;



canvas.Children.Add(this.selectedLine);



                // set animation

Storyboard board = new Storyboard();



DoubleAnimation animation = new DoubleAnimation()

{

    From = 0,

    To = 3,

    Duration = new Duration(TimeSpan.FromMilliseconds(300)),

    RepeatBehavior = RepeatBehavior.Forever,

};

Storyboard.SetTarget(animation, this.selectedLine);

Storyboard.SetTargetProperty(animation, new PropertyPath("(StrokeDashOffset)"));

board.Children.Add(animation);



board.Begin();

完结。

 

源代码:Jewellery.zip

你可能感兴趣的:(silverlight)