Pull to refresh

Используем Farseer Physics Engine в Silverlight

Reading time 7 min
Views 1.5K
Сегодня я вам покажу, как можно довольно просто добавить физику в Silverlight-проект. Рассмотрим это на небольшом примере с использованием физического движка Farseer Physics, распространяющегося совершенно бесплатно.

FarseerPhysicsNoBorder430X260.png

До того, как мы приступим к созданию приложения, нам потребуется скачать движок Farseer Physics Silverlight, доступный на Codeplex. В этом примере я буду использовать версию 2.1.3 – самую свежую из доступных. Также нам понадобится Physics Helper, сильно упрощающий добавление физических объектов в проект с Farseer Physics.

Для самой разработки нам потребуются следующие инструменты:



Все DLL-файлы, которые понадобятся для нашего проекта, вы можете скачать одним архивом здесь.

Итак, приступим. Сделаем все за 7 простых шагов.

  1. Открываем Visual Studio и создаем новый Silverlight-проект. У меня он называется SilverlightPhysics:

    image
  2. Копируем 3 нужных DLL-файла в какую-нибудь папку. Теперь нужно подключить эти файлы к проекту. В окне Solution Explorer нажимаем правой кнопкой мыши на папке References и выбираем пункт “Add reference”:

    image

    Выбираем наши файлы на закладке Browse и жмем OK:

    image

    Аналогичным образом добавим System.Windows.Interactivity из Expression Blend 3 SDK. Проверяем:

    image
  3. Открываем файл MainPage.xaml. В этом примере удобнее будет использовать Canvas вместо Grid, поэтому заменим тег <Grid> на <Canvas>. Добавим необходимые объекты с помощью XAML-кода:
    <UserControl <br>  x:Class="SilverlightPhysics.MainPage"  <br>  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   <br>  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  <br>  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  <br>  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   <br>  mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"><br>  <Canvas x:Name="LayoutRoot" Background="Black"><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="215" Canvas.Top="433"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="245" Canvas.Top="433"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="275" Canvas.Top="433"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="305" Canvas.Top="433"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="335" Canvas.Top="433"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="365" Canvas.Top="433"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="230" Canvas.Top="403"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="290" Canvas.Top="283"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="305" Canvas.Top="313"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="275" Canvas.Top="313"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="320" Canvas.Top="343"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="290" Canvas.Top="343"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="260" Canvas.Top="343"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="335" Canvas.Top="373"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="305" Canvas.Top="373"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="275" Canvas.Top="373"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="245" Canvas.Top="373"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="350" Canvas.Top="403"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="320" Canvas.Top="403"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="290" Canvas.Top="403"/><br>    <Rectangle Fill="White" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Left="260" Canvas.Top="403"/><br>    <Rectangle Fill="White" StrokeThickness="2" Height="29" Width="640" Canvas.Left="0" Canvas.Top="475"/><br>    <Ellipse Fill="Red" Stroke="#FFB9B9B9" StrokeThickness="2" Height="25" Width="25" Canvas.Top="173" Canvas.Left="255"/><br>  </Canvas><br></UserControl>
    Если запустить проект на данном этапе, то можно будет увидеть большой прямоугольник для будущей платформы, небольшую пирамидку из белых кубиков и красный шарик. Никакой физики у объектов пока нет:

    image
  4. Добавим два пространства имен для легкого обращения к физическому движку и System.Windows.Interactivity:
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"<br>xmlns:pb="clr-namespace:Spritehand.PhysicsBehaviors;assembly=Spritehand.PhysicsBehaviors"<br>

    Теперь мы должны определить PhysicsController, который можно сделать из любого контейнера XAML. В нашем примере это будет Canvas, так как именно в нем содержатся все нужные нам объекты – кубики и шарик. Для этого в XAML-код Canvas добавляем соответствующий узел поведения (как ужасно это звучит на русском :) ). Там же включим свойство MousePickEnabled, чтобы можно было с помощью мыши перетаскивать любой объект:
    <Canvas x:Name="LayoutRoot" Background="Black"><br>    <i:Interaction.Behaviors><br>      <pb:PhysicsControllerBehavior MousePickEnabled="True"/><br>    </i:Interaction.Behaviors><br>

    Делаем платформу. Сначала нам потребуется добавить закрывающийся тег для самого нижнего прямоугольника. Наша платформа должна быть статичной и никуда не падать, поэтому мы добавим соответствующее свойство IsStatic и установим его значение в True. Код для этого прямоугольника станет выглядеть следующим образом:
    <Rectangle Fill="White" StrokeThickness="2" Height="29" Width="640" Canvas.Left="0" Canvas.Top="475"><br>      <i:Interaction.Behaviors><br>        <pb:PhysicsObjectBehavior IsStatic="True"/><br>      </i:Interaction.Behaviors><br>    </Rectangle>

    Соответствующим образом меняем код для всех маленьких прямоугольников и круга. Только теперь уже свойство IsStatic добавлять не надо, потому что эти объекты должны быть динамичны и подвержены законам физики. Финальный код можно посмотреть в готовом проекте


    Да, данный движок не идеален:

    image

    Зато он бесплатен, довольно прост в использовании и позволяет легко добавить физику даже в игры Xbox 360 (сделанные на XNA).

    Данный пример был достаточно простым. Если проявить фантазию и приложить немного усилий, то можно сделать что-нибудь гораздо более впечатляющее. Например, добавить физику жидкости, взрывы и т.п. Буду ждать ваших проектов ;)
Tags:
Hubs:
+5
Comments 11
Comments Comments 11

Articles