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

08.10.2013, 00:53

C# Farseer funktioniert nicht bei Viewportänderung

Ich habe eine Kamera in mein Projekt eingebaut. Die Spielfigur(Bart Simpson) befindet sich dabei immer in der Mitte des Viewports. Sobald sich nach dem Start des Programms der Viewport ändert bewegt sich das Farseer-Rectangle der Spielfigur auf einmal schneller als das Spielfigur-Sprite. Woran liegt das? Ich verstehe nicht warum das Spielfigur-Sprite und das Farseer-Rectangle der Spielfigur auf einmal verschiedene Positionen haben ?( Wie kann das sein?
Ein weiteres Problem habe ich mit der Mauer. Das Farseer-Rectangle der Mauer bewegt sich sobald der Viewport ändert. Die Mauer soll sich aber immer an der gleichen Position befinden und sich nicht bewegen, auch nicht wenn der Viewport ändert. Warum bewegt sich das Farseer-Rectangle der Mauer obwohl der BodyType auf "Static" steht?

C#-Quelltext

1
 Mauer.BodyType = BodyType.Static;

Warum funktioniert Farseer nicht richtig wenn sich der Viewport ändert?
Im Video erkennt man die Probleme sofort: Video
Projekt zum Download: Projekt
Kompletter Code:

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
public class Game1 : Microsoft.Xna.Framework.Game
    {
       GraphicsDeviceManager graphics;
       SpriteBatch spriteBatch;
       Player player;
       Camera camera;
       Texture2D Background, MauerSprite;
       Vector2 Neuecameraposition;

       public World world;
       Body Mauer;
       bool debugView_Zeichnen = true;
       DebugViewXNA physicsDebug;
       // Simple camera controls
       private Matrix _view;
       private Vector2 _cameraPosition;
       private Vector2 _screenCenter;


       private static float _displayUnitsToSimUnitsRatio = 100f;

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

        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);
            // Initialize camera controls
            _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);

            Background = Content.Load<Texture2D>("backgrsprite");
            Vector2 PlayerStartpos = new Vector2(graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight / 2-200);
            player = new Player(this,PlayerStartpos);
            player.Load(Content);
            Vector2 cameraposition = new Vector2(PlayerStartpos.X - graphics.PreferredBackBufferWidth / 2, PlayerStartpos.Y - graphics.PreferredBackBufferHeight / 2);
            camera = new Camera(cameraposition);

            MauerSprite = Content.Load<Texture2D>("mauerspr");
            Mauer = BodyFactory.CreateRectangle(world, 0.90f, 0.90f, 1.0f);
            Mauer.BodyType = BodyType.Static;
            Mauer.Position = new Vector2(2.0f, 1.5f);
            Mauer.Rotation = 0;
            Mauer.CollisionCategories = Category.Cat10;
        }

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

            Neuecameraposition = new Vector2(ConvertUnits.ToDisplayUnits(player.rectangle.Position.X) - graphics.PreferredBackBufferWidth / 2, ConvertUnits.ToDisplayUnits(player.rectangle.Position.Y) - graphics.PreferredBackBufferHeight / 2);
            if (Neuecameraposition.Y < 0)
                Neuecameraposition.Y = 0;
            if (Neuecameraposition.X < 0)
                Neuecameraposition.X = 0;
            camera.Update(gameTime, Neuecameraposition);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.AnisotropicClamp, DepthStencilState.None, RasterizerState.CullNone, null, camera.GetMatrix());
            spriteBatch.Draw(Background, new Rectangle(graphics.PreferredBackBufferWidth/2, graphics.PreferredBackBufferHeight /2, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight), null, Color.White, 0, new Vector2(Background.Width / 2, Background.Height / 2), SpriteEffects.None, 1f);
            spriteBatch.Draw(MauerSprite, ConvertUnits.ToDisplayUnits(Mauer.Position),
                                             null,
                                             Color.White, Mauer.Rotation, new Vector2(MauerSprite.Width / 2.0f, MauerSprite.Height / 2.0f), 1f,
                                             SpriteEffects.None, 0.5f);
            player.Render(spriteBatch);
            spriteBatch.End();

            if (debugView_Zeichnen == true)
            {
                // calculate the projection and view adjustments for the debug view
                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));
                // draw the debug view
                physicsDebug.RenderDebugData(ref projection, ref view);
            }

            base.Draw(gameTime);
        }
    }

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Camera
    {
        public Vector2 Cameraposition;

        public Camera(Vector2 cameraposition)
        {
            Cameraposition = cameraposition;
        }

        public void Update(GameTime gameTime, Vector2 CamPosition)
        {
            Cameraposition = CamPosition;
        }

        public Matrix GetMatrix()
        {
            return Matrix.CreateTranslation(new Vector3(-Cameraposition, 0));
        }
    }

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
public class Player
    {
        Texture2D Playertex;
        public Vector2 Playerposition;
        private Game1 game1;
        public Body rectangle;

        public Player(Game1 game,Vector2 startposition)
        {
            game1 = game;
            Playerposition = startposition;
        }

        public void Load(ContentManager content)
        {
            Playertex = content.Load<Texture2D>("simpson");
            rectangle = BodyFactory.CreateRectangle(game1.world, 1.0f, 1.0f, 1.0f);
            rectangle.BodyType = BodyType.Dynamic;
            rectangle.Position = new Vector2(Playerposition.X / 100f, Playerposition.Y / 100f);
            rectangle.Rotation = 0;
            rectangle.CollisionCategories = Category.Cat5;
            TouchPanel.EnabledGestures = GestureType.HorizontalDrag | GestureType.VerticalDrag;
        }

        public void Update(GameTime gameTime, float elapsed)
        {
            while (TouchPanel.IsGestureAvailable)
            {
                GestureSample gs = TouchPanel.ReadGesture();
                switch (gs.GestureType)
                {
                    case GestureType.HorizontalDrag:
                        rectangle.Position = new Vector2(rectangle.Position.X + gs.Delta.X/100f, rectangle.Position.Y + gs.Delta.Y/100f);
                        break;
                    case GestureType.VerticalDrag:
                        rectangle.Position = new Vector2(rectangle.Position.X + gs.Delta.X/100f, rectangle.Position.Y + gs.Delta.Y/100f);
                        break;
                }
            }
        }

        public void Render(SpriteBatch batch)
        {
            batch.Draw(Playertex, ConvertUnits.ToDisplayUnits(rectangle.Position),
                                             null,
                                             Color.White, rectangle.Rotation, new Vector2(Playertex.Width / 2.0f, Playertex.Height / 2.0f), 1f,
                                             SpriteEffects.None, 0f);
        }
    }

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

