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

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

1

05.10.2015, 23:03

[C++ | Sfml]

Hallo Leute,

zurzeit programmiere ich immer noch ein Spiel für eine Challenge. Nun ist das Menü fertig und jetzt muss ich das PlayState machen. Dabei habe ich eine View eingebaut:

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Konstruktor: // Die View
    mPlayerView.setSize(sf::Vector2f(768.f, 768.f));
    mPlayerView.setCenter(mPlayerSprite.getPosition().x, mPlayerSprite.getPosition().y);
    mPlayerView.setViewport(sf::FloatRect(0, 0, 1, 1));
    mPlayerView.zoom(0.8);
// Update-Funktion: // Oben
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W))
    {
        mPlayerSprite.move(0, -playerSpeed);
        mPlayerView.move(0.f, -viewSpeed);
        mPlayerSprite.setRotation(atan2(90.f, 90.f) * 360.f / PI);
    }

    // Unten
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S))
    {
        mPlayerSprite.move(0, playerSpeed);
        mPlayerView.move(0.f, viewSpeed);
        mPlayerSprite.setRotation(atan2(90.f, 90.f) * -360.f / PI);
    }

    // Rechts
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D))
    {
        mPlayerSprite.move(playerSpeed, 0);
        mPlayerView.move(viewSpeed, 0);
        mPlayerSprite.setRotation(atan2(180.f, 180.f) * -720.f / PI);
    }

    // Links
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A))
    {
        mPlayerSprite.move(-playerSpeed, 0);
        mPlayerView.move(-viewSpeed, 0);
        mPlayerSprite.setRotation(atan2(0.f, 0.f) * 360.f / PI);
    }

    // Oben Rechts
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W) && sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D))
    {
        mPlayerSprite.setRotation(135.f);
    }

    // Oben Links
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W) && sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A))
    {
        mPlayerSprite.setRotation(45.f);
    }

    // Unten Rechts
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S) && sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D))
    {
        mPlayerSprite.setRotation(225.f);
    }

    // Unten Links
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S) && sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A))
    {
        mPlayerSprite.setRotation(-45.f);
    }
// Process-Events:  
// y-Achse
    if (mPlayerSprite.getPosition().y <= 310.f)
    {
        mPlayerView.setCenter(mPlayerSprite.getPosition().x, 310);
    }
    else if (mPlayerSprite.getPosition().y >= 1000.f)
    {
        mPlayerView.setCenter(mPlayerSprite.getPosition().x, 1000);
    }


    // x-Achse
    else if (mPlayerSprite.getPosition().x <= 310.f)
    {
        mPlayerView.setCenter(310, mPlayerSprite.getPosition().y);
    }

    else if (mPlayerSprite.getPosition().x >= 2150.f)
    {
        mPlayerView.setCenter(2100, mPlayerSprite.getPosition().y);
    }

    else
        mPlayerView.setCenter(mPlayerSprite.getPosition().x, mPlayerSprite.getPosition().y);
// Render:
App.setView(mPlayerView);


Leider funktioniert das nicht so richtig, d.h. manchmal bleibt die Kamera stehen und manchmal nicht. Sieht jemand den Fehler?
Danke im Voraus :)

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »cojo2015« (05.10.2015, 23:10)


2

06.10.2015, 00:21

Nutz doch endlich mal den Debugger..

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

06.10.2015, 06:37

Ich habe nicht alles durchgesehen, aber hier ist definitiv schon mal ein Fehler. 2150 vs 2100. Unter anderem deshalb sind Magic Numbers schlecht.

C-/C++-Quelltext

1
2
3
4
else if (mPlayerSprite.getPosition().x >= 2150.f)
    {
        mPlayerView.setCenter(2100, mPlayerSprite.getPosition().y);
    }

Davon mal abgesehen setzt Du mit den Limits immer auch immer wieder die Koordinaten des Sprites, statt die Koordinaten des Views zu verwenden, womit der zweite IF-Block natürlich die Werte des ersten kaputt macht. Ich schlage vor, du machst lieber etwas in der Art:
mPlayerView.setCenter(std::max(310, std::min(2150, mPlayerSprite.getPosition().x)), std::max(310, std::min(1000, mPlayerSprite.getPosition().y)));
Das ist wesentlich kürzer als Deine ganzen IFs und zudem richtig.
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]

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

