手指之舞(三):多点触摸实现并且模拟GestureListener操作

  经过多点探索,实在没有办法,只有重回到silverlight低级触摸事件了。但是对GestureListener还有点依依不舍,毕竟那个操作起来方便。现在没办法,只有自己写,那就模拟一下吧。

现在重写上一篇那个实况方向控制盘。

先把界面做好:

<Ellipse x:Name="innerRound" Width="100" Height="100" VerticalAlignment="Top"
                     HorizontalAlignment="Left" Margin="100,350,0,0" Fill="Red"
                     Stroke="Blue" StrokeThickness="5" >
                <Ellipse.RenderTransform>
                    <TranslateTransform x:Name="innerTran"/>
                </Ellipse.RenderTransform>
            </Ellipse> 
            <TextBlock x:Name="textblock1" Width="150" Height="80" HorizontalAlignment="Left"
                       VerticalAlignment="Top" Text="click Me" FontSize="40" Margin="300,0,0,0"/>
            <TextBlock x:Name="direct" Text="direct" Width="200" Height="100" 
                       HorizontalAlignment="Left"
                       VerticalAlignment="Top"
                       FontSize="40" Margin="250,200,0,0"/>
            <TextBlock x:Name="click" Text="click" Width="150" Height="100" 
                       HorizontalAlignment="Left"
                       VerticalAlignment="Top"
                       FontSize="40" Margin="300,300,0,0"/>


界面就不截图了。和上一篇的界面基本一样,就是颜色不太一样。放置了两个Textblock来作为多点触控测试用。


然后在PageLoaded注册事件:

Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);

但是怎么模拟呢,毕竟这个是基础事件,获取到的是所有的触摸点,并且手指不一定第一次Down的时候就放在那个圆盘里面,可能是Move进去的。所有TouchPoint的Action事件有点难以判断了。而且,我不想用两个手指来控制我这个方向盘。但是,如果第一个进去的手指我又怎么判断它已经离开了这个方向盘呢。Action.Up?这个不行,毕竟可能是Move出去的。

另外,要模拟GestureListener,主要的是要得到的是水平和竖直方向的坐标改变。那么我们只能要先记录下上一个坐标。才能得到坐标的改变。


经过细想:现在制定的规则是:定义一个 Dictionary<int, Point>来保存TouchDevice.Id 和上一个点的Position。那么就可以用这个来判断是否是原来的手指并且可以得到坐标改变值。而且对每一个TouchPoint来判断它的Action是否是Up。如果是Up,那么判断下是否是刚才操作圆盘的手指,是的话就从dictionary里面Remove掉那个手指,只有就能让新的手指进来操作方向盘了。


添加两个成员变量:

        Dictionary<int, Point> ETouchDict = new Dictionary<int, Point>();  

        TranslateTransform tr = new TranslateTransform();



具体代码如下:

void Touch_FrameReported(object sender, TouchFrameEventArgs e)
        {
            TouchPoint primaryTouchPoint = e.GetPrimaryTouchPoint(null);

            // Inhibit mouse promotion
            if (primaryTouchPoint != null && primaryTouchPoint.Action == TouchAction.Down)
                e.SuspendMousePromotionUntilTouchUp();

            TouchPointCollection touchPoints = e.GetTouchPoints(null);
            foreach (var item in touchPoints)
            {
                if (item.Action == TouchAction.Up)
                {
                    if (ETouchDict.ContainsKey(item.TouchDevice.Id))
                    {
                        ETouchDict.Remove(item.TouchDevice.Id);
                        this.innerTran.X = 0;
                        this.innerTran.Y = 0;
                        showDirect();
                    }
                }
                if (item.TouchDevice.DirectlyOver == textblock1) {
                    //Debug.WriteLine("textblock1 is touch!  "  + item.Action.ToString());
                    click.Text = "A";
                    click.Foreground = new SolidColorBrush(
                            Color.FromArgb(255, (byte)rand.Next(256),
                                                (byte)rand.Next(256),
                                                (byte)rand.Next(256)));
                }
                else if (item.TouchDevice.DirectlyOver == innerRound)
                {
                    //Debug.WriteLine("rectangle is touch!  " + item.Action.ToString());
                    EllipseTouchHandle(item);
                }
            }
            
        }

        void EllipseTouchHandle(TouchPoint tp)
        {
            if (ETouchDict.Count() > 0 && !ETouchDict.ContainsKey(tp.TouchDevice.Id) )
            {
                return;
            }
            if (ETouchDict.Count() <= 0)
	        {
                ETouchDict.Add(tp.TouchDevice.Id, tp.Position);
                //Debug.WriteLine("Ellipse is touch!  x:" + tp.Position.X + " Y:" + tp.Position.Y);
	        }
            else
            {
                Point LastPoint = ETouchDict.FirstOrDefault().Value;
                double horX = tp.Position.X - LastPoint.X;
                double verY = tp.Position.Y - LastPoint.Y;
                double x = this.innerTran.X + horX;
                double y = this.innerTran.Y + verY;
                if (x <= -50)
                    this.innerTran.X = -50;
                else if (x >= 50)
                    this.innerTran.X = 50;
                else
                    this.innerTran.X = x;

                if (y <= -50)
                    this.innerTran.Y = -50;
                else if (y >= 50)
                    this.innerTran.Y = 50;
                else
                    this.innerTran.Y = y;
                showDirect();
                //Debug.WriteLine("Ellipse is touch! HorizontalVelocity(X): " + horX.ToString() + " VerticalVelocity(Y):" + verY.ToString());
                ETouchDict.Remove(tp.TouchDevice.Id);
                ETouchDict.Add(tp.TouchDevice.Id, tp.Position);
            }
        }

        void showDirect()
        {
            double x = innerTran.X;
            double y = innerTran.Y;
            if (x <= -15 && x >= -50 && y <= -15 && y >= -50 )
            {
                direct.Text = "左上" + x + "," + y; 
            }
            else if (x >= 15 && x <= 50 && y <= -15 && y >= -50)
            {
                direct.Text = "右上" + x + "," + y;
            }
            else if (x <= -15 && x >= -50 && y >= 15 && y <= 50)
            {
                direct.Text = "左下" + x + "," + y;
            }
            else if (x >= 15 && x <= 50 && y >= 15 && y <= 50)
            {
                direct.Text = "右下" + x + "," + y;
            }
            else if (x <= 15 && x >= -15 && y < 0)
            {
                direct.Text = "上" + x + "," + y;
            }
            else if (x <= 15 && x >= -15 && y > 0)
            {
                direct.Text = "下" + x + "," + y;
            }
            else if (y <= 15 && y >= -15 && x < 0)
            {
                direct.Text = "左" + x + "," + y;
            }
            else if (y <= 15 && y >= -15 && x > 0)
            {
                direct.Text = "右" + x + "," + y;
            }
            else
            {
                direct.Text = "";
            }
        }

这样,就可以多点触控了。而且,无论怎样操作,我的方向盘和那么的所谓的A键,就能发出“命令”了。

结果实在是不好截图。毕竟在真机上调试的。把工程放上来吧。http://115.com/file/c2p3tv39#MultiTouchDemo.zip

你可能感兴趣的:(手指之舞(三):多点触摸实现并且模拟GestureListener操作)