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

1

22.04.2011, 22:10

(zufällig?) unterschiedliche Programm Ausführung

Ich habe das Problem, dass mein Prgramm manchmal einfach unterschiedlich reagiert, obwohl es exakt gleich ausgeführt wird.
Ich nutze Code Blocks und sfml 1.6.
Ich bin gerade dabei ein kleines Programm zu schreiben, bei dem man mit einem Block unter "physikalischen" Gesetzen durch die Gegend hüpfen kann. Nichts Aufregendes.
Der Block fällt anfangs von oben nach unten. Dort trifft er auf und wird wieder nach oben gefedert. Das geschieht so lang, bis seine Energie sehr klein ist. Nun passiert es, dass er manchmal 4 Mal springt, manchmal 3 Mal und selten auch mal 1 Mal.
Außerdem habe ich auch noch das Problem, dass ... naja der Block verzögert reagiert. D.h. er liegt auf dem Boden, ich drücke nach oben, er soll eigentlich eine bestimmte Geschwindigkeit erfahren, also kurz springen, es dauert aber ne halbe Sekunde bis er das tut. Manchmal geschieht es auch sofort.

Wie kann so etwas kommen?
Hier mal 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
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
#include <SFML/Graphics.hpp>
#include <iostream>
#include <cstdlib>
#include <sstream>
#include "Klassen.hpp"

string Display_Energy(Object *objct);
string Display_Velocity(Object *objct);

using namespace std;


const float Factor=20; //Faktor, damit die Geschwindigkeiten passen
const float Gravity=9.81*Factor;



class Time{
    private:

    float Dif_x;
    float Dif_y;
    float Dif_z;

    sf::Clock Time_x;
    sf::Clock Time_y;
    sf::Clock Time_z;

    public:
    Time():Dif_x(0),Dif_y(0),Dif_z(0){};

    void Reset_x()          {Time_x.Reset(); Dif_x=0;}
    void Reset_y()          {Time_y.Reset(); Dif_y=0;}
    void Reset_z()          {Time_z.Reset(); Dif_z=0;}

    void Set_Dif_x(float x) {Dif_x=x;}
    void Set_Dif_y(float y) {Dif_y=y;}
    void Set_Dif_z(float z) {Dif_z=z;}

    float GetTime_x()       {return Time_x.GetElapsedTime();}
    float GetTime_y()       {return Time_y.GetElapsedTime();}
    float GetTime_z()       {return Time_z.GetElapsedTime();}

    float Get_TimeDif_x()   {return Time_x.GetElapsedTime()-Dif_x;}
    float Get_TimeDif_y()   {return Time_y.GetElapsedTime()-Dif_y;}
    float Get_TimeDif_z()   {return Time_z.GetElapsedTime()-Dif_z;}
};

class Acceleration{

    private:
    float m_x, m_y, m_z;

    public:
    Acceleration(){
        m_x=0;
        m_y=Gravity;
        m_z=0;
    }

    void Set(float x, float y, float z){
        m_x=x;
        m_y=y+Gravity;
        m_z=z;
    }
    void Add(float x, float y, float z){
        m_x+=x;
        m_y+=y;
        m_z+=z;
    }
    float Get_x()       {return m_x;}
    float Get_y()       {return m_y;}
    float Get_z()       {return m_z;}

    void Set_x(float x) {m_x=x;}
    void Set_y(float y) {m_y=y;}
    void Set_z(float z) {m_z=z;}

};

class Velocity{

    private:
    float m_x, m_y, m_z;

    public:
    Velocity(){
        m_x=0;
        m_y=0;
        m_z=0;
    }

    void Set(float x, float y, float z){
        m_x=x;
        m_y=y;
        m_z=z;
    }
    void Add(float x, float y, float z){
        m_x+=x;
        m_y+=y;
        m_z+=z;
    }
    float Get_x()       {return m_x;}
    float Get_y()       {return m_y;}
    float Get_z()       {return m_z;}

    void Set_x(float x) {m_x=x;}
    void Set_y(float y) {m_y=y;}
    void Set_z(float z) {m_z=z;}


};

