IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

fonction de collision


Sujet :

C#

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    786
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 786
    Points : 602
    Points
    602
    Par défaut fonction de collision
    Bonjour,
    j' ai trouve une fonction de collision sur internet...
    Seul probleme je n'arrive pas l'appliquer :s

    ma textbox m'affiche toujours que ca ne "collisionne" pas !

    Comme je suis debutant je poste mon code car j' ai du faire une erreur bete, merci. Si vous voyez une erreur bete a tout hasard...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    <UserControl x:Class="Demolisher.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:uc="clr-namespace:Demolisher"
        mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="500" Cursor="none">
      <Grid x:Name="LayoutRoot" Background="Black" Width="600" Height="500">
            <Canvas x:Name="mainCanvas" Width="600" Height="500">
                <uc:ship x:Name="ship" Width="80" Height="80" Canvas.Left="268" Canvas.Top="164"></uc:ship>
                <TextBlock Height="30" Width="640" x:Name="mytext" Canvas.Top="5" Text="U" Foreground="White" FontSize="12"/>
                <uc:asteroid x:Name="asteroid" Width="80" Height="80" Canvas.Left="145" Canvas.Top="70"></uc:asteroid>
            </Canvas>
        </Grid>
    </UserControl>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    private void CompositionTarget_Rendering(object sender, EventArgs e)
            {
                // lets get pointers to the actual UI elements we care about:
                Path shipShell = ship.FindName("ShipShell") as Path;
                Path pathAsteroid1 = asteroid.FindName("pathAsteroid") as Path;
     
                // check for collisions between ship and objects
                if (CheckCollision(ship, shipShell, asteroid, pathAsteroid1))
                {
                    mytext.Text = "enfin";
                }
                else
                {
                    mytext.Text = "rev pas";
                }
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    <UserControl x:Class="Demolisher.ship"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width="400" Height="300">
        <Canvas x:Name="Ship" Width="50" Height="44" Canvas.Left="0" Canvas.Top="0">
            <Path x:Name="ShipShell" Stretch="Fill" Stroke="#FF000000" Width="50" Height="44" Canvas.Left="1" Canvas.Top="1" Data="M256,82 L241,99 239,129 231,150 206,162 206,176 257,180 311,174 299,155 280,148 273,127 271,98 z">
                <Path.Fill>
                    <RadialGradientBrush>
                        <GradientStop Color="#FFE1D0D0" Offset="0"/>
                        <GradientStop Color="#FF673434" Offset="1"/>
                        <GradientStop Color="#FFE3D8D8" Offset="0.024"/>
                    </RadialGradientBrush>
                </Path.Fill>
            </Path>
            <Ellipse Stroke="#FF000000" Width="10" Height="16" Canvas.Left="20" Canvas.Top="5">
                <Ellipse.Fill>
                    <RadialGradientBrush>
                        <GradientStop Color="#FFA4EADF" Offset="0"/>
                        <GradientStop Color="#FFF6F6EE" Offset="1"/>
                    </RadialGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
     
            <Path Fill="#FF6B3C3C" Stretch="Fill" Stroke="#FF000000" Width="7.333" Height="15" Canvas.Left="21" Canvas.Top="29" Data="M374,203.33333 L371,217.33366 377.33333,217.33366 z"/>
     
            <Ellipse x:Name="ShipThrust" Opacity="0.5" Width="8.5" Height="31" Canvas.Left="20" Canvas.Top="44">
                <Ellipse.Fill>
                    <RadialGradientBrush>
                        <GradientStop Color="#FFE5DC48" Offset="0"/>
                        <GradientStop Color="#FF66C0CB" Offset="1"/>
                    </RadialGradientBrush>
                </Ellipse.Fill>
            </Ellipse>
     
        </Canvas>
    </UserControl>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <UserControl x:Class="Demolisher.asteroid"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width="400" Height="300">
            <UserControl.Resources>
            <Storyboard x:Name="sbRotate" RepeatBehavior="Forever">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="pathAsteroid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
                    <EasingDoubleKeyFrame KeyTime="00:00:04.5000000" Value="360"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
            </UserControl.Resources>
     
            <Canvas x:Name="cnvAsteroid" Background="Transparent" Width="100" Height="97">
                <Path x:Name="pathAsteroid" Fill="#FF444343" Stretch="Fill" Stroke="#FF000000" Width="100" Height="97" Canvas.Left="0" Canvas.Top="0" Data="M251,96 L211,101 212,116 196,124 186,144 193,161 C193,161 206,171 213,174 220,177 223,191 223,191 L243,192 265,179 283,164 285,138 276,112 z" RenderTransformOrigin="0.5,0.5">
                    <Path.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform/>
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </Path.RenderTransform>
     
                </Path>
     
            </Canvas>
     
    </UserControl>

    et la fonction de collision sense marche :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    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);
            }
     
     
     
     
        }
    }

  2. #2
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    786
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 786
    Points : 602
    Points
    602
    Par défaut re
    La test de collision rectangulaire marche.
    Cependant le test de pixel represente par ces lignes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                else
                {
                    List<UIElement> hits = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(pt, controlElem) as List<UIElement>;
                    return (hits.Contains(controlElem));
                }
    ne marche pas, faut-il implementer quelques choses de speciale?

    merci

Discussions similaires

  1. aide pour une fonction collision en bash
    Par dipper dans le forum Linux
    Réponses: 5
    Dernier message: 14/04/2011, 23h21
  2. Fonction pour tester la collision entre deux objets
    Par izissie dans le forum Newton
    Réponses: 1
    Dernier message: 22/09/2010, 20h56
  3. Réponses: 0
    Dernier message: 20/04/2010, 22h22
  4. Modification d'une droite en fonction des collisions
    Par Remizkn dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 26/11/2009, 16h15
  5. Réponses: 1
    Dernier message: 02/06/2008, 11h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo