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

CraftPlorer

Frischling

  • »CraftPlorer« ist der Autor dieses Themas

Beiträge: 39

Wohnort: Elsfleth

Beruf: Schüler

  • Private Nachricht senden

1

15.03.2013, 21:25

C++,OpenGl, glfw Eingabe bug

Hallo,
wenn ich zb. W gedrückt halte und dann versuche zu Springen (Leertaste) Spring ich einfach nicht woran liegt das?
Hat das was mit glfw zu tun oder hab ich ein fehler gemacht?
Der Code:

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
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "controlls.h"

//Globel variables

glm::vec3 position      = glm::vec3( 0, 0, 5 ); //position
float horizontalAngle   = 3.14f; // horizontal angle : toward -Z
float verticalAngle     = 0.0f; // vertical angle : 0, look at the horizon
float initialFoV        = 45.0f; // Initial Field of View
float speed             = 3.0f; // 3 units / second
float mouseSpeed        = 0.05f; //mouseSpeed
bool  jump              = false;




glm::mat4 ViewMatrix; // ViewMmartix
glm::mat4 ProjectionMatrix; // ProjectionMatrix

glm::mat4   getProjectionMatrix(){
    return ProjectionMatrix;
}
glm::mat4   getViewMatrix(){
    return ViewMatrix;
}

void jumpFunk(float deltaTime);

void computeMatricesFromInputs(){
    static double lastTime  = glfwGetTime(); // one time on first call the func(computeMatricesFromInputs())
    double currentTime      = glfwGetTime();
    float deltaTime         = float(currentTime - lastTime);

    // screen size
    GLFWvidmode desktopMode;
    glfwGetDesktopMode( &desktopMode);
    int height  = desktopMode.Height;
    int width   = desktopMode.Width;

    int xpos, ypos; // x and y pos of the mouse

    glfwGetMousePos(&xpos, &ypos); // get the mouse pos
    glfwSetMousePos(height/2, width/2); // set the mouse to the middle of the screen

    horizontalAngle += mouseSpeed * deltaTime * float(height/2 - xpos);
    verticalAngle   += mouseSpeed * deltaTime * float(width/2 -ypos);

    if(verticalAngle > 0.5){
        verticalAngle = 0.5;
    }else if(verticalAngle < -0.25){
        verticalAngle = -0.25;
    }


    glm::vec3 direction(
        cos(verticalAngle) * sin(horizontalAngle),
        sin(verticalAngle),
        cos(verticalAngle) * cos(horizontalAngle)
    );

    // Right vector
    glm::vec3 right = glm::vec3(
    sin(horizontalAngle - 3.14f/2.0f),
    0,
    cos(horizontalAngle - 3.14f/2.0f)
    );

    // Up vector : vertical to both direction and right
    glm::vec3 up = glm::cross( right, direction );

    // Position move forward
    if (glfwGetKey( 'W' ) == GLFW_PRESS){
        position += direction * deltaTime * speed;
    }
    // Move backward
    if (glfwGetKey( 'S' ) == GLFW_PRESS){
        position -= direction * deltaTime * speed;
    }
    // Strafe right
    if (glfwGetKey( 'D' ) == GLFW_PRESS){
        position += right * deltaTime * speed;
    }
    // Strafe left
    if (glfwGetKey( 'A' ) == GLFW_PRESS){
        position -= right * deltaTime * speed;
    }

    //zoom
    float FoV = initialFoV - (2+speed) * glfwGetMouseWheel();

    if(FoV >= 65.0f){
        FoV = 65.0f;
    }else if(FoV <= 35.0f){
        FoV = 35.0f;
    }

    jumpFunk(deltaTime);

    if(position.y < 0.00f)
        position.y = 0.00f;
    
    
    



    // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    ProjectionMatrix = glm::perspective(FoV, 4.0f / 3.0f, 0.1f, 100.0f);
    // Camera matrix
    ViewMatrix       = glm::lookAt(
        position,           // Camera is here
        position+direction, // and looks here : at the same position, plus "direction"
        up                  // Head is up (set to 0,-1,0 to look upside-down)
    );

    lastTime = currentTime;
}