class Position{
    private:
    float m_x, m_y, m_z;
    public:
    Position(){m_x=0; m_y=0; m_z=0;};

    Position(float x, float y, float z): m_x(x), m_y(y), m_z(z){}

    void Set(float x, float y, float z){
        m_x=x;
        m_y=y;
        m_z=z;
    }
    void Add(float x, float y, float z){
        m_x+=x;
        m_y+=y;
        m_z+=z;
    }
    float Get_x()       {return m_x;}
    float Get_y()       {return m_y;}
    float Get_z()       {return m_z;}

    void Set_x(float x) {m_x=x;}
    void Set_y(float y) {m_y=y;}
    void Set_z(float z) {m_z=z;}

};

class Energy{
    private:
    float m_x, m_y, m_z;

    public:
    Energy(){
        m_x=0;
        m_y=0;
        m_z=0;
    }

    void Set(float x, float y, float z){
        m_x=x;
        m_y=y;
        m_z=z;
    }
    void Add(float x, float y, float z){
        m_x+=x;
        m_y+=y;
        m_z+=z;
    }
    float Get_x()       {return m_x;}
    float Get_y()       {return m_y;}
    float Get_z()       {return m_z;}

    void Set_x(float x) {m_x=x;}
    void Set_y(float y) {m_y=y; cout << m_y << endl;}
    void Set_z(float z) {m_z=z;}


};

class Object{

private:
    sf::Sprite Sprite;
    float Inverse_Mass;
    Acceleration m_Acceleration;
    Velocity m_Velocity;
    Position m_Position;
    Time m_Time;
    Energy m_Energy;

public:
    Object(){
        sf::Image Image;
        Image.LoadFromFile("quad.jpg");
        Sprite.SetImage(Image);
        Sprite.SetPosition(m_Position.Get_x(), m_Position.Get_y());
    }
    void Set_Mass(float mass){if(mass>0) Inverse_Mass=1.f/mass;}

    void Set_Velocity(){
        float x=0,y=0,z=0;
        x=m_Acceleration.Get_x()*m_Time.Get_TimeDif_x();
        y=m_Acceleration.Get_y()*m_Time.Get_TimeDif_y();
        z=m_Acceleration.Get_z()*m_Time.Get_TimeDif_z();
        m_Velocity.Add(x,y,z);
    }

    void Set_Acceleration(float x, float y, float z)    {m_Acceleration.Set(x,y,z);}
    void Set_Acceleration_x(float x)                    {m_Acceleration.Set_x(x);}
    void Set_Acceleration_y(float y)                    {m_Acceleration.Set_y(y);}
    void Set_Acceleration_z(float z)                    {m_Acceleration.Set_z(z);}

    void Set_Velocity(float x, float y, float z)    {m_Velocity.Set(x,y,z);}
    void Set_Velocity_x(float x)                    {m_Velocity.Set_x(x);}
    void Set_Velocity_y(float y)                    {m_Velocity.Set_y(y);}
    void Set_Velocity_z(float z)                    {m_Velocity.Set_z(z);}

    void Set_Kinetic_Energy()       { m_Energy.Set_x(  0.5* 1/Inverse_Mass*GetVelocity_x()*GetVelocity_x()*1/Factor*1/Factor ); //Factor muss aus Velocity rausgerechnet werden
                                    m_Energy.Set_y(  0.5* 1/Inverse_Mass*GetVelocity_y()*GetVelocity_y()*1/Factor*1/Factor );
                                    m_Energy.Set_z(  0.5* 1/Inverse_Mass*GetVelocity_z()*GetVelocity_z()*1/Factor*1/Factor ); }

    void Set_Kinetic_Energy_x()     { m_Energy.Set_x(  0.5* 1/Inverse_Mass*GetVelocity_x()*GetVelocity_x()*1/Factor*1/Factor ); }
    void Set_Kinetic_Energy_y()     { m_Energy.Set_y(  0.5* 1/Inverse_Mass*GetVelocity_y()*GetVelocity_y()*1/Factor*1/Factor ); }
    void Set_Kinetic_Energy_z()     { m_Energy.Set_z(  0.5* 1/Inverse_Mass*GetVelocity_z()*GetVelocity_z()*1/Factor*1/Factor ); }



