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

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

01.12.2010, 21:31

Egoshooter Steuerung - Mathe

Hallo,

ich hab vor 4 Tagen mit OpenGL angefangen und probiere gerade eine typische Egoshooter Steuerung umzusetzen. Dafür hab ich mir einfach mal eine Quadrat als "Boden" erstellt und darauf ein paar Dreicke gesetzt um zu sehen wieweit und wohin ich mich bewege. Im Moment schaffe ich es die Kamera um alle Achsen zu drehen und über W und S dann in die entsprechende Richtung zu laufen. Das große Problem ist der "Seitwärtsschritt", bei dem weiß ich nicht wie ich die Kamera verschieben soll. Vielleicht liegt es auch generel an meiner falschen Technik, da ich vielleicht die Welt und nicht die Kamera bewegen sollte?
Für alle Bewegungen habe ich nur gluLookAt benutzt, so das ich also nichts transformiere oder rotiere.
Ich geb euch einfach mal alles. Sind wahrscheinlich tausende von Fehlern drin und Verbesserungen nötig, aber ich steh ja noch am Anfang :) C++ kann ich auch noch nicht sooooo gut aber es ist langweilig ein halbes Jahr nichts grafisches zu machen. Newbe bin ich aber trotzdem nicht (PHP, Java, Python, ...).

So hier jetzt aber:

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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#include <iostream.h>
#include <math.h>
#include <gl/glut.h>

class Camera{
    private:
        float pos[3];       // Position der Kamera (Punkt)
        float energie[3];   // Energie (Vektor)
        float dir[3];       // Kameraausrichtung (Vektor)
        float speed[2];     // Geschwindigkeiten (Bewegung, Drehgeschwindigkeit)
        float rot[2];       // Rotation
        
    public: 
        Camera(float posX, float posY, float posZ, float rotX, float rotY){
            this->pos[0] = posX;
            this->pos[1] = posY;
            this->pos[2] = posZ;
            this->rot[0] = rotX;
            this->rot[1] = rotY;
            
            this->energie[0] = 0.0;
            this->energie[1] = 0.0;
            this->energie[2] = 0.0;
            
            this->dir[0] = 0;
            this->dir[1] = 0;
            this->dir[2] = 0;
            
            this->speed[0] = 0.01;
            this->speed[1] = 0.001;
        }
        
        void move(){
            // Drehen
            this->dir[0] = sin(this->rot[0]);
            this->dir[1] = tan((this->rot[1]-(floor(this->rot[1]/M_PI))*M_PI-M_PI/2));
            this->dir[2] = cos(this->rot[0]);
                                
            // Versetzen (mit Bewegungsenergie)
            this->pos[0] += (this->energie[0]*this->dir[0])*this->speed[0];
            this->pos[1] += (this->energie[1]*this->dir[1])*this->speed[0];
            this->pos[2] += (this->energie[2]*this->dir[2])*this->speed[0];
        }
        
        // Position liefern
        void getPosition(float* position){
            position[0] = this->pos[0]; 
            position[1] = this->pos[1];
            position[2] = this->pos[2];
            position[3] = this->pos[0]+this->dir[0];
            position[4] = this->pos[1]+this->dir[1];
            position[5] = this->pos[2]+this->dir[2]; 
        }
        
        // Vorwaerts/Ruckwaerts
        void forward(int i){
            this->energie[0] = i;
            this->energie[2] = i;
        }
        
        // Kamera drehen
        void rotate(float x, float y){
            this->rot[0] += x*this->speed[1];
            this->rot[1] += y*this->speed[1];
            
            // Y max = PI
            if(this->rot[1] < -3.1){
                this->rot[1] = -3.14159;    
            }
            else if(this->rot[1] > 0){
                this->rot[1] = -0.00001;
            }
        }
};

int width, height;                                      // Breite und Hoehe des Fensters
float lastMousePosition[] = {0, 0};                     // Letzte Mauskoordinaten
float fps_frame = 0, fps_time, fps_timebase = 0, fps = 0;  // FPS-Berechnung
Camera* player = new Camera(0.0, 10.0, -1.0, M_PI/2, 0);

/******************************************************************************\
* Steuerung                                                                 *
\******************************************************************************/

// Taste gedrueckt
void keyPressed(unsigned char key, int x, int y){   
    switch(key){
        // D
        case 97:
            break;  
        // A
        case 100:
            break;
        // W
        case 119:
            player->forward(1);
            break;
        // S
        case 115:
            player->forward(-1);
            break; 
        // Leertaste
        case 32:
            // ...
            break;
        case 27:
            exit(0); 
    }   
}

