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

02.05.2013, 14:36

C# Wie sollte man dieses Objekt am besten bewegen und rotieren?

Die Spielfigur befindet sich in einer Kanone die sich horizontal von links nach rechts und wieder zurück bewegt. Die Kanone soll sich dabei immer zwischen den Koordinaten (100,400) und (900,400) bewegen. Die Spielfigur wird aus der Kanone geschossen sobald man die Taste A drückt. Um den Code übersichtlicher zu halten habe ich die Spielfigur noch nicht eingebaut. Die Spielfigur einzubauen ist ja auch nicht schwer.
Mich würde interessieren, ob meine Lösung des Problems(also die Kanone hin- und herbewegen) gut so ist oder ob es eine bessere Lösung gibt?

Um das Ganze noch etwas interessanter zu machen, rotiert sich die Kanone auch noch um ihren Mittelpunkt, deshalb habe ich die Origin der Kanone geändert. Das Problem beim Rotieren ist nur dass sich die Kanone jedesmal beim Kontakt der äußeren Grenzen(X=100 und X=900) in einem anderen Winkel befindet. Ist es möglich die Kanone so zu rotieren dass sie jedesmal den gleichen Winkel(RotationAngle) an einem bestimmten Punkt hat?
Beispiel:
1.Durchgang:
(100,400): Die Kanone hat hier einen RotationAngle von 0.
Danach bewegt sich die Kanone nach rechts und wieder zurück.
2.Durchgang:
(100,400): Die Kanone ist wieder an ihrem Ursprung angelangt und hat hier auch wieder einen RotationAngle von 0.

Ist sowas kompliziert? Wie macht man das?

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
public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D Kanone;
        Vector2 Kanone_Pos = new Vector2(100, 400);
        Vector2 Kanone_Origin;
        bool KanoneVonLinksNachRechtsBewegen = true;
        float RotationAngle;

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

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

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Kanone = Content.Load<Texture2D>("kanoneoben");
            Kanone_Origin.X = Kanone.Width / 2;
            Kanone_Origin.Y = Kanone.Height / 2;
        }

        protected override void Update(GameTime gameTime)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            RotationAngle += 0.004f * elapsed;
            float circle = MathHelper.Pi * 2;
            RotationAngle = RotationAngle % circle;

            if (KanoneVonLinksNachRechtsBewegen == true)
                Kanone_Pos.X += 0.4f * elapsed;
            else
                Kanone_Pos.X -= 0.4f * elapsed;

            if (Kanone_Pos.X >= 900)
            {
                Kanone_Pos.X = 900;
               KanoneVonLinksNachRechtsBewegen = false;
            }

            if (Kanone_Pos.X <= 100)
            {
                Kanone_Pos.X = 100;
                KanoneVonLinksNachRechtsBewegen = true;
            }

            base.Update(gameTime);
        }

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

            spriteBatch.Begin();
            spriteBatch.Draw(Kanone, Kanone_Pos, null, Color.White, RotationAngle, Kanone_Origin, 1.0f, SpriteEffects.None, 0f);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

2

02.05.2013, 15:58

Das lässt sich mit Math.Atan2 recht elegant lösen:

C#-Quelltext

1
2
3
var delta = Vector2.Normalize(Spieler_Origin - Kanone_Origin);

RotationAngle  = Math.Atan2(delta.Y, delta.X) + MathHelper.PiOverTwo; // oder -MathHelper.PiOverTwo


wie im kommentar steht: plus oder minus MathHelper.PiOverTwo. dann sollte die kanone immer zum spieler zeigen.

3

02.05.2013, 18:34

Ich möchte nicht dass die Kanone dauernd auf ein Ziel gerichtet ist ;)
Die Spielfigur befindet sich in der Kanone. Die Spielfigur ist eigentlich eine Kanonenkugel, die man abfeuern kann. Die Kugel wird in die Richtung abgefeuert in die die Kanone gerade zeigt. Das bekomme ich auch hin. Mein Problem ist dass die Kanone an einem bestimmten Punkt nie im gleichen Winkel(RotationAngle) ist.
Wenn die Kanone am Anfang(Spielstart) am Punkt(100,400) mit einem RotationAngle von 0 beginnt, dann sollte die Kanone wenn sie wieder an diesem Punkt ankommt auch wieder bei RotationAngle = 0 stehen. Die Anzahl der Umdrehungen die die Kanone über diesen Weg zurücklegt ist egal. Ich dachte z.B. an 4 komplette Umdrehungen über diesen Weg. Der Weg geht ja von 100 bis 900 und danach wieder von 900 bis 100. Dann fängt das Ganze wieder von vorne an. Das Ganze hört erst auf wenn der Spieler die Kanonenkugel abschießt.
Wenn das mit den Umdrehungen zu kompliziert wird dann lasse ich es so wie es ist. Ich gehe aber mal davon aus dass das gar nicht so kompliziert ist, oder?