    void ResetTime_x()      {m_Time.Reset_x();}
    void ResetTime_y()      {m_Time.Reset_y();}
    void ResetTime_z()      {m_Time.Reset_z();}

    float GetTime_x()       {return m_Time.GetTime_x();}
    float GetTime_y()       {return m_Time.GetTime_y();}
    float GetTime_z()       {return m_Time.GetTime_z();}

    float GetPos_x()        {return m_Position.Get_x();}
    float GetPos_y()        {return m_Position.Get_y();}
    float GetPos_z()        {return m_Position.Get_z();}

    float GetSize_x()       {return Sprite.GetSize().x;}
    float GetSize_y()       {return Sprite.GetSize().y;}

    float GetVelocity_x()   {return m_Velocity.Get_x();}
    float GetVelocity_y()   {return m_Velocity.Get_y();}
    float GetVelocity_z()   {return m_Velocity.Get_z();}

    float GetEnergy_x()     {return m_Energy.Get_x();}
    float GetEnergy_y()     {return m_Energy.Get_y();}
    float GetEnergy_z()     {return m_Energy.Get_z();}

    float Bounce(float energy)      {return sqrt(energy*2*Inverse_Mass); }

    sf::Sprite Get_Sprite(){return Sprite;}

    void Position_Update(){
        float x=m_Position.Get_x();
        float y=m_Position.Get_y();
        float z=m_Position.Get_z();
        Set_Velocity();
        x+=m_Velocity.Get_x()*m_Time.Get_TimeDif_x();
        y+=m_Velocity.Get_y()*m_Time.Get_TimeDif_y();
        z+=m_Velocity.Get_z()*m_Time.Get_TimeDif_z();
        m_Position.Set(x,y,z);
        Sprite.SetPosition(x,y);
        m_Time.Set_Dif_x(m_Time.GetTime_x());
        m_Time.Set_Dif_y(m_Time.GetTime_y());
        m_Time.Set_Dif_z(m_Time.GetTime_z());
    }

    void Update(float Height, float Width){
        Position_Update();
        Set_Kinetic_Energy();
        if( Sprite.GetPosition().x+Sprite.GetSize().x>=Width){
            Sprite.SetPosition(Width-Sprite.GetSize().x, Sprite.GetPosition().y);
            m_Position.Set_x(Width-Sprite.GetSize().x);
            if(m_Velocity.Get_x()>0){
                m_Velocity.Set_x(0);
                m_Acceleration.Set_x(0);
            }
            if(m_Energy.Get_x()>10){
                m_Velocity.Set_x(-0.5*Bounce(m_Energy.Get_x())*Factor);
            }
        }
        else if(Sprite.GetPosition().x<=0){
            Sprite.SetPosition(0, Sprite.GetPosition().y);
            m_Position.Set_x(0);
            if(m_Velocity.Get_x()<0){
                m_Velocity.Set_x(0);
                m_Acceleration.Set_x(0);
            }
            if(m_Energy.Get_x()>10){
                m_Velocity.Set_x(0.5*Bounce(m_Energy.Get_x())*Factor);
            }
        }
        if(Sprite.GetPosition().y+Sprite.GetSize().y>=Height-0.2){
            Sprite.SetPosition(Sprite.GetPosition().x, Height-Sprite.GetSize().y);
            m_Position.Set_y(Height-Sprite.GetSize().y);
            if(m_Velocity.Get_y()>0){
                m_Velocity.Set_y(0);
                m_Acceleration.Set_y(0);
            }
            if(m_Energy.Get_y()>10){
                m_Velocity.Set_y(-0.9*Bounce(m_Energy.Get_y())*Factor);
            }
        }
        else m_Acceleration.Set_y(Gravity);


    }