08.10.2013, 07:01

Da Farseer überhaupt keinen Viewport kennt, machst Du wohl eher beim Zeichnen irgendwas verkehrt ;)
Ich würde mal schätzen, dass das Debug-Draw nicht von Deinem Viewport beeinflusst wird, denn wie ich das sehe, bewegt sich die Farseer-Box von Bart gleichförmig weiter nach unten. Das ConvertUnits.ToDisplayUnits macht also wohl was falsch oder Deine Translation im Debug-Draw macht die Änderungen der Kamera rückgängig und damit die Kamera kaputt.
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

08.10.2013, 22:33

Hier noch die Klasse ConvertUnits. Ich kann mir aber nicht vorstellen dass dort das Problem liegt.

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
 /// <summary>
    /// Convert units between display and simulation units.
    /// </summary>
    public static class ConvertUnits
    {
        private static float _displayUnitsToSimUnitsRatio = 100f;
        private static float _simUnitsToDisplayUnitsRatio = 1 / _displayUnitsToSimUnitsRatio;

        public static void SetDisplayUnitToSimUnitRatio(float displayUnitsPerSimUnit)
        {
            _displayUnitsToSimUnitsRatio = displayUnitsPerSimUnit;
            _simUnitsToDisplayUnitsRatio = 1 / displayUnitsPerSimUnit;
        }

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

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

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

        public static void ToDisplayUnits(ref Vector2 simUnits, out Vector2 displayUnits)
        {
            Vector2.Multiply(ref simUnits, _displayUnitsToSimUnitsRatio, out displayUnits);
        }

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

        public static Vector2 ToDisplayUnits(float x, float y)
        {
            return new Vector2(x, y) * _displayUnitsToSimUnitsRatio;
        }

        public static void ToDisplayUnits(float x, float y, out Vector2 displayUnits)
        {
            displayUnits = Vector2.Zero;
            displayUnits.X = x * _displayUnitsToSimUnitsRatio;
            displayUnits.Y = y * _displayUnitsToSimUnitsRatio;
        }

        public static float ToSimUnits(float displayUnits)
        {
            return displayUnits * _simUnitsToDisplayUnitsRatio;
        }

        public static float ToSimUnits(double displayUnits)
        {
            return (float)displayUnits * _simUnitsToDisplayUnitsRatio;
        }

        public static float ToSimUnits(int displayUnits)
        {
            return displayUnits * _simUnitsToDisplayUnitsRatio;
        }

        public static Vector2 ToSimUnits(Vector2 displayUnits)
        {
            return displayUnits * _simUnitsToDisplayUnitsRatio;
        }

        public static Vector3 ToSimUnits(Vector3 displayUnits)
        {
            return displayUnits * _simUnitsToDisplayUnitsRatio;
        }

        public static void ToSimUnits(ref Vector2 displayUnits, out Vector2 simUnits)
        {
            Vector2.Multiply(ref displayUnits, _simUnitsToDisplayUnitsRatio, out simUnits);
        }

        public static Vector2 ToSimUnits(float x, float y)
        {
            return new Vector2(x, y) * _simUnitsToDisplayUnitsRatio;
        }

        public static Vector2 ToSimUnits(double x, double y)
        {
            return new Vector2((float)x, (float)y) * _simUnitsToDisplayUnitsRatio;
        }

        public static void ToSimUnits(float x, float y, out Vector2 simUnits)
        {
            simUnits = Vector2.Zero;
            simUnits.X = x * _simUnitsToDisplayUnitsRatio;
            simUnits.Y = y * _simUnitsToDisplayUnitsRatio;
        }
    }