// Taste losgelassen
void keyReleased(unsigned char key, int x, int y){
    switch(key){
        // D
        case 97:
            break;  
        // A
        case 100:
            break;
        // W
        case 119:
            player->forward(0);
            break;
        // S
        case 115:
            player->forward(0);
            break; 
    }   
}

// Mausbewegung
void mouseMotion(int x, int y){                             
    player->rotate(lastMousePosition[0]-x, lastMousePosition[1]-y); 
                    
    // Mauszeiger zuruecksetzen
    if(x < 200 || x > width-200 || y < 200 || y > height-200){
        glutWarpPointer(width/2, height/2); 
        lastMousePosition[0] = width/2;
        lastMousePosition[1] = height/2;
    }
    else{
        lastMousePosition[0] = x;
        lastMousePosition[1] = y;   
    }
}

/******************************************************************************\
* Ausgabe                                                                   *
\******************************************************************************/

// FPS ausgeben
void getFPS(){
    fps_frame++;
    fps_time = glutGet(GLUT_ELAPSED_TIME);  
    if(fps_time-fps_timebase > 1000){
        fps = fps_frame*1000/(fps_time-fps_timebase);
        fps_timebase = fps_time;        
        fps_frame = 0;
                
        cout<<"FPS: "<<fps<<endl;   // <<<<<<<<<<<<<<<
    }   
}

// Graphische Ausgabe
void draw(){    
    // Boden
    glColor3f(1.0, 1.0, 1.0);
    glBegin(GL_QUADS);
        glVertex3f(-100.0f, 0.0f, -100.0f);
        glVertex3f(-100.0f, 0.0f, 100.0f);
        glVertex3f(100.0f, 0.0f, 100.0f);
        glVertex3f(100.0f, 0.0f, -100.0f);
    glEnd();
    
    // Referenzlinien
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_TRIANGLES);
        for(int r = 0; r < 21; r++){
            for(int c = 0; c < 21; c++){
                glVertex3f(-100.0f+c*10, 0.0f, -100.0f+r*10);
                glVertex3f(-100.0f+c*10+1, 0.0f, -100.0f+r*10);
                glVertex3f(-100.0f+c*10, 7.0f, -100.0f+r*10);   
            }   
        }
    glEnd();
}

void display(){ 
    // FPS
    getFPS(); 
    
    // Kamera
    player->move();
    float pos[6];
    player->getPosition(pos);
    glLoadIdentity();
    gluLookAt(pos[0], pos[1], pos[2],
            pos[3], pos[4], pos[5],
            0.0, 1.0, 0.0);
    
    // Buffer leeren, Matrix loeschen
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    
    // Zeichnen
    draw();
            
    // Matrix mit Aenderungen speichern
    glPopMatrix();
    
    // Buffer tauschen
    glutSwapBuffers();
}

void reshape(int w, int h){
    if(h == 0){
        h = 1;  
    } 
    
    // Breite und Hoehe speichern
    width = w;
    height = h;  
    float ratio = 1.0*w/h;
    
    // Koordinatensystem zuruecksetzen
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); 

    // Fensterbereich fuer Ausgabe (ganzes Fenster)
    glViewport(0, 0, w, h);
    
    // Perspektive setzen
    gluPerspective(50, ratio, 1, 1000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 10.0, 0.0,
            0, 10.0, -1.0,
            0.0, 1.0, 0.0);   
}

int main(int argc, char **argv){    
    // Initialisierung
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB);
    
    // Fenster
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("ES_Steuerung");
    glutSetCursor(GLUT_CURSOR_NONE); // Cursor loeschen
    
    // Ausgabe
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    
    // Eingabe
    glutKeyboardFunc(keyPressed);
    glutKeyboardUpFunc(keyReleased);
    glutPassiveMotionFunc(mouseMotion);
    
    // Tiefenvergleich aktivieren
    glEnable(GL_DEPTH_TEST);
    
    glutMainLoop(); 
    return 0;   
}


Die Klasse oben kommt später in eine DLL, das hab ich aber jetzt mal rausgenommen.


DeKugelschieber

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

01.12.2010, 21:47

Du kennst doch deinen LookAt Vektor und deinen Up Vektor? Einfach Kreuzprodukt von (LookAt - Kameraposition) und Up Vektor berechnen gibt dir einen Vektor der seitwärts zeigt...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

01.12.2010, 21:58

Danke für die schnelle Antwort!