    void Show_Status(){
    cout << "Position:\nx: " << m_Position.Get_x() << "\ny: " << m_Position.Get_y() << "\nz: " << m_Position.Get_z() << "\n"<< endl;
    cout << "Velocity:\nx: " << m_Velocity.Get_x() << "\ny: " << m_Velocity.Get_y() << "\nz: " << m_Velocity.Get_z() << "\n"<< endl;
    cout << "Acceleration:\nx: " << m_Acceleration.Get_x() << "\ny: " << m_Acceleration.Get_y() << "\nz: " << m_Acceleration.Get_z() << "\n"<< endl;
    }

};


int main(){


    const float hor_acc=2*Factor;

    sf::RenderWindow App(sf::VideoMode(400,400,32),"Physik");
    sf::Color Black(0,0,0,255);
    sf::Color White(255,255,255,255);
    sf::Font Font_A;
    sf::Clock Time1;
    if(!Font_A.LoadFromFile("arial.ttf",30))
    cout << "error" << endl;

    sf::String String;
    String.SetFont(Font_A);
    String.SetSize(30);
    String.SetColor(White);

    App.Clear(Black);
    App.Display();

    bool pressed_r=false;
    bool pressed_l=false;
    bool pressed_u=false;
    bool pressed_d=false;

    Object Block;
    Block.Set_Mass(50);
    App.Draw(Block.Get_Sprite());
    App.Display();
    Time1.Reset();
    float f=0.f;

string neu="";
    while(App.IsOpened()){
        sf::Event Event;

        Block.Update(App.GetHeight(), App.GetWidth());
        App.Clear(Black);
        App.Draw(Block.Get_Sprite());



        if(Time1.GetElapsedTime()>=f){
            String.SetText(Display_Velocity(&Block));
            f+=0.1;
        }
        App.Draw(String);
        App.Display();


        while(App.GetEvent(Event)){

            if( (Event.Type==sf::Event::KeyPressed) &&(Event.Key.Code==sf::Key::Escape))
                App.Close();
            if(Event.Type==sf::Event::Closed)
                App.Close();
            if((Event.Type==sf::Event::KeyPressed)&& (Event.Key.Code==sf::Key::Right)){
                if (pressed_r==false){
                    Block.ResetTime_x();
                    pressed_r=true;
                }
                if(Block.GetPos_x()+Block.GetSize_x()<App.GetWidth())
                    Block.Set_Acceleration_x(hor_acc);
            }
            if((Event.Type==sf::Event::KeyReleased)&& (Event.Key.Code==sf::Key::Right)){
                Block.Set_Velocity_x(0);
                Block.Set_Acceleration_x(0);
                pressed_r=false;
            }

            if((Event.Type==sf::Event::KeyPressed)&& (Event.Key.Code==sf::Key::Left)){
                if (pressed_l==false){
                    Block.ResetTime_x();
                    pressed_l=true;
                }
                if(Block.GetPos_x()>0)
                    Block.Set_Acceleration_x(-hor_acc);
            }

            if((Event.Type==sf::Event::KeyReleased)&& (Event.Key.Code==sf::Key::Left)){
                Block.Set_Velocity_x(0);
                Block.Set_Acceleration_x(0);
                pressed_l=false;
            }
            if( (Event.Type==sf::Event::KeyPressed) && (Event.Key.Code==sf::Key::Up) ){
                if ( Block.GetPos_y()>App.GetHeight()-20.2 ){
                    pressed_u=true;
                    Block.Set_Velocity_y(Gravity*-0.8);
                }
            }
            if( (Event.Type==sf::Event::KeyReleased) && (Event.Key.Code==sf::Key::Up) ){
                if ( pressed_u==true  ){
                    if(Block.GetVelocity_y()<=0)
                        Block.Set_Velocity_y(0); // Falls Sprung immer gleich hoch sein soll, diese Zeile auskommentieren
                    Block.ResetTime_y();
                    pressed_u=false;
                }
            }

        }


    }
    Block.Show_Status();

return EXIT_SUCCESS;
}


