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

1

22.04.2014, 17:07

[C++ & SFML] Lösungsansatz zur Charakterbewegung in einem 2D Panzerspiel

Hallo,
ich bin gerade dabei mich in die SFML einzuarbeiten. Nun glaube ich mich weit genug um ein Spiel, dass ich angefangen hatte mit der SDL zu programmieren neu mit der SFML zu programmieren. Es ist/war ein 2D Panzerspiel in dem man einen kleinen Panzer recht eckig steuern kann/konnte. Nun wollte ich, dass man den Panzer mit "A" nach links rotieren kann und mit "D" nach rechts. Mit "W" sollte man Vorwärtsfahren und mit "S" Rückwärtsfahren können. Wenn ich nun meinen Panzer z.B. um 32° nach links rotiert habe und ich Vorwärtsfahren will kann ich nun ja nicht mehr nur die Y-Koordinate verringern da der Panzer ja aus Sicht des Spielers nicht geradeaus sondern seltsam seitlich fahren würde. Also muss ich die Koordinaten abhängig von der Ausrichtung des Panzers manipulieren. Doch wie soll ich die Ausrichtung des Panzers und davon abhängig die Bewegung berechnen?

Vielen Dank schon Mal für's lesen dieser Frage.
Gruß Swoerm. :)

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

2

22.04.2014, 17:15

Dem Panzer einen Richtungsvektor geben?

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

4

22.04.2014, 19:23

Ich habe jetzt versucht, dass was ich dem Link entnehmen konnte umzusetzten:

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
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
#define _USE_MATH_DEFINES

#include <SFML\Graphics.hpp>
#include <math.h>
#include <iostream>

#define FRAMERATE_LIMIT 60

int main ()
{
    
    sf::RenderWindow MainWindow (sf::VideoMode (1680, 1050, 32), "SFML_Game 3 - SwoermGames", sf::Style::Default);

    MainWindow.setFramerateLimit (FRAMERATE_LIMIT);

    sf::Event Event;
    sf::Clock Clock;

    float dt = 0.0f;
    float PLAYER_SPEED = 100.0f;

    float x = MainWindow.getSize().x/2, y = MainWindow.getSize().y/2;

    sf::Image   PlayerImage;
    sf::Texture PlayerTexture;

    PlayerImage.loadFromFile ("Data/Images/Player.bmp");
    PlayerImage.createMaskFromColor (sf::Color (255, 0, 255, 255));
    PlayerTexture.loadFromImage (PlayerImage);
    sf::Sprite  PlayerSprite (PlayerTexture);
    PlayerSprite.setOrigin (PlayerSprite.getPosition().x+PlayerSprite.getTexture()->getSize().x/2, PlayerSprite.getPosition().y+PlayerSprite.getTexture()->getSize().y/2);
    PlayerSprite.setRotation (32);
    PlayerSprite.setPosition (x, y);

        
     // Main-Loop
    while (MainWindow.isOpen())
    {

        dt = Clock.restart().asSeconds();

        // Event-Handling
        while (MainWindow.pollEvent(Event))
        {

            if ( Event.type == sf::Event::Closed )
                MainWindow.close ();
        }

        if ( sf::Keyboard::isKeyPressed (sf::Keyboard::Escape) )
                MainWindow.close ();

        // PlayerMovement

        if ( sf::Keyboard::isKeyPressed (sf::Keyboard::W) )
            y += static_cast<float> ((PLAYER_SPEED * -sin ( PlayerSprite.getRotation() * (M_PI / 180) )) * dt);

        PlayerSprite.setPosition (x, y);

        // Clear the window
        MainWindow.clear ();

        // Draw the sprites
        MainWindow.draw (PlayerSprite);

        // Display window content
        MainWindow.display ();

    }

    return 0;
}


Jedoch bewegt sich der Spieler wenn ich "W" drücke weiterhin nur nach oben.

C-/C++-Quelltext

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

Cookiezzz

Frischling

Beiträge: 91

Wohnort: Deutschland

Beruf: Schüler

  • Private Nachricht senden

5

22.04.2014, 19:26

Du änderst x ja auch nicht. Warum sollte sich der Spieler dann seitlich bewegen?

Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

6

22.04.2014, 20:01

Mein Code sieht jetzt so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
// PlayerMovement

        if ( sf::Keyboard::isKeyPressed (sf::Keyboard::W) )
        {
            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);
        }

        if ( sf::Keyboard::isKeyPressed (sf::Keyboard::D) )
        {
            PlayerSprite.setRotation (PlayerSprite.getRotation()+1);
        }


Allerdings bewegt sich der Spieler so gut wie immer nach oben.

C-/C++-Quelltext

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

Dreat

Frischling

Beiträge: 86

Wohnort: Heilbronn

  • Private Nachricht senden

7

22.04.2014, 20:23

Was in welcher Einheit gibt den getRotation die Rotation zurück? Als Radiant oder Grad probiers mal ohne Pi/180

8

22.04.2014, 20:24

Bogenmaße / Gradmaße beachten!

Pi ist ein Bogenmaß (3.14), das kannst du nicht so einfach durch eine Gradzahl dividieren (180) ;)

Edit: Natürlich essei denn, du möchtest die Rotation von Grad in Bogenmaß konvertieren^^



Wenn du möchtest, dass pi auch durch das Bogenmaß von 180 dividiert wird, solltest du das einfach weglassen. Denn Pi durch Pi ist 1.
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »iSmokiieZz« (22.04.2014, 20:31)


Swoerm

Alter Hase

  • »Swoerm« ist der Autor dieses Themas

Beiträge: 451

Wohnort: 127.0.0.1

  • Private Nachricht senden

9

22.04.2014, 20:42

getRotation () gibt eine Gradzahl zurück (0°-360°). Wenn ich PI / 180 entferne verhält sich der Spieler allerdings immer noch nicht wie gewünscht.

C-/C++-Quelltext

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

10

22.04.2014, 20:57

Wenn getRotation() eine Gradzahl zurückgibt, musst du M_PI/180 auf jeden fall stehen lassen.

Habe soeben ein heruntergebrochenes Projekt bei mir kompiliert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#define M_PI 3.14159265358979323846
float x = 0.0f;
float y = 0.0f;
float alpha = 45.0f;
float fSpeed = 100.0;

x += static_cast<float> ((fSpeed * cos(alpha * (M_PI / 180)))*1.0f);
y += static_cast<float> ((fSpeed * -sin(alpha * (M_PI / 180)))*1.0f);

cout << x << endl << y << endl;


Er spuckt mir aus:

70.7107
-70.7107

Debugge doch mal deine Werte ;)
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Werbeanzeige