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

24.01.2016, 16:58

SDL_GetTicks(); Problem.

Halli Hallo :)

Ich bin neu was die Spiele-Entwicklung mit SDL2 angeht.
Bisher habe ich mit dem GameMaker 8 Minispiele mit der Sprache C++ erstellt.
Nun wollte ich selbst ein Spiel von Anfang an schreiben und bin dabei auf ein Problem gestoßen.

Die SDL Funktion -> SDL_GetTicks();

Ich arbeite mit der VisualStudio Express 2012 Version und SDL2.
Ich habe bereits ein Fenster erzeugt, und habe auch schon ein Image geladen den ich fließend bewegen kann. Nur ist das Problem, das sich das Bild zu schnell bewegt und ich einfach nicht schaffe die Geschwindigkeit so zu regulieren, dass es sich mit einer normalen Geschwindigkeit bewegt.

Ich habe schon gegooglet, und auf YouTube nach hilfreichen Tutorials gesucht aber bisher habe ich nichts gefunden was mich weiter bringt.

So sieht mein Code (SDL_GetTicks) aus den ich für mein Spiel verwenden will:

//Zeigt die Zeit in Sekunden an.
CurrentTime = SDL_GetTicks() / 1000.0f;

//DeltaTime.
DeltaTime = (SDL_GetTicks() - CurrentTime);

und DeltaTime kombiniere ich dann mit der Geschwindigkeit des spielers-> float Movespeed = 1.0f;

also so:
texr.x += Movespeed * DeltaTime;

Das Problem hierbei ist, das es sich entweder gar nicht bewegt, oder sich einfach viel zu schnell bewegt, oder das es sich zuerst langsam bewegt und von zeit zur zeit immer schneller und schneller wird.

Was ich brauche ist eine ganz einfache (nichts hochkomplexes) erklärung, wie man SDL_GetTicks verwendet, also wo man es einsetzt, wie man es einsetzt und ein einfaches beispiel also eigentlich die Grundlagen die ich dann später selbst zu etwas komplexeren aufbauen kann.

Kann mir bitte jemand helfen was die Anwendung von SDL_GetTicks() angeht?
Ich wäre sehr dankbar.

MfG Seddy :)

PS: ich weiß das es hier auch schon das Thema gibt, aber da habe ich auch nichts gefunden was mich weiter bringt.

2

24.01.2016, 17:21

//Zeigt die Zeit in Sekunden an.
CurrentTime = SDL_GetTicks() / 1000.0f;

//DeltaTime.
DeltaTime = (SDL_GetTicks() - CurrentTime);

und DeltaTime kombiniere ich dann mit der Geschwindigkeit des spielers-> float Movespeed = 1.0f;

also so:
texr.x += Movespeed * DeltaTime;

Der Debuger würde dir hier die Wert Verraten, dann würde dir vielleicht auffallen das DeltaTime = (SDL_GetTicks() - CurrentTime); Relative groß ist, da du hier Sekunden von Millisekunden Subtrahiertst.

Edit:
Übrigens DeltaTime = (SDL_GetTicks() - CurrentTime); wenn beides die selben Einheiten hat dann ist das Ergebnis 0 wenn du beides im selben Frame berechnet wird.
Deshalb wäre es Sinnvoll die Zeit vom Frame vorher bis jetzt zu berechnen.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Koschi« (24.01.2016, 17:29)


3

24.01.2016, 17:35

Ok danke für deine Antwort :)

Kannst du vielleicht ein einfaches Beispiel zeigen wie man die Zeit berechnet und für die Movements verwendet?

Ich habe das Beispiel übrigens aus einem Tutorial, dass Komische ist nur das es in dem Tutorial sehr gut geklappt hat.

Also wenn das was ich eben beschrieben habe nicht funktioniert, wie muss ich das dann machen? Kannst du mir da evtl. weiter helfen?

4

24.01.2016, 17:43

Ich verweise mal auf einen Wiki Artikel von SPPRO.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

5

24.01.2016, 18:09

Danke aber auch das ist mir etwas zu unübersichtlich...
Kann mir jemand bitte einen ganz einfachen Code bzw. ein einfaches Beispielcode zeigen (etwas wirklich ganz kleines) um mir die Grundlagen zu erklären?

Sorry aber das was ich auf der WikiSeite eben gelesen habe bringt mich kein bisschen weiter weil der Code ähnlich aufgebaut ist wie meiner den ich zuvor schon gepostet habe aber wie ich bereits erwähnt habe funktioniert das nicht.

"Konstante Logikrate = 60
Konstante Zeitschritt = 1 / Logikrate
Zeitkonto = 0

Prozedur AktualisiereSpielzustand(Δt):
Zeitkonto = Zeitkonto + Δt
Solange Zeitkonto ≥ Zeitschritt:
ZeitschrittDurchführen()
Zeitkonto = Zeitkonto - Zeitschritt"

So einen ähnlichen Code hatte ich schon aus einem YouTube Tutorial gesehen und der hat auch nichts gebracht...
Die Geschwindigkeit war dann viel zu schnell und ich wusste nicht wie man es reguliert da es nicht so gut erklärt wurde.

Ich möchte nur wissen wie man die zeit so berechnet, das es zusammen mit der Spieler Geschwindigkeit in einer vernünftigen Geschwindigkeit läuft.
Die ganzen WikiArtikel, google Youtube usw habe ich alles schon durch, ich sitze schon seit 2 Wochen dran und möchte wirklich nru etwas ganz einfaches bzw. ein Rechenweg und wie man den Code + der Geschwindigkeit einsetzt.

6

24.01.2016, 18:19

C-/C++-Quelltext

1
2
3
4
5
// deltaT in sekunden
float deltaT = (aktuelleZeit - alteZeit) / 1000;
alteZeit = aktulleZeit;

Figur.x = Figur.x + deltaT * MoveSpeed;


Zum Verständnis:
Frame 1
AktuelleZeit = 500
AlteZeit = 0
MoveSpeed = 1.0f

Dann bewegt sich die Figur 0.5 nach rechts.

Frame 2
AktuelleZeit = 1000
AlteZeit = 500
MoveSpeed = 1.0f

Figur bewegt sich wieder um 0.5 nach rechts.

usw...

Du musst mein PseudoCode nur umsetzten, ich hoffe du verstehst damit wie es funktionieren kann.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

7

24.01.2016, 18:34

Ich habe es jetzt so eingesetzt:

#include <SDL.h>
#include <SDL_image.h>
#include <iostream>

#define Bild1 "asd.png"

using namespace std;

int main(int argc, char* argv[])
{
SDL_Window *Window = NULL;
SDL_Renderer *Render = NULL;
SDL_Texture *Image = NULL;

float AktuelleZeit = SDL_GetTicks();
float AlteZeit = 0;
float DeltaTime = (AktuelleZeit - AlteZeit) / 1000;
AlteZeit = AktuelleZeit;

const float Movespeed = 1.0;

if(SDL_Init(SDL_INIT_VIDEO) == -1)
{
return -1;
}

Window = SDL_CreateWindow ("Fenster",100, 100, 500, 500, 0);
Render = SDL_CreateRenderer (Window, -1, SDL_RENDERER_ACCELERATED);

Image= IMG_LoadTexture (Render, Bild1);

SDL_Rect texr; texr.x = 100; texr.y = 100; texr.w = 150; texr.h = 150;

bool Fensterläuft = true;

while(Fensterläuft)
{
SDL_Event Event;

while(SDL_PollEvent(&Event))

switch(Event.type)
{

case SDL_QUIT:
{
Fensterläuft = false;
}break;
}

const Uint8 *Taste = SDL_GetKeyboardState(NULL);

if (Taste[SDL_SCANCODE_RIGHT])
{
texr.x = texr.x + DeltaTime * Movespeed;
}

if (Taste[SDL_SCANCODE_LEFT])
{
texr.x -= Movespeed;
}

if (Taste[SDL_SCANCODE_UP])
{
texr.y -= Movespeed;
}

if (Taste[SDL_SCANCODE_DOWN])
{
texr.y += Movespeed;
}

else
{
texr.x == 0;
texr.y == 0;
}
SDL_RenderClear(Render);
SDL_RenderCopy(Render, Image, NULL, &texr);
SDL_RenderPresent(Render);

}
SDL_DestroyTexture(Image);
SDL_DestroyRenderer(Render);
SDL_DestroyWindow(Window);

return 0;
}

