Silverlight Pixel完美碰撞检测

时间:2013-04-02 13:16:55

标签: silverlight collision-detection pixel-perfect

我正在为我的Uni开展一个项目,目前我正在通过这个网站http://www.andybeaulieu.com/Home/tabid/67/EntryID/160/Default.aspx进行Pixel Perfect Collision Detection。我已经下载了使用此collsion检测的示例项目,即使使用我自己的图片也能正常工作。我在我的项目中做了同样的事情,但它无法正常工作。这是我的应用程序的链接:https://www.cubby.com/pl/LostInTheMath.zip/_dd23e2c827604c068a3fe63ff42d22b2任何人都可以告诉我它有什么问题吗?谢谢。

这是主要代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace LostInTheMath
   {
public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(Page_Loaded);
    }
    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
    }

    private void UserCntrl_MouseMove(object sender, MouseEventArgs e)
    {
        Point pt = e.GetPosition(cnvHitTest);

        Monkey.SetValue(Canvas.LeftProperty, pt.X);
        Monkey.SetValue(Canvas.TopProperty, pt.Y);

    }

    void CompositionTarget_Rendering(object sender, EventArgs e)
    {
        Image MonkeyShell = Monkey.FindName("imgMonkey") as Image;
        Image Mazer = Maze.FindName("imgMaze") as Image;

        if (CheckCollision(Monkey, MonkeyShell, Maze, Mazer))
        {
            Monkey.Width = 1000;
            txtStatus.Text = "Collision with XAML Element!";
            return;
        }
        txtStatus.Text = string.Empty;
    }

   private bool CheckCollision(FrameworkElement control1, FrameworkElement controlElem1, FrameworkElement control2, FrameworkElement controlElem2)
     {
         // first see if sprite rectangles collide
         Rect rect1 = UserControlBounds(control1);
         Rect rect2 = UserControlBounds(control2);

         rect1.Intersect(rect2);
         if (rect1 == Rect.Empty)
         {
             // no collision - GET OUT!
             return false;
         }
         else
         {
             bool bCollision = false;
             Point ptCheck = new Point();

             // NOTE that creating the writeablebitmap is a bit intense
             // so we will do this once and store results in Tag property
             // in a real game, you might abstract this into a Sprite class.
             if (controlElem1 is Image)
                 controlElem1.Tag = GetWriteableBitmap(control1);

             if (controlElem2 is Image)
                 controlElem2.Tag = GetWriteableBitmap(control2);

             // now we do a more accurate pixel hit test
             for (int x = Convert.ToInt32(rect1.X); x < Convert.ToInt32(rect1.X + rect1.Width); x++)
             {
                 for (int y = Convert.ToInt32(rect1.Y); y < Convert.ToInt32(rect1.Y + rect1.Height); y++)
                 {
                     ptCheck.X = x;
                     ptCheck.Y = y;


                     if (CheckCollisionPoint(ptCheck, control1, controlElem1))
                         if (CheckCollisionPoint(ptCheck, control2, controlElem2))
                         {
                             bCollision = true;
                             break;
                         }

                 }
                 if (bCollision) break;
             }
             return bCollision;
         }
     }

     public bool CheckCollisionPoint(Point pt, FrameworkElement control, FrameworkElement controlElem)
     {
         if (controlElem is Image)
         {
             // NOTE that we saved the WB in the Tag object for performance.
             // in a real app, you might abstract this in your sprite class.
             WriteableBitmap wb = controlElem.Tag as WriteableBitmap;

             int width = wb.PixelWidth;
             int height = wb.PixelHeight;

             double offSetX = Convert.ToDouble(control.GetValue(Canvas.LeftProperty));
             double offSetY = Convert.ToDouble(control.GetValue(Canvas.TopProperty));

             pt.X = pt.X - offSetX;
             pt.Y = pt.Y - offSetY;

             int offset = Convert.ToInt32((width * pt.Y) + pt.X);

             return (wb.Pixels[offset] != 0);
         }
         else
         {
             List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(pt, controlElem) as List<UIElement>;
             return (hits.Contains(controlElem));
         }
     }

     private WriteableBitmap GetWriteableBitmap(FrameworkElement control)
     {
         WriteableBitmap wb = new WriteableBitmap((int)control.Width, (int)control.Height); ;
         wb.Render(control, new TranslateTransform());
         wb.Invalidate();

         return wb;
     }

     public Rect UserControlBounds(FrameworkElement control)
     {
         Point ptTopLeft = new Point(Convert.ToDouble(control.GetValue(Canvas.LeftProperty)), Convert.ToDouble(control.GetValue(Canvas.TopProperty)));
         Point ptBottomRight = new Point(Convert.ToDouble(control.GetValue(Canvas.LeftProperty)) + control.Width, Convert.ToDouble(control.GetValue(Canvas.TopProperty)) + control.Height);

         return new Rect(ptTopLeft, ptBottomRight);
     }



 }
}

0 个答案:

没有答案