Ich hab mir das gerade mal auf Wiki angeguckt, versteh aber nicht ganz wie das jetzt gerechnet wird (tja, bin leider "erst" 10te auf der Realschule).
Welche der Formeln kann icht jetzt verwenden? Hab das gerade mal für ein Beispiel durchgerechnet. Wenn keiner lust hat mir das zu erklären kann ich morgen meinen Mathelehrer fragen.

DK

[Edit]

Was mir gerade noch einfällt: Wie sieht der Code so aus? Die Technik? Ich bin für jede Korrektur/Verbesserung dankbar!

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

01.12.2010, 22:11

Ganz einfach mit der Formel:
§ \begin{pmatrix} a_1 \\ a_2 \\ a_3 \end{pmatrix} \times \begin{pmatrix} b_1 \\ b_2 \\ b_3 \end{pmatrix} = \begin{pmatrix} a_2 \cdot b_3 - a_3 \cdot b_2 \\ a_3 \cdot b_1 - a_1 \cdot b_3 \\ a_1 \cdot b_2 - a_2 \cdot b_1 \end{pmatrix} §

Was den Code angeht: für den Anfang passt das schon so. Klassen für Vektoren und Matritzem würden sicherlich nicht schaden ;)

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

01.12.2010, 22:13

An Klassen für Vektoren und Matrizen hab ich natürlich auch schon gedacht, wird dann auch demnächst umgesetzt aber das Problem ist ja erstmal die Mathematik :) Wenn ichs drauf hab wird das dann erstellt.

Dank dir, ich probier das morgen mal gründlich aus und meld mich.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

02.12.2010, 16:19

Also ich bekomm das jetzt noch nicht ganz so hin...
Was meinst du mit Up Vektor? Ich hab jetzt den Punkt an dem sich die Kamera befindet und als Vektor den LookAt, also Punkt+LookAt = LookAt Punkt.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
// Position liefern
        void getPosition(float* position){
            position[0] = this->pos[0]; 
            position[1] = this->pos[1];
            position[2] = this->pos[2];
            position[3] = this->pos[0]+this->dir[0];
            position[4] = this->pos[1]+this->dir[1];
            position[5] = this->pos[2]+this->dir[2]; 
        }


Kann ich mir aus den Daten die ich hab den zweiten Vektor bauen oder brauch ich noch mehr? Gibt es eine andere Umsetzung davon? Weil sonst find ich die Steuerung in Ordnung, bzw. die Berechnung davon.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

02.12.2010, 16:22

Nein mit einem einzelnen Vektor wirst du nicht weit kommen. Du suchst einen Vektor der normal auf deinen LookAt Vektor steht. Da gibts aber unendlich viele Möglichkeiten, du willst aber eine ganz bestimmte und nicht irgendeine Lösung. Du übergibst den Up Vektor an gluLookAt, also kennst du ihn. Einfach ein Vektor der anzeigt wo oben ist. Den brauchst du, denn nur wenn du zwei Richtungen kennst kannst du die dritte bestimmen...

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

8

02.12.2010, 16:25

Achso! Ok dann ist alles klar :), funktioniert jetzt.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Seitwaerts
    void sideward(float i){
        float a1 = this->dir[0];
        float a2 = this->dir[1];
        float a3 = this->dir[2];
        float b1 = 0;
        float b2 = 1;
        float b3 = 0;
        
        float c1 = a2*b3-a3*b2;
        float c2 = a3*b1-a1*b3;
        float c3 = a1*b2-a2*b1;
        
        this->pos[0] += c1*i;
        this->pos[1] += c2*i;
        this->pos[2] += c3*i;
    }


Sobald ich wieder Probleme hab (beim Springen) meld ich mich :D

[Edit]

Kürzer:

C-/C++-Quelltext

1
2
3
4
5
6
// Seitwaerts
        void sideward(float i){         
            this->pos[0] += (this->dir[1]*0-this->dir[2]*1)*i;
            this->pos[1] += (this->dir[2]*0-this->dir[0]*0)*i;
            this->pos[2] += (this->dir[0]*1-this->dir[1]*0)*i;
        }

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (02.12.2010, 16:32)


CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

9

02.12.2010, 19:00

ich würde den Up-Vektor nicht explizit hartcoden, dann kannst du die Kamera nicht mehr rollen, womit man jedoch schöne Effekte erzielen kann ;)

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

10

02.12.2010, 19:03

Wieso? Das hier ist eine Shooter Steuerung, wenns eine für einen Flugsimulator sein sollte währe das natürlich richtig. Oder gibt es Situationen in einem Shooter wo das nötig ist? Wenn ja kann ichs dann ja auch noch einbauen.

DK

Werbeanzeige