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

14.05.2013, 12:42

C# Springender Ball in Farseer

Ich habe einen Ball erstellt der mit ein paar Plattformen kollidiert und dabei realistisch springen soll. Bis jetzt funktioniert auch alles, jedoch möchte ich die Simulation noch verbessern. Es kann ja z.B. mal passieren dass der Ball zwei Plattformen gleichzeitig berührt, was muss ich an meinem Code ändern damit in diesem Fall keine sonderbare Ballbewegung entsteht? Die einfachste Lösung wäre sicherlich dafür zu sorgen dass dieser Fall erst gar nicht eintreten kann. Wie würde man denn vorgehen falls dieser Fall doch eintreten könnte?

Außerdem weiss ich nicht wie ich die Startgeschwindigkeit des Balls ändere ?( Wenn der Ball z.B. geworfen wird, dann ist die Startgeschwindigkeit ja deutlich höher. Ich habe versucht die Startgeschwindigkeit mit ApplyForce zu ändern, jedoch hat das nichts gebracht :(
Wie ändert man die Startgeschwindigkeit am einfachsten?

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
  public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        World world;
        Body rectangle, rectangle2, rectangle3, rectangle4, rectangle5, ballcircle;
        Texture2D rectangleSprite, BallSprite;

        private static float _displayUnitsToSimUnitsRatio = 100f;

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

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

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

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            BallSprite = Content.Load<Texture2D>("ball");
            rectangleSprite = Content.Load<Texture2D>("tile");

            if (world == null)
            {
                world = new World(new Vector2(0, 1));
            }
            else
            {
                world.Clear();
            }

            ballcircle = BodyFactory.CreateCircle(world, 0.25f, 1.0f);
            ballcircle.BodyType = BodyType.Dynamic;
            ballcircle.Position = new Vector2(2.76f, 0f);
            ballcircle.AngularDamping = 0.4f;
            ballcircle.Restitution = 0.5f;

            rectangle = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
            rectangle.BodyType = BodyType.Static;
            rectangle.Position = new Vector2(2.96f, 1.16f);
            rectangle.Rotation = -0.3f;
            rectangle.CollisionCategories = Category.Cat5;

            rectangle2 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
            rectangle2.BodyType = BodyType.Static;
            rectangle2.Position = new Vector2(1.0f, 1.80f);
            rectangle2.Rotation = 1.0f;
            rectangle2.CollisionCategories = Category.Cat5;

            rectangle3 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
            rectangle3.BodyType = BodyType.Static;
            rectangle3.Position = new Vector2(5.1f, 4.80f);
            rectangle3.CollisionCategories = Category.Cat5;

            rectangle4 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
            rectangle4.BodyType = BodyType.Static;
            rectangle4.Position = new Vector2(3.6f, 4.80f);
            rectangle4.CollisionCategories = Category.Cat5;

            rectangle5 = BodyFactory.CreateRectangle(world, 1.50f, 0.50f, 1.0f);
            rectangle5.BodyType = BodyType.Static;
            rectangle5.Position = new Vector2(6.6f, 4.80f);
            rectangle5.CollisionCategories = Category.Cat5;
        }
        
        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(ballcircle.Position),
                                           null,
                                           Color.White, ballcircle.Rotation, new Vector2(BallSprite.Width / 2.0f, BallSprite.Height / 2.0f), 1.0f,
                                           SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle.Position),
                                            null,
                                            Color.White, rectangle.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle2.Position),
                                            null,
                                            Color.White, rectangle2.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle3.Position),
                                            null,
                                            Color.White, rectangle3.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);

            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle4.Position),
                                            null,
                                            Color.White, rectangle4.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                            SpriteEffects.None, 0f);
            spriteBatch.Draw(rectangleSprite, ConvertUnits.ToDisplayUnits(rectangle5.Position),
                                           null,
                                           Color.White, rectangle5.Rotation, new Vector2(rectangleSprite.Width / 2.0f, rectangleSprite.Height / 2.0f), 1f,
                                           SpriteEffects.None, 0f);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

14.05.2013, 12:55

Es kann ja z.B. mal passieren dass der Ball zwei Plattformen gleichzeitig berührt, was muss ich an meinem Code ändern damit in diesem Fall keine sonderbare Ballbewegung entsteht?
Ich kann mir gerade nicht vorstellen, was das bedeuten soll.
Vielleicht erklärst Du nochmal überhaupt, was Dein Spiel tut, das steht nämlich nirgends und ohne dieses Wissen ist total unklar, was genau Dein Problem überhaupt sein soll. Vielleicht hilft auch eine Skizze oder ein Screenshot.

Eine Startgeschwindigkeit kannst Du wohl einfachsten über setLinearVelocity() setzen.
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

14.05.2013, 13:14