4

03.05.2013, 00:08

Was ist das für ne Kanone, wie die sich da dreht? Ich kanns mir grad nicht vorstellen.
Aber das müsste Dreisatz sen. Teilstrecke / Gesamtstrecke = Teilwinkel / Gesamtwinkel.

ds/s = dw/w
dw = w0 + ds/s * w

w0 Startwinkel

Deine Gesamtstrecke wäre 900 - 100 = 800 Pixel. Bei 4 Umdrehungen hättest du einen Gesamtwinkel von 4 * 360 Grad. Deine Startwinkel soll 0 Grad sein.

dw = 0 + ds/800 * 4 * 360

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dr.hallo« (03.05.2013, 00:15)


TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

03.05.2013, 07:16

Ich glaube jetzt weiß ich, was du meinst versuch es mal so:

C#-Quelltext

1
2
3
4
5
6
7
8
var startVector = new Vector2(100,400);
var endVector = new Vector2(900,400);
var distance = endVector.X - startVector.X;

const float WholeRotation = MathHelper.TwoPi * 4;
var currentPositionX = 350;

var currentRotation = MathHelper.Lerp(0, WholeRotation, (currrentPositionX - startVector.X) / distance);


Wenn du einen Start- end Endpunkt gegeben hast (in diesem Fall mit gleichen Y-Wert). Dann ist das einfach ein Linear interpolierter Wert von minimaler und maximaler Winkel.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »TrommlBomml« (03.05.2013, 07:29)


6

03.05.2013, 11:04

Danke :) Das hat funktioniert.
Ich habe noch zwei kleine Fragen. 0 ist ja hier der Startwinkel. Wenn der Startwinkel aber 180° betragen soll dann müsste ich das ja so machen, oder?

C#-Quelltext

1
currentRotation = MathHelper.Lerp(MathHelper.ToRadians(180), WholeRotation, (Kanone_Pos.X - startVector.X) / distance);


Wie errechnet man den Endwinkel? Den Winkel am Punkt (900,400)? Mit welcher mathematischen Formel geht das?
Ich möchte nur wissen wieviel Grad der Winkel an diesem Punkt hat. Sagen wir mal, der Startwinkel beträgt 0, der Endwinkel soll auch 0 betragen. Wie lang(wieviel Pixel) muss dann die zurückgelegte Strecke bei 4 kompletten Umdrehungen betragen?

7

03.05.2013, 12:41

Der Endwinkel ist der Gesamtwinkel + Startwinkekl.
Wenn Anfangs und Endwinkel 0 Grad sein sollen, beträgt die Gesamtstrecke 800. Die Lösung hast du doch schon da zu stehen. (?)

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

8

03.05.2013, 13:21

Zitat

Ich habe noch zwei kleine Fragen. 0 ist ja hier der Startwinkel. Wenn der Startwinkel aber 180° betragen soll dann müsste ich das ja so machen, oder?


Genau ;)

Zitat

Wie errechnet man den Endwinkel? Den Winkel am Punkt (900,400)? Mit welcher mathematischen Formel geht das?


Gar nicht. Mit der Methode hier kannst du das einfach angeben. Du gibst einen Start- und einen EndWinkel ein.

Zitat

Ich möchte nur wissen wieviel Grad der Winkel an diesem Punkt hat. Sagen wir mal, der Startwinkel beträgt 0, der Endwinkel soll auch 0 betragen. Wie lang(wieviel Pixel) muss dann die zurückgelegte Strecke bei 4 kompletten Umdrehungen betragen?


Du gibst ja minimalen und maximalen Winkel vor. Wenn du den maximalen Winkel auf Grund der Distanz von Start zum Ende haben willst, musst du ein Kriterium angeben, für wie viel Pixel sich deine Kanone wie Weit drehen soll. Eins von beidem, Also Start und EndWinkel oder Rotationswinkel Pro Pixel musst du festlegen. Was möchtest du denn nun?

9

03.05.2013, 16:07

Du gibst ja minimalen und maximalen Winkel vor. Wenn du den maximalen Winkel auf Grund der Distanz von Start zum Ende haben willst, musst du ein Kriterium angeben, für wie viel Pixel sich deine Kanone wie Weit drehen soll. Eins von beidem, Also Start und EndWinkel oder Rotationswinkel Pro Pixel musst du festlegen. Was möchtest du denn nun?

Ich habe es jetzt verstanden ;) Ich hatte vergessen dass man den Endwinkel ja selbst festlegen kann, somit ist das Problem ja gelöst. Mir geht es nur um den Start- und Endwinkel.
Ich werde das Abschießen einer Kugel jetzt mal testen.

Werbeanzeige