3

私はWindows Phoneゲームに取り組んでおり、衝突検出を差し引いて泳いでいます。

2 つの XAML オブジェクトが互いに重なり合っているかどうかを検出できる簡単な方法はありますか?

私が知っている唯一の方法は、ゲーム内のすべての衝突可能なオブジェクトの座標を含むリストを作成し、リストをスキャンして衝突があるかどうかを判断することです。

トリガーやビヘイビアなどの優れた XAML 機能をすべて備えているので、もっと簡単な方法があるのではないかと考えました。ただし、検索結果はスリムです。

何か案は?最も単純なのは、私が探しているものです。クレイジーなことは何も必要ありません。プレーヤーがオブジェクトと衝突すると、オブジェクトが消えます。

それが違いを生むかどうかはわかりませんが、私のオブジェクトはすべて画像です。

4

3 に答える 3

3

XAMLオブジェクトとの衝突検出のための組み込みのメカニズムはありません。これは理にかなっています。XAMLはアプリケーションUIを作成するために設計されており、ゲームエンジンではありません。

PhysicsHelperフレームワークを試すことができます。

http://physicshelper.codeplex.com/

これにより、動作を介してXAMLオブジェクトを「物理」オブジェクトに変換できる物理エンジンが追加されます。

  <Ellipse Width="100" Height="100" Fill="Red"
            Canvas.Left="80" Canvas.Top="100">
    <!-- make the engine aware of this element -->
    <i:Interaction.Behaviors>
      <pb:PhysicsObjectBehavior />
    </i:Interaction.Behaviors>
  </Ellipse>

しばらく前に、このフレームワークを簡単に試してみました。

http://www.scottlogic.co.uk/blog/colin/2011/12/a-festive-and-fun-windows-phone-7-maze-game/

なかなか良かったです!

于 2013-02-24T08:11:02.753 に答える
1

So I installed Physics helper but the one that was offered above DOESN'T work with any windows phone build past mango. So I hunted down Physics Helper XAML which is not an install file and has to poor documentation to use it in the foreseeable future.

So I created my own XAML collision detection system. It is pretty simple, does what I need and is fast.

Most importantly though you can edit your canvas in Blend or in the WYSISYG editor and it not break the code.

First I create my nested canvas with the items I would like to be collidable

<Canvas x:Name="Collidables">
            <Image x:Name="star" Width="50" Height="50" Source="images/star.png" Canvas.Left="54" Canvas.Top="-132"/>
            <Image x:Name="star_Copy" Width="50" Height="50" Source="/images/star.png" Canvas.Left="158" Canvas.Top="-190"/>
            <Image x:Name="star_Copy1" Width="50" Height="50" Source="/images/star.png" Canvas.Left="268" Canvas.Top="-260"/>
            <Image x:Name="star_Copy2" Width="50" Height="50" Source="/images/star.png" Canvas.Left="372" Canvas.Top="-322"/>
            <Image x:Name="star_Copy3" Width="50" Height="50" Source="/images/star.png" Canvas.Left="54" Canvas.Top="-390"/>
            <Image x:Name="star_Copy4" Width="50" Height="50" Source="/images/star.png" Canvas.Left="158" Canvas.Top="-448"/>
            <Image x:Name="star_Copy5" Width="50" Height="50" Source="/images/star.png" Canvas.Left="268" Canvas.Top="-518"/>
            <Image x:Name="star_Copy6" Width="50" Height="50" Source="/images/star.png" Canvas.Left="372" Canvas.Top="-580"/>
            <Image x:Name="star_Copy7" Width="50" Height="50" Source="/images/star.png" Canvas.Left="372" Canvas.Top="-798"/>
            <Image x:Name="star_Copy8" Width="50" Height="50" Source="/images/star.png" Canvas.Left="268" Canvas.Top="-882"/>
            <Image x:Name="star_Copy9" Width="50" Height="50" Source="/images/star.png" Canvas.Left="158" Canvas.Top="-982"/>
            <Image x:Name="star_Copy10" Width="50" Height="50" Source="/images/star.png" Canvas.Left="54" Canvas.Top="-1060"/>
