Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

11.11.2013, 17:27

C#, Farseer Wie soll ich hiervon ein Polygon erstellen?

Ich habe ein Sprite das die Form eines Herzens hat. Für dieses Herz habe ich ein Polygon mit Farseer erstellt, jedoch gehe ich davon aus dass ich dabei nicht die richtigen Einstellungen vorgenommen habe oder dass sich ein Polygon für die Form eines Herzens nicht eignet. Denn ich habe Probleme mit der Kollision wenn ein anderes Objekt beide Seiten des Herzens gleichzeitig berührt, wie man hier im Video sieht: Problem mit Kollision
Aus irgendeinem Grund fällt das andere Objekt(Ball) nicht sofort durch das Herz ?(
Berührt ein anderes Objekt jedoch nicht beide Seiten gleichzeitig dann funktioniert es, wie man hier sieht: Kollision funktioniert
Bei diesem Video befindet sich der Ball ein paar Pixel weiter links, deshalb funktioniert die Kollision auf einmal ?(
Warum funktioniert die Kollision nicht richtig wenn ein anderes Objekt beide Seiten des Herzens gleichzeitig berührt?
Würdet ihr das Polygon anders erstellen oder kein Polygon verwenden? Ich verstehe nicht warum es in diesem Fall Probleme mit der Kollision gibt, ich habe den Code bereits mit anderen (eckigeren) Sprites getestet und da hat alles richtig funktioniert.

C#-Quelltext

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        bool Draw_debugView = true;
        World world;
        Body Ball, Heart;
        Texture2D BallSprite, HeartSprite;
        List<Vertices> list = new List<Vertices>();
        Vector2 _origin;
        float _scale;

        DebugViewXNA physicsDebug;
        private Matrix _view;
        private Vector2 _cameraPosition;
        private Vector2 _screenCenter;

        private static float _displayUnitsToSimUnitsRatio = 100f;

        public static Vector2 ToDisplayUnits(Vector2 simUnits)
        {
            return simUnits * _displayUnitsToSimUnitsRatio;
        }

        public bool Heart_OnCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact)
        {
            if (fixtureB.CollisionCategories == Category.Cat15)
                //remove the heart body if the ball touches it
              world.RemoveBody(fixtureA.Body);
            return true;
        }

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            InactiveSleepTime = TimeSpan.FromSeconds(1);
            graphics.IsFullScreen = true;
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            TouchPanel.EnabledGestures = GestureType.Tap;
            _view = Matrix.Identity;
            _cameraPosition = Vector2.Zero;
            _screenCenter = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2f, graphics.GraphicsDevice.Viewport.Height / 2f);
        
            if (world == null)
            {
                world = new World(new Vector2(0, 1));
            }
            else
            {
                world.Clear();
            }

            physicsDebug = new DebugViewXNA(world);
            physicsDebug.DefaultShapeColor = Color.White;
            physicsDebug.SleepingShapeColor = Color.LightGray;
            physicsDebug.LoadContent(GraphicsDevice, Content);

            BallSprite = Content.Load<Texture2D>("ballbig");
            HeartSprite = Content.Load<Texture2D>("heartbig");
            //create the ball
            Ball = BodyFactory.CreateCircle(world, 0.50f, 1.0f);
            Ball.BodyType = BodyType.Dynamic;
            Ball.Position = new Vector2(graphics.GraphicsDevice.Viewport.Width / 200f, graphics.GraphicsDevice.Viewport.Height / 200f-4f);
            Ball.Restitution = 0.5f;
            Ball.LinearVelocity = new Vector2(0, 2.0f);
            Ball.CollisionCategories = Category.Cat15;

            //create the heart
            uint[] data = new uint[HeartSprite.Width * HeartSprite.Height];
            HeartSprite.GetData(data);
            Vertices textureVertices = PolygonTools.CreatePolygon(data, HeartSprite.Width, false);
            Vector2 centroid = -textureVertices.GetCentroid();
            textureVertices.Translate(ref centroid);
            _origin = -centroid;
            textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f);
            list = BayazitDecomposer.ConvexPartition(textureVertices);
            _scale = 1f;
            Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * _scale;
            foreach (Vertices vertices in list)
            {
                vertices.Scale(ref vertScale);
            }

            Heart = BodyFactory.CreateCompoundPolygon(world, list, 1.0f, BodyType.Static);
            Heart.IsSensor = true;
            Heart.Position = new Vector2(4.20f, 2.00f);
            Heart.Rotation = 0f;
            Heart.CollisionCategories = Category.Cat4;
            Heart.OnCollision += Heart_OnCollision;
        }

        protected override void Update(GameTime gameTime)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
            world.Step(Math.Min(elapsed, (1f / 60f)));

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
              spriteBatch.Draw(BallSprite, ConvertUnits.ToDisplayUnits(Ball.Position), null, Color.White, Ball.Rotation, new Vector2(BallSprite.Width / 2.0f, BallSprite.Height / 2.0f), 1f, SpriteEffects.None, 0f);
              spriteBatch.Draw(HeartSprite, ConvertUnits.ToDisplayUnits(Heart.Position), null, Color.White, Heart.Rotation, _origin, _scale, SpriteEffects.None, 0f);          
            spriteBatch.End();

            if (Draw_debugView == true)
            {
              Matrix projection = Matrix.CreateOrthographicOffCenter(0f, graphics.GraphicsDevice.Viewport.Width / _displayUnitsToSimUnitsRatio, graphics.GraphicsDevice.Viewport.Height / _displayUnitsToSimUnitsRatio, 0f, 0f, 1f);
              Matrix view = Matrix.CreateTranslation(new Vector3((_cameraPosition / _displayUnitsToSimUnitsRatio) - (_screenCenter / _displayUnitsToSimUnitsRatio), 0f)) * Matrix.CreateTranslation(new Vector3((_screenCenter / _displayUnitsToSimUnitsRatio), 0f));
              physicsDebug.RenderDebugData(ref projection, ref view);
            }

            base.Draw(gameTime);
        }
    }

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