Ich gehe auch davon aus dass es an der DebugView liegt. Ich habe noch ein neues Video erstellt und da sieht man dass es zum gleichen Zeitpunkt zur Kollision zwischen den beiden Sprites und den beiden Farseer-Rectangles kommt: Video
Ich habe versucht einige Variablen beim DebugView-Zeichnen zu ändern jedoch hat das nichts gebracht. Was sollte ich deiner Meinung nach am DebugView-Zeichnen ändern? Ich habe nämlich keine Ahnung was ich daran ändern soll ?(
Ich hatte z.B. diese Zeile

C#-Quelltext

1
 Matrix view = Matrix.CreateTranslation(new Vector3((_cameraPosition / _displayUnitsToSimUnitsRatio) - (_screenCenter / _displayUnitsToSimUnitsRatio), 0f)) * Matrix.CreateTranslation(new Vector3((_screenCenter / _displayUnitsToSimUnitsRatio), 0f));

durch folgende ersetzt:

C#-Quelltext

1
 Matrix view = Matrix.CreateTranslation(new Vector3((Neuecameraposition / _displayUnitsToSimUnitsRatio) - (_screenCenter / _displayUnitsToSimUnitsRatio), 0f)) * Matrix.CreateTranslation(new Vector3((_screenCenter / _displayUnitsToSimUnitsRatio), 0f));

Jedoch hat das nichts geändert.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

09.10.2013, 06:53

Tja, da wirst Du wohl mal die Werte mit dem Debugger anschauen müssen. Dein Debug-View verschiebt sich jedenfalls nicht, wenn Du die Kamera bewegst. Oder zumindest bewegt er sich nicht passend zur Kamera. Dein "_screencenter" würde ich da wohl auch mal überprüfen. Wie es aussieht ändert sich dessen Position nämlich nie und ist immer nur (height/2, width/2), was natürlich nur in einer ganz bestimmten Situation richtig ist - und zwar dann, wenn die Kamera mit der linken oberen Ecke im Ursprung steht.
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]

5

09.10.2013, 18:29

Ich weiss nicht wann _screenCenter welche Koordinaten haben muss ?( Ich update die Variable nun in der Update Methode jedoch hat sich dadurch nichts geändert :(

C#-Quelltext

1
 _screenCenter = new Vector2(Neuecameraposition.X + graphics.PreferredBackBufferWidth / 2, Neuecameraposition.Y + graphics.PreferredBackBufferHeight / 2);

Und bei view benutze ich nun die Variable Neuecameraposition:

C#-Quelltext

1
 Matrix view = Matrix.CreateTranslation(new Vector3((Neuecameraposition / _displayUnitsToSimUnitsRatio) - (_screenCenter / _displayUnitsToSimUnitsRatio), 0f)) * Matrix.CreateTranslation(new Vector3((_screenCenter / _displayUnitsToSimUnitsRatio), 0f));

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

09.10.2013, 20:12

Rechne jetzt halt einfach endlich mal nach und schau Dir die Werte mit dem Debugger an. Es sieht jedenfalls reichlich falsch aus. Die Skalierungen der Summanden/Subtrahenden passen doch auch vorn und hinten 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]

7

12.10.2013, 23:57

Ich habe das Problem nun gelöst und zeichne alles so:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if (debugView_Zeichnen == true)
{
Matrix projection, view;

float width = 1f * ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Width);
float height = -1f * ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Height);
float zNearPlane = 0f;
float zFarPlane = 1000000f;
projection = Matrix.CreateOrthographic(width, height, zNearPlane, zFarPlane);

float xTranslation = -1 * ConvertUnits.ToSimUnits(camera.Cameraposition.X + graphics.PreferredBackBufferWidth / 2);
float yTranslation = -1 * ConvertUnits.ToSimUnits(camera.Cameraposition.Y+ graphics.PreferredBackBufferHeight / 2);
Vector3 translationVector = new Vector3(xTranslation, yTranslation, 0f);
view = Matrix.Identity;
view.Translation = translationVector;

physicsDebug.RenderDebugData(ref projection, ref view);
}

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

16.10.2013, 15:51

Tipp:
Statt -1 * x kannst du auch einfach -x schreiben.

Werbeanzeige