4

06.10.2015, 10:26

Danke für die Antworten. @BC Ja das ist wesentlich besser und übersichtlicher als die beiden IFs. Das werde ich heute Abend mal probieren. Danke :thumbsup:

5

06.10.2015, 12:49

Nur mal als Tipp:
Es bietet sich durchaus auch an, sich für die Zukunft eine "clamp" Funktion zu schreiben. D.h. dass eine Variabel zwischen 2 Werten fixiert wird.
Ist praktisch nichts anderes als das, was BC geschrieben hat, ließt sich aber wesentlich besser.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
template <typename T>
T clamp(const T& _min, const T& _max, const T& _value)
{
    return std::max(_min, std::min(_max, _value));
}

// ...
mPlayerView.setCenter(clamp(310, 2150, mPlayerSprite.getPosition().x), clamp(310, 1000, mPlayerSprite.getPosition().y));


PS: Ich weiß, boost bietet sowas an, warum es das nicht in den Standard geschafft hat, ist mir allerdings schleierhaft...

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »anti-freak« (06.10.2015, 12:54)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

06.10.2015, 14:31

Ist das so herum üblich bei clamp? Intuitiv für mich wäre jetzt "value, min, max" gewesen.
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

06.10.2015, 15:13

Weiß ich gerade nicht, müsste ich später nachschauen.

EDIT: Hast recht, "val, min, max".
Hier mal noch der link zu boost
http://www.boost.org/doc/libs/1_53_0/boo…rithm/clamp.hpp

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »anti-freak« (06.10.2015, 15:40)


cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

8

06.10.2015, 17:51

mPlayerView.setCenter(std::max(310, std::min(2150, mPlayerSprite.getPosition().x)), std::max(310, std::min(1000, mPlayerSprite.getPosition().y)));


Das klappt nicht. Hier der implementierte Code:

C-/C++-Quelltext

1
2
3
4
5
    #include <algorithm>
// ...
mPlayerView.setCenter(
        std::max(310, std::min(2150, mPlayerSprite.getPosition().x)), 
        std::max(310, std::min(1000, mPlayerSprite.getPosition().y)));


Hier die Fehler:

Schweregrad Code Beschreibung Projekt Datei Zeile
Fehler C2784 "_Ty std::min(std::initializer_list<_Elem>,_Pr)": template-Argument für "std::initializer_list<_Elem>" konnte nicht von "int" hergeleitet werden.

Fehler C2780 "const _Ty &std::min(const _Ty &,const _Ty &,_Pr)": Erwartet 3 Argumente - 2 unterstützt

Fehler C2780 "_Ty std::min(std::initializer_list<_Elem>)": Erwartet 1 Argumente - 2 unterstützt

Fehler C2782 "const _Ty &std::min(const _Ty &,const _Ty &)": template-Parameter "_Ty" ist mehrdeutig.

Fehler C2780 "_Ty std::max(std::initializer_list<_Elem>,_Pr)": Erwartet 2 Argumente - 1 unterstützt

Fehler C2780 "const _Ty &std::max(const _Ty &,const _Ty &,_Pr)": Erwartet 3 Argumente - 1 unterstützt

Fehler C2784 "_Ty std::max(std::initializer_list<_Elem>)": template-Argument für "std::initializer_list<_Elem>" konnte nicht von "int" hergeleitet werden.

Fehler C2780 "const _Ty &std::max(const _Ty &,const _Ty &)": Erwartet 2 Argumente - 1 unterstützt

Habe ich deine Antwort falsch interpretiert?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

06.10.2015, 17:56

#include <algorithm> ?
Oder sind .x und .y floats? Wenn ja, müssen die Konstanten entsprechend angepasst werden.
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]

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

10

06.10.2015, 18:03

#include ?
Oder sind .x und .y floats? Wenn ja, müssen die Konstanten entsprechend angepasst werden.</algorithm>

Bei Google habe ich gefunden, dass man wenn man std::max bzw. std::min verwendet das include machen.
Ja, .x und .y sind floats ^^

Werbeanzeige