12.11.2013, 06:38

Polygone müssen konvex sein. Wenn das Objekt konkav ist, so wie ein Herz, brauchst Du mehrere Polygone. Ob PolygonTools das erledigt, weiß ich nicht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

12.11.2013, 18:45

Bedeutet konkav dass ein Sprite nicht eckig ist oder zumindest einen runden Teil hat oder was bedeutet konkav in diesem Fall?
Bei wikipedia steht zwar was konvexe und konkave Linsen sind jedoch das ja nichts hiermit zu tun.

Dreat

Frischling

Beiträge: 86

Wohnort: Heilbronn

  • Private Nachricht senden

4

12.11.2013, 19:31

Konvex nach aussen gebogen ()
Konkav nach innen gebogen )(

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

5

12.11.2013, 19:40

Merksatz den ich mal irgendwo aufgeschnappt hab und seitdem nicht mehr aus dem Kopf bekomme:
"Hatte das Mädchen Sex so wird der Bauch konvex, aber war das Mädchen brav, so bleibt der Bauch konkav"

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

12.11.2013, 20:24

Konvex heißt, dass es keinen Innenwinkel über 180° gibt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

26.11.2013, 12:48

Ich habe das Problem mittlerweile gelöst. Es lag nicht an den Polygonen, sondern nur daran dass ich den Heart-Body während eines Steps gelöscht habe:

C#-Quelltext

1
2
3
4
5
6
7
8
  public bool Heart_OnCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact)
        {
            if (fixtureB.CollisionCategories == Category.Cat15)
               //remove the heart body if the ball touches it
              //ohne folgende Zeile funktioniert es
              world.RemoveBody(fixtureA.Body);
            return true;
        }

Den Body lösche ich nun in der Update Methode, so kommt es nicht zu Problemen.

Werbeanzeige