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

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

11

22.04.2014, 21:37

Ich komme bei der gleichen Berechnung wie du auf die gleichen Werte.
Winkel: 45°
Start-Position (0;0)
Position nach einem Frame: (70,7107;-70,7107)
Zeit-Variable: 1

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

12

22.04.2014, 21:47

Ich finds angenehmer direkt mit einem Richtungsvektor zu arbeiten.

C-/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
struct vec2{
    float x, y;
    
    void rotate(float deg){
        x = cosf(deg)*x-sinf(deg)*y;
        y = sinf(deg)*x+cosf(deg)*y;
    }
};

class Panzer{
    private:
        vec2 direction;
        
    public:
        Panzer(){
            direction.x = 1;
            direction.y = 0;
        }
        
        void onA(float deltaTime){
            direction.rotate(10*deltaTime);
        }
        
        void onD(float deltaTime){
            direction.rotate(-10*deltaTime);
        }
};


Oder so in der Richtung...

[Edit]

Hier du könntest auch eine Rotationsmatrix direkt aufsetzen.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (22.04.2014, 21:53)


13

22.04.2014, 22:31

Wenn du auf die selben Werte kommst, musst du das in deinem Fall mal probieren und debuggen.

Verwende mal feste sin/cos-Werte (sin(45°) = sqrtf(2.0f)/2.0f)), oder sogar feste diff-Werte. Ich vermute, dass das Problem eher bei einer fehlerhaften Zuweisung bei SFML liegt, als bei irgend einer mathematischen Berechnung.

C-/C++-Quelltext

1
2
x += PLAYER_SPEED * (sqrtf(2.0f)*0.5f) * dt;
y += PLAYER_SPEED * (-sqrtf(2.0f)*0.5f) * dt;
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

14

23.04.2014, 03:42

Zitat

Ich vermute, dass das Problem eher bei einer fehlerhaften Zuweisung bei SFML liegt, als bei irgend einer mathematischen Berechnung.

Klar, die Engine ist Schuld....

Folgenden Code eben noch getestet, funktioniert wunderbar. Ziemlich ähnlich mit deinem wenn du dir die komplette Version anguckst...

C-/C++-Quelltext

1
2
3
4
5
6
7
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
        {
            sf::Vector2f v(100.f*step.asSeconds(), 100.f*step.asSeconds());
            float alpha=(((PlayerSprite.getRotation()+45)*3.1415926535897f)/180.f);
            PlayerSprite.setPosition(PlayerSprite.getPosition()+sf::Vector2f(v.x*std::cos(alpha) - v.y*std::sin(alpha),
                                                             v.x*std::sin(alpha) + v.y*std::cos(alpha)));
        }
...die hier zu erreichen ist.

@Swoerm: Warum benutzt du math.h, benutzt #defines für Konstanten, deklarierst Variablen viel zu früh? ;(

C-/C++-Quelltext

1
PlayerSprite.setOrigin (PlayerSprite.getPosition().x+PlayerSprite.getTexture()->getSize().x/2, PlayerSprite.getPosition().y+PlayerSprite.getTexture()->getSize().y/2);

Was soll die Zeile denn machen? Der Origin ist ein lokaler Punkt des Objekts, der nicht von den globalen Koordinaten abhängig ist. Die Zeile gehört in die "'WTF' Codeschnipsel". :P Das geht hier nur gut, weil die Position des Spielers zu diesem Zeitpunkt (0|0) ist, kann aber schnell ins Auge gehen.

C-/C++-Quelltext

1
PlayerSprite.setOrigin(PlayerSprite.getTexture()->getSIze()/2.f);


MfG
Check

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

15

23.04.2014, 14:36

@Swoerm: Warum benutzt du math.h, benutzt #defines für Konstanten, deklarierst Variablen viel zu früh?
1. Ich habe gegoogelt wie man den exakten Wert von PI verwenden kann und kam in ein andres Forum wo math.h verwendet wurde. Dies funktioniert allerdings nur wenn ich das #define _USE_MATH_DEFINES definiere.
2. Was ist an #defines für Konstanten so schlimm? Dafür sind sie doch da, oder?
3. Wie meinst du, dass Variablen zu früh deklarieren?

Den Code mit .setOrigin hatte ich aus einem Tut und hab in mir da er wunderbar funktionierte nicht näher angeschaut. :pinch:

Folgenden Code eben noch getestet, funktioniert wunderbar. Ziemlich ähnlich mit deinem wenn du dir die komplette Version anguckst...
Dieser Code bewirkt bei mir gar nichts. Der Spieler bewegt sich kein Stück. Allerdings weiß ich nicht genau was du mit step.asSeconds() meinst.

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

16

23.04.2014, 14:45

1. Ich habe gegoogelt wie man den exakten Wert von PI verwenden kann und kam in ein andres Forum wo math.h verwendet wurde. Dies funktioniert allerdings nur wenn ich das #define _USE_MATH_DEFINES definiere.
math.h ist C. In C++ inkludiert man cmath.

2. Was ist an #defines für Konstanten so schlimm? Dafür sind sie doch da, oder?
Nein. Sie sind für Makros da und für Präprozessor-Anweisungen. Für Konstanten gibt es "const". Define kennt keinen Datentyp. Const schon.

3. Wie meinst du, dass Variablen zu früh deklarieren?
Deklaration mehrere Zeilen vor ihrer konkreten Verwendung oder Initialisierung. Unnötig. Schwer zu lesen.
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]

17

23.04.2014, 15:32

Ich habe soeben exakt deinen Code genommen und etwas dran rumgespielt. Wenn du folgende Zeilen änderst, funktioniert es bei mir wie gewünscht:

C-/C++-Quelltext

1
2
3
4
5
PlayerSprite.setOrigin (PlayerSprite.getPosition().x+PlayerSprite.getTexture()->getSize().x/2, PlayerSprite.getPosition().y+PlayerSprite.getTexture()->getSize().y/2);

// zu:

PlayerSprite.setOrigin(PlayerImage.getSize().x * 0.5f, PlayerImage.getSize().y * 0.5f);


und

C-/C++-Quelltext

1
2
3
4
5
6
7
x += static_cast<float> ((PLAYER_SPEED * cos ( PlayerSprite.getRotation() * (M_PI / 180) )) * dt);
y += static_cast<float> ((PLAYER_SPEED * -sin ( PlayerSprite.getRotation() * (M_PI / 180) )) * dt);

// zu:

x += static_cast<float> ((PLAYER_SPEED * cos((PlayerSprite.getRotation() - 90.0f) * (M_PI / 180))) * dt);
y += static_cast<float> ((PLAYER_SPEED * sin((PlayerSprite.getRotation() - 90.0f) * (M_PI / 180))) * dt);


Erklärung zu letzterem:
Aus den Polarkoordinaten: x = r*cos(theta) und y = r*sin(theta) ergibt sich die gerichtete Bewegung in die Richtung eines Winkels.
Da die Spitze des Panzers bei dir vermutlich ebenfalls "nach oben" zeigt, der Winkel 0 in einem Polarkoordinatensystem jedoch "nach rechts", muss der Winkel "zurück" gerechnet werden. Also -90.0f.

Du kannst das Problem eleganter lösen, indem du deine Pixelgrafik des Panzers um 90° nach rechts drehst und anschließend als Initialrotation PlayerSprite.setRotation(-90.0f); angibst. ;)
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

18

23.04.2014, 16:25

@iSmokiieZz
Vielen Dank, dein Code funktioniert. :thumbsup:

@BlueCobold
In einem meiner C++ Bücher (weiß grad nicht mehr welches) stand, dass man #define auch für Konstanten verwenden kann.
Was cmath angeht dachte ich immer, dass cmath von C ist und math.h für C++. Ich weiß nicht wo her ich das habe.

Und auch vielen Dank an die anderen die mir geholfen haben. 8)

C-/C++-Quelltext

1
2
    /* Keep the compiler happy */
    return(0);

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

19

23.04.2014, 16:48

Man KANN #define für Konstanten einsetzen, sollte es aber nicht tun. Ist einfach schlechter C++-Stil.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

20

23.04.2014, 17:47

Es ist nicht so, dass man es nicht macht, weil es irgendwie hässlich ist oder so. Problematiken wie diese und deren Art sie zu lösen gibt es in Effektiv C++ von Scott Meyers wunderbar beschrieben.
Im Allgemeinen merk dir einfach, wenn du es dir nicht besorgen möchtest, dass man den Präprozessor als allerletztes benutzen sollte, eben nur, wenn es gar nicht anders geht. Nicht zuletzt hilfst du dir selbst damit, wenn mal ein Fehler durch das Makro auftritt, denn der Compiler kann dir ja nicht wirklich sagen, dass es am Makro liegt.

MfG
Check

Werbeanzeige