</canvas>

Then you can go to the code behind to do the rest ##NOTE THAT EVERY ITEM IS NAMED UNIQUELY##

Within the game loop I have the following methods declared to check for collision detection

 collisionChecks();
 handleCollisions();

So what is happening in the first method is this:

  1. All the elements from the collidable canvas are pulled into a list

  2. To save on checking items that aren't even on the screen I weed them out by saying if the Top of the element is on the screen add it to the collisionEnabled List otherwise forget it.

    public void collisionChecks()
    {            
        List<UIElement> AllCollidables = Collidables.Children.ToList();
        collisionEnabled.Clear();
    
        foreach (UIElement item in AllCollidables)
        {
            if (Canvas.GetTop((Image)item) + canvasShift > 0)
                collisionEnabled.Add(item as Image);
        }
    }
    

Now we can Handle the objects that are eligible for collisions

  1. First foreach loop checks to see if there is a collision between the player and each object that is in the collisionEnabled List.

  2. If there is a collision it gets added to the Collisions to handle list

  3. Once we have all the objects that are actually being collide with we can handle them individually based on their name to determine what to do with them. For example in this code I say if the name contains "star" then have it disappear and soon it will play a sound also. But I could also say if it contains "rocket" then change the player state to flying or what ever.

    public void handleCollisions()
    {
    
        Rect player = new Rect();
        player.X = Canvas.GetLeft(Player);
        player.Y = Canvas.GetTop(Player);
        player.Height = Player.Height;
        player.Width = Player.Width;
    
    
        foreach (Image item in collisionEnabled)
        {
            if (item.Visibility == Visibility.Visible)
            {
                Rect obj = new Rect();
                obj.X = Canvas.GetLeft(item);
                obj.Y = Canvas.GetTop(item) + canvasShift;
                obj.Height = item.Height;
                obj.Width = item.Width;
    
                obj.Intersect(player);
    
                if (!obj.IsEmpty)
                {
                    collisionsToHandle.Add(item);
                }
            }
        }
        foreach (Image item in collisionsToHandle)
        {                
            item.Visibility = Visibility.Collapsed;
    
            if (item.Name.ToLower().Contains("star"))
            {
                score += 100;
            }
        }
        collisionsToHandle.Clear();
        collisionEnabled.Clear();}
    

This isn't the cleanest way to implement a collision detection system but it is the smallest and fastest one I have ever come up with. Hope this helps anyone else interested in simple 2D Collision detection for XAML Objects

于 2013-02-24T21:00:25.280 に答える
0

Physics Helper XAML ( http://physicshelperxaml.codeplex.com ) は、元の Physics Helper ( https://physicshelper.codeplex.com ) を書き直したもので、Blend Behaviors API を介して Silverlight (ブラウザーと WindowsPhone) に使用できると述べています。

新しいものは、元々WinRTの初期バージョンに移植されたので、私が理解しているビヘイビアを使用していません( http://www.spritehand.com/2011/09/physics-helper-xaml-for-metro-winrt.html ?m=1 ) 類似の機能がまだ利用できない場合。ただし、その作成者は、新しいコードベースの方が単純であると考えています (また、ブラウザーと Windows Phone 用に Silverlight に移植することもできます)。

もう 1 つはhttps://xamlphysics.codeplex.comで、Farseer Physics エンジンのラッパーでもあり、Attached Properties を使用して物理プロパティをオブジェクトにアタッチしているようです (これは、私がそのような機能を構築した場合にも使用するパターンです)。

親に重力を設定してそのすべての子に影響を与えるなど、そのようなプロパティをコンテナにも追加できるかどうかはわかりません

于 2015-05-11T08:25:41.777 に答える