void jumpFunk(float deltaTime){
    float jumpSpeed = 6.5f;
    float hight     = 2.0f;


    if (glfwGetKey( GLFW_KEY_SPACE ) == GLFW_PRESS){
        if(!position.y > 0.1f)
            jump = true;
    }

    if(jump == true && position.y < hight){
        position.y += jumpSpeed * deltaTime;
    }else if(position.y > 0.0f || !position.y < 0.0f){
        position.y -= jumpSpeed * deltaTime;
        jump = false;
    }

    
    std::cout << "Time " << deltaTime << std::endl;
    std::cout << "Hight " << position.y << std::endl;
    std::cout << std::endl;

    }


mfG

2

15.03.2013, 23:44

Aber Springen funktioniert korrekt, wenn du nicht W dabei drückst?

Allgemein ein paar Anmerkungen:
- es heißt 'Height' ^^
- in 131: 'größer als 0 oder nicht kleiner als 0'? Sicher dass das Sinn macht?
- if(jump == true) ist unnötig, ein einfaches if(jump) reicht auch. Außerdem macht es einen semantischen Unterschied:
(if(1==true) wird ausgeführt, if(2==true) aber nicht. Aber sowohl if(1) als auch if(2) werden ausgeführt).
Lieber dumm fragen, als dumm bleiben!

CraftPlorer

Frischling

  • »CraftPlorer« ist der Autor dieses Themas

Beiträge: 39

Wohnort: Elsfleth

Beruf: Schüler

  • Private Nachricht senden

3

16.03.2013, 03:05

Aber Springen funktioniert korrekt, wenn du nicht W dabei drückst?

Ja es geht nur nicht solange ich w gedrückt halte.

- es heißt 'Height'

Ok :D

- in 131: 'größer als 0 oder nicht kleiner als 0'? Sicher dass das Sinn macht?

Ich weiß auch nicht was das sollte.
- if(jump == true) ist unnötig, ein einfaches if(jump) reicht auch. Außerdem macht es einen semantischen Unterschied:
(if(1==true) wird ausgeführt, if(2==true) aber nicht. Aber sowohl if(1) als auch if(2) werden ausgeführt).

Also das man anstatt if(jump == true) auch if(jump) schreiben kann wusste ich auch aber was das für ein Unterschied macht habe ich jetzt nicht ganz verstanden.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

4

16.03.2013, 03:16

Wenn ein boolean mit einem int vergleicht wird (oder in mit sonstigen Operatoren verknüpft wird) wird true in 1 und false in 0 umgewandelt. Das führt dazu, dass

C-/C++-Quelltext

1
1==true
wahr ist, aber

C-/C++-Quelltext

1
2==true
falsch. Auf der anderen Seite wird ein int, falls es in ein boolean umgewandelt wird, für jeden Wert ausser 0 wahr und für 0 falsch. Das führt dazu, dass diese Vergleiche unterschiedliche Werte haben.

CraftPlorer

Frischling

  • »CraftPlorer« ist der Autor dieses Themas

Beiträge: 39

Wohnort: Elsfleth

Beruf: Schüler

  • Private Nachricht senden

5

16.03.2013, 12:20

Ok. Aber das hat doch jetzt keinen Einfluss auf meine eigentliches Problem oder?

CraftPlorer

Frischling

  • »CraftPlorer« ist der Autor dieses Themas

Beiträge: 39

Wohnort: Elsfleth

Beruf: Schüler

  • Private Nachricht senden

6

18.03.2013, 19:28

Achja fast vergessen. Wenn ich A und D drücke kann ich springen bloß bei W und S nicht.

7

18.03.2013, 22:03

Die Logik dahinter ergibt ja auch überhaupt gar keinen Sinn.
Wenn du nach vorne läufst, addierst du 'direction', der kann aber je nach Blickwinkel auch gerne mal schräg nach oben zeigen. Du kannst also offensichtlich schon rumfliegen, wieso solltest du dann noch springen wollen?

Und dann die Abfrage 'if(!position.y > 0.1f)' Du kannst nur springen, wenn du unterhalb von 0.1 bist? Was du damit eigentlich ausdrücken willst, ist wohl, dass du nur springen kannst, wenn du auf dem Boden stehst, der sich vermutlich bei y=0 befindet. Ich könnte mir vorstellen, dass wenn du ein bisschen nach oben guckst, du dich auch nach oben bewegst, und dann oberhalb des Bodens bist.
Dann rufst du aber die Jump-Funktion auf, die nicht erkennt, dass du Springen willst, sondern nur, dass du schon in der Luft schwebst, und dann denkt, sie müsste dich Fallen lassen, wodurch sie dich wieder nach unten beschleunigt, was daraufhin nach der Jump-Funktion direkt wieder abgefangen wird.