http://s7.directupload.net/file/d/3255/ljcaelil_png.htm
Das rote und das blaue Quadrat sind zwei Plattformen. Der grüne Kreis ist der Ball. Was würde passieren wenn es jetzt zu der Kollision kommt wie sie auf dem Bild dargestellt ist? Würde der Ball dann noch immer richtig vom Boden abprallen oder könnte es vorkommen dass der Ball seltsam abprallt da er die rote und blaue Plattform gleichzeitig berührt?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Big_Santa« (14.05.2013, 13:36)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

14.05.2013, 13:37

Er würde ganz normal wie zu erwarten von einer flachen Fläche abprallen. Genau genommen kann der Ball theoretisch auch nur genau eine Fläche berühren, weil ein Kreis nur einen Kontakt-Punkt mit einer Fläche haben kann - auch wenn zwei Schnittpunkte gehen. Ich würde jedenfalls kein merkwürdiges Verhalten erwarten und habe bei Box2D in solchen Fällen bisher auch keins feststellen können.
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]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (14.05.2013, 13:47)


5

14.05.2013, 14:03

Ich nutze ebenfalls Farseer ..jedoch mit Blitzmax...Um die Geschwindigkeit Deines Balls zu verändern kannst Du SetLinearVelocity oder ApplyForce verwenden,
wobei ApplyForce permanent aufgerufen werden muss..mit einem einmaligen Aufruf ist es nicht getan ( jedenfalls ist es so in BMax)
Die besten Grüsse

Thomas

Mutant3D Basic
www.tcspiele.de

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

14.05.2013, 14:06

Du kannst auch mit ApplyForce einmalig einen Effekt erzeugen. Aber die Kraft muss entsprechend groß sein, wenn sie nur für einen kleinen Zeitraum einwirkt. Impulse oder direkt festlegen sind eher der gangbare Weg.
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]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (14.05.2013, 14:18)


7

14.05.2013, 14:19

Du kannst auch mit ApplyForce einmalig einen Effekt erzeugen. Aber die Kraft muss entsprechend groß sein, wenn sie nur für einen kleinen Zeitraum einwirkt. Impulse oder direkt festlegen sind eher der gangbare Weg.


so ist es.. 8)
Die besten Grüsse

Thomas

Mutant3D Basic
www.tcspiele.de

8

14.05.2013, 14:20

Er würde ganz normal wie zu erwarten von einer flachen Fläche abprallen. Genau genommen kann der Ball theoretisch auch nur genau eine Fläche berühren, weil ein Kreis nur einen Kontakt-Punkt mit einer Fläche haben kann - auch wenn zwei Schnittpunkte gehen. Ich würde jedenfalls kein merkwürdiges Verhalten erwarten und habe bei Box2D in solchen Fällen bisher auch keins feststellen können.

Gilt das gleiche denn auch für andere geometrische Formen wie z.B. Rechtecke? Also, würden die auch richtig abprallen?

Ich habe noch eine kleine Frage zur Masse. Ich habe bis jetzt noch nie die Masse geändert. Wenn ich möchte dass der Ball anders springt, sollte ich dann die Masse des Balles ändern oder muss ich auch die Masse der Plattformen ändern mit denen der Ball kollidiert?

9

14.05.2013, 14:28

Er würde ganz normal wie zu erwarten von einer flachen Fläche abprallen. Genau genommen kann der Ball theoretisch auch nur genau eine Fläche berühren, weil ein Kreis nur einen Kontakt-Punkt mit einer Fläche haben kann - auch wenn zwei Schnittpunkte gehen. Ich würde jedenfalls kein merkwürdiges Verhalten erwarten und habe bei Box2D in solchen Fällen bisher auch keins feststellen können.

Gilt das gleiche denn auch für andere geometrische Formen wie z.B. Rechtecke? Also, würden die auch richtig abprallen?

Ich habe noch eine kleine Frage zur Masse. Ich habe bis jetzt noch nie die Masse geändert. Wenn ich möchte dass der Ball anders springt, sollte ich dann die Masse des Balles ändern oder muss ich auch die Masse der Plattformen ändern mit denen der Ball kollidiert?


Mittels SetRestitutionCoefficient / SetFrictionCoefficient kannst Du ebenfalls das (Sprung)Verhalten des Balls verändern
Die besten Grüsse

Thomas

Mutant3D Basic
www.tcspiele.de

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »tomgames« (14.05.2013, 14:35)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

14.05.2013, 14:31

Das hat mit der Masse relativ wenig zu tun. Wichtig ist dabei die Restitution beider Kollisions-Partner. Beide auf 1.0 heißt perfekte Reflektion ohne Verluste. 0.0 heißt vollständig inelastisch (wie Sandsack auf Sand). Alles dazwischen ist folglich der Zwischenwert. Es wird die kleinste Zahl beider Partner verwendet, kein Produkt der beiden oder sowas!
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]

Werbeanzeige