Jetzt kam wieder das Problem das es sich keinen Pixel gerührt hat als ich nach rechts gedrückt habe.
Habe ich da etwas falsch eingesetzt (an der Rechnung kann es ja nicht liegen) oder muss man da irgendetwas noch einstellen?

8

24.01.2016, 18:49

Wenn ich dein Code sehe (der sich besser lesen lässt in Code-Tags) dann würde ich behaupten du hast da ganze Konzept noch nicht Verstanden!

1. Die Berechnung an sich ist Richtig, nur soll sie jedes Frame (also jede While-Schleifen durchlauf) berechnet/aktualisieren werden.
2. Wird dein TextrueRect bewegt aber nicht dein Bild weil es da kein "Verknüpfung" gibt (weiß nicht wie SDL das im detail macht)
3. texr.x == 0; texr.y == 0; ist Falsch, das '==' ist ungleich '='
4. wird (wenn 3 Korrigiert ist) dein Texturerect wenn keine Eingabe erfolgt auf 0 gesetzt, was bestimmt auch nicht in deinem Sinn ist.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

9

24.01.2016, 18:56

Image= IMG_LoadTexture (Render, Bild1);
SDL_Rect texr; texr.x = 100; texr.y = 100; texr.w = 150; texr.h = 150;

Das mit dem Bild bzw. Rechteck ist schon richtig, weil ohne zeit bewegt sich das Bild ganz normal, nur bewegt es sich nicht so wie ich es will wenn ich die Zeit einsetze.

Also müssten die Zeitangaben in der while-Schleife stattfinden richtig?
Also so hier:

const float Movespeed = 1.0;

if(SDL_Init(SDL_INIT_VIDEO) == -1)
{
return -1;
}

Window = SDL_CreateWindow ("Fenster",100, 100, 500, 500, 0);
Render = SDL_CreateRenderer (Window, -1, SDL_RENDERER_ACCELERATED);

Image= IMG_LoadTexture (Render, Bild1);

SDL_Rect texr; texr.x = 100; texr.y = 100; texr.w = 150; texr.h = 150;

bool Fensterläuft = true;

while(Fensterläuft)
{
float AktuelleZeit = SDL_GetTicks();
float AlteZeit = 0;
float DeltaTime = (AktuelleZeit - AlteZeit) / 1000;
AlteZeit = AktuelleZeit;
...

Und ja du hast ja recht, ich habe das mit der Zeit nicht verstanden deswegen ja auch das Thema weil ich Hilfe brauche ^^

Wäre das so wie ich das jetzt geschrieben habe richtig?

10

24.01.2016, 19:00

"4. wird (wenn 3 Korrigiert ist) dein Texturerect wenn keine Eingabe erfolgt auf 0 gesetzt, was bestimmt auch nicht in deinem Sinn ist."

nein es bleibt an der stelle wo sie zurzeit ist, wenn ich es ganz normal ohne zeit laufen lasse.

und ja "==" ist nicht gleich "=" das weiß ich da "=" eine zuweisung ist. es geht ja darum, das bild zu bewegen, und wenn es nicht bewegt wird (else) die geschwindigkeit auf 0 zu setzen. das ist alles soweit richtig das habe ich ausgetestet und es läuft genau so wie ich es haben wollte also einwandfrei und für mich perfekt.
nur das mit der zeit kriege ich nicht hin das ist das einzige problem der rest funktioniert an sich sehr gut.
nur will ich den rest einfach mit der zeit verknüpfen so das ich die geschwindigkeit selbst regulieren kann weil das bild sich ohne zeit viel zu schnell bewegt ^^

Werbeanzeige