Zusammengefasst hast du also nicht nur eine kaputte Jump-Funktion, du hast auch noch eine Flug-Funktion eingebaut, die von der Jump-Funktion kaputt gemacht wird. Einzelne Ideen deiner Implementierung sind ja gut und richtig, aber du hast das eigentliche Problem falsch abstrahiert, wodurch ziemlich alberne Sachen passieren. Und dann versuchst du mit noch mehr Logik, die Symptome zu verhindern, anstatt die Ursache zu beheben.

Also, wie reparieren wir das ganze? Nun, tatsächlich ist es erstaunlich einfach, die Gesetze der Physik zu benutzen: Ein Sprung bedeutet nicht, dass du dich ein Weilchen nach oben bewegst, und dann plötzlich umkehrst und die nach unten bewegst. In der echten Welt gibt es Schwerkraft, und die beschleunigt dich nach unten, solltest du nicht durch den Boden aufgehalten werden. Durch einen Sprung wird dein Körper einfach nur nach oben Beschleunigt, natürlich kann dieser aber nur ausgeführt werden, wenn du am Boden stehst.
Am Anfang stehst du also still am Boden, dein Geschwindigkeitsvektor ist also 0. Springst du, bekommt dieser einen positiven Y Eintrag, und du bewegst dich nach oben, denn Bewegung funktioniert, indem man den Geschwindigkeitsvektor auf den Ortsvektor addiert. Nachdem du aber angefangen hast, dich zu bewegen, bist du in der Luft, also nicht mehr am Boden, also wirkt die Schwerkraft und verringert deinen Geschwindigkeitsvektor. Am Scheitelpunkt des Sprunges ist dieser dann 0, danach kehrt sich das Vorzeichen um und du beschleunigst Richtung Boden. Sobald du ihn erreicht hast, wird dein Geschwindigkeitvektor durch den Boden wieder auf 0 gesetzt.
Das schöne ist, damit kannst du auch Plattformen auf bleiebiger Höhe haben, alles was du benötigst ist ein "istAufBoden"-Test.

Und weil mein Abendessen noch 10 Minuten braucht, kommt jetzt auch noch Pseudocode:

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
vec3 Position;
vec3 Geschwindigkeit;

while(Hauptschleife)
{
  Position+=Geschwindigkeit;
  if(Sprungtaste && AufBoden())//abspringen
  {
    Geschwindigkeit.y=20;
  }

  if( ! AufBoden())//Gravitation
  {
     Geschwindigkeit.y-=0.6;
     //Gravitation wirkt immer, unabhängig davon, ob man gesprungen ist. Läuft man
     //über eine Kante hinaus fällt man ja auch runter, ohne vorher gesprungen zu sein.
  }
  else
  { 
     Geschwindigkeit.y=0;

     Position.y=0;
     //durch das letzte Position+=Geschwindigkeit könnten wir in den Boden gerutscht sein, das
     //gleichen wir hier einfach mal aus, notwendig ist dies aber nicht
  }
}

AufBoden()
  return Position.y<=0;


Und das schöne ist: Diese simple Rechnung ergibt eine physikalisch halbwegs korrekt Flugparabel (Effekte wie Reibung sind halt noch nicht berücksichtigt).
Und was auch schön ist: Der Code ist jetzt nicht nur richtig, sondern er ist auch einfacher geworden. Man erlebt es erstaunlich oft, dass gute Abstraktionen sehr einfach und elegant sind.
Lieber dumm fragen, als dumm bleiben!

CraftPlorer

Frischling

  • »CraftPlorer« ist der Autor dieses Themas

Beiträge: 39

Wohnort: Elsfleth

Beruf: Schüler

  • Private Nachricht senden

8

19.03.2013, 20:39

Echt super Antwort. Werde mich mal dransetzen. Danke dir

PS: Hoffe dein Essen hat geschmeckt :D

Werbeanzeige