string Display_Energy(Object *objct){
    ostringstream os;
    os<< "E.x: " << objct->GetEnergy_x()<<"Nm \n"
    << "E.y: ";
    if (objct->GetEnergy_y()<0.1)
        os << "0";
    else
        os<<objct->GetEnergy_y();
    os<<"Nm\n ";
    //<< "Z-Energy: " << objct.GetEnergy_z()<<"N \n";


    return os.str();
}

string Display_Velocity(Object *objct){
    ostringstream os;
    os<< "V.x: " << objct->GetVelocity_x()*3.6/Factor<<"Km/h \n"
    << "V.y: " << objct->GetVelocity_y()*3.6/Factor<<"Km/h \n";
    //<< "Z-Energy: " << objct.GetEnergy_z()<<"N \n";

    return os.str();
}


Sorry für die Länge, aber ich hab halt echt keine Ahnung woran es liegen könnte...

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

22.04.2011, 22:48

Tja, ich würde ja jetzt mal vermuten, dass das ein typisches Problem eines inkrementellen Systems ist (welches für den nächsten Frame auf den Daten des letzten Frames basiert). Eventuell wäre da die Überlegung zu einem Absolut-Zeit-abhängigen System zu wechseln statt auf einem System mit Relativ-Zeit zu arbeiten.
Vielleicht ist da aber auch einfach nur irgendwo ein Bug, so detailliert habe ich mir den Code nicht angeschaut. Klingt aber meiner Meinung nach typisch für inkrementelle Systeme.
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]

3

26.04.2011, 18:28

Hm okay. .... Du hast nicht rein zufällig interessante Lektüre zu dem Thema? Ich habe gerade mal auf die schnelle im Netz gesucht, aber noch nichts super tolles gefunden. Das werde ich bestimmt, wenn ich da etwas Zeit rein investiere, aber vllt hast Du ja direkt was... :)

Nexxtron

Alter Hase

Beiträge: 424

Wohnort: Heilbronn

Beruf: Student - Software Engineering

  • Private Nachricht senden

4

26.04.2011, 18:38

ich würde dir raten sf::RenderWindow::GetInput() Methode für Key Events zu nehmen....könnte vllt. das Problem beheben...
New Project: Operation CityRacer

Nexxtron

Alter Hase

Beiträge: 424

Wohnort: Heilbronn

Beruf: Student - Software Engineering

  • Private Nachricht senden

5

26.04.2011, 18:38

ich würde dir raten sf::RenderWindow::GetInput() Methode für Key Events zu nehmen....könnte vllt. das Problem beheben...

Edit: 2-fach Post bitte löschen ;)
New Project: Operation CityRacer

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

6

26.04.2011, 18:54

Hier passiert nichts zufaellig. Wenn das Programm den gleichen Input bekommt, gibt es auch den gleichen Output. Dummerweise ist der Input fuer "GetElapsedTime()" so ziemlich alles, was Windows + alle anderen Tasks tun und damit unkontrollierbar. Daher wirst du selten den gleichen Output sehen.

Beiträge: 721

Wohnort: /dev/null

Beruf: Software-Entwickler/Nerd

  • Private Nachricht senden

7

26.04.2011, 19:18

Das ist C-Code, da gibt's sehr wohl Nebeneffekte, die man nicht verhindern kann. Zusätzlich sind komplexe elektronische Geräte sowieso einem kleinen Zufalls(Quasi)-Faktor unterworfen. Haskell läuft im Kern zum Beispiel komplett ohne Nebeneffekte. :)

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

8

26.04.2011, 19:27

Das ist C-Code, da gibt's sehr wohl Nebeneffekte, die man nicht verhindern kann. Zusätzlich sind komplexe elektronische Geräte sowieso einem kleinen Zufalls(Quasi)-Faktor unterworfen. Haskell läuft im Kern zum Beispiel komplett ohne Nebeneffekte. :)
stimmt, darum kann in C-Code so gute Zufallsgeneratoren schreiben, was in Haskell ja nicht geht...

Werbeanzeige