|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 15.09.2004, 13:15 Titel: Timing: Geht das so? |
|
|
Hi,
ich habe mal eine grundlegende Frage zum Timing. Ich mache es immer so, ich habe eine "Timer"-Klasse:
Code: |
class Timer
{
unsigned timo;
unsigned interval;
public:
void Start(const int& intervall);
bool Abgelaufen();
};
void Timer::Start(const int &intervall)
{
timo=timeGetTime();
interval=intervall;
}
bool Timer::Abgelaufen()
{
if(timeGetTime()-timo>=interval)
{
timo=timeGetTime();
return 1;
}
return 0;
}
|
Dort ruf ich dann Start auf (in diesem Fall 1 Millisekunde) und mach dann in der While Schleife beispielsweise:
[cpp]
if(timer.Abgelaufen()) x+=5;
[/cpp]
oder so.
Also soll er sich jede Millisekunde um 5 Pixel bewegen (nur so als Beispiel). Dann zeichne ich einfach alles und die Framerate kann mir egal sein. Kann man das so machen? Weil ich ja überall gelesen habe, dass man da irgendwie die Framerate einbeziehen muss etc... Ich habe nämlich jetzt das Problem, dass sich die Figur ziemlich ruckelig springt, fällt und bewegt, wenn ich die Timerabfrage wegmache, ist schön flüssig, aber das würde ja dann auf jeden Computer anders schnell laufen, was ich ja nicht will, also kann man das so machen oder muss man es ganz anders machen? _________________ http://www.sieder25.org/ (Siedler 2 - Remake) |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 15.09.2004, 13:24 Titel: Re: Timing: Geht das so? |
|
|
OLiver hat Folgendes geschrieben: | Dann zeichne ich einfach alles und die Framerate kann mir egal sein. |
Ganz so ist es nicht. Du solltest natürlich schon darauf achten, dass die Framerate im "normalen" Bereich bleibt. D.h., wenn du nicht genug Optimierungen anstellst/langsame Zeichenfunktionen verwendest, dann geht die Framerate ja trotzdem schnell in den Keller.
OLiver hat Folgendes geschrieben: | Ich habe nämlich jetzt das Problem, dass sich die Figur ziemlich ruckelig springt, fällt und bewegt, wenn ich die Timerabfrage wegmache |
Ich mache es z.Z. auch so und bei mir funzt es flüssig...
Zeig doch mal den Code, in dem du die Timerklasse einsetzt. Vielleicht stimmt da was nicht ganz _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 15.09.2004, 13:38 Titel: |
|
|
Es ist ein abgespeckte Version von Hazels Demoprogramm und es sieht ja auch ganz gut aus wie der springt, aber es ruckelt halt wie gesagt noch ziemlich dolle.
Code: |
#include <windows.h>
#include "os_spiele.h"
#include <string>
Direct3D d3d;
Tastatur tast;
HWND myhwnd;
Sprite figur;
bool jumps=0;
float jumppower=0;
// Koordinaten und die Geschwindigkeiten des Spielers
float x=500,y=0,sx=0,sy=0;
// Timer für Bewegungen
Timer moving;
// Tastenarray
bool tasten[256];
// Breite und Größe des Spielers
#define WIDTH 70
#define HEIGHT 70
const float GRAVITY = .2f; // Schwerkraft. Wird als Beschleunigungsfaktor verwendet
const float AIRCONTROL = 0.15f; // Wieviel kontrolle über die Bewegung auf der X-Achse
// hat der Spieler, wenn er in der Luft ist(Beschleunigung)
const float JUMPPOWER = 10.0f; // Sprungkraft des Spielers
bool Stand();
LRESULT CALLBACK MessageHandler(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
DestroyWindow(hwnd);
break;
}
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX wc={
sizeof(WNDCLASSEX),
CS_HREDRAW|CS_VREDRAW,
MessageHandler,
0,
0,
hInstance,
LoadIcon(NULL,IDI_WINLOGO),
LoadCursor(NULL,IDC_ARROW),
(HBRUSH)GetStockObject(WHITE_BRUSH),
NULL,
"WindowClass",
LoadIcon(NULL,IDI_WINLOGO) };
RegisterClassEx(&wc);
myhwnd=CreateWindowEx(NULL,"WindowClass","Jumptest",WS_POPUP | WS_VISIBLE,0,0,1024,768,NULL,NULL,hInstance,NULL);
if(!d3d.Create(myhwnd,1024,768,75))
return 1;
if(!tast.Create(hInstance,myhwnd))
return 2;
if(!d3d.CreateSprite("figur.png",70,70,figur,0xFFFF00FF))
return 3;
MSG msg;
ShowCursor(0);
moving.Start(1);
while(msg.message!=WM_QUIT)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Tasten holen
tast.GetDevice((LPVOID)&tasten);
if(moving.Abgelaufen())
{
// Spieler bewegen
y+=sy;
// Wenn der Spieler sich in der Luft befindet
if(!Stand())
{
// Schwerkraft wirken lassen
sy+=GRAVITY;
}
// Wenn der Spieler fällt
if(sy>0)
{
// ggf zum Stehen bringen
if(Stand())
{
sy=0;
}
}
else if(!sy)
{
if(tasten[DIK_SPACE])
{
jumps=1;
jumppower+=1;
if(jumppower==JUMPPOWER)
{
sy= -JUMPPOWER;
jumppower=0;
jumps=0;
}
}
else
{
if(jumps)
{
sy= -jumppower;
jumppower=0;
jumps=0;
}
}
}
// Nach rechts oder links laufen
if(tasten[DIK_RIGHT])
x+=5;
if(tasten[DIK_LEFT])
x-=5;
}
// Bildschrirmgrenzen einhalten
if(x<0)
x=0;
else if(x+WIDTH>1024)
x=1024-WIDTH;
d3d.BeginScene();
// Hintergrund mit Schwarz füllen
d3d.FillBackBuffer(0xFF000000);
d3d.DrawSprite(figur,x,y);
d3d.EndScene();
d3d.Present();
}
}
return 0;
}
bool Stand()
{
if(y+HEIGHT<768)
return 0;
else
{
y=768-HEIGHT;
return 1;
}
}
|
|
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 15.09.2004, 13:55 Titel: Re: Timing: Geht das so? |
|
|
Mit dem Code scheint alles in Ordnung zu sein.
Allerdings bin ich mir gerade nicht sicher, ob das beim Kontruktor der Timer-Klasse so einfach geht, wenn du das als Referenz übergibst.
Die '1', die du übergibst, muss ja dauerhaft im Speicher sein, damit der Timer auf diese Adresse zugreifen kann.
Vielleicht musst du mal versuchen, das ohne Referenz zu machen:
OLiver hat Folgendes geschrieben: | Code: |
class Timer
{
// [...]
void Start(const int intervall);
};
void Timer::Start(const int intervall)
{
timo=timeGetTime();
interval=intervall;
} |
|
_________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 15.09.2004, 14:07 Titel: |
|
|
Hmm, das glaub ich nich, denn es wird ja nur als Referenz übergeben und gespeichert als normale Membervariable , die dann den Inhalt von der Referenz bekommt, ich denke schon, dass mit der Timerklasse alles in Ordnung ist, vielleicht is eine Millisekunde auch zu viel, dass es ruckelt, vielleicht muss es noch genauer werden? Ich weiß es nicht |
|
Nach oben |
|
|
MATTT Junior JLI'ler
Anmeldedatum: 18.06.2003 Beiträge: 59
Medaillen: Keine
|
Verfasst am: 15.09.2004, 15:10 Titel: |
|
|
Wenn du deine Timer auf 1 Millisekunde stellt und dein Computer schafft es nicht (und das tuht er auch auch nicht!) innerhalb 1 ms einen Frame zu generieren.
Ein Beispiel: Dein Spiel schafft eine Framerate von 90! Das wären
1s/90 = 1000ms/90 = 11.11111111...ms -> also mehr als 1 ms.
Die Lösung des Problems wäre, dass du einen höheren Intervall setzt.
Oder (noch besser) du machst es so:
Code: |
x += (verstrichene_zeit_seit_letzte_mal / intervall) * geschindigkeit_pro_intervall;
|
|
|
Nach oben |
|
|
PeaceKiller JLI Master
Alter: 35 Anmeldedatum: 28.11.2002 Beiträge: 970
Medaillen: Keine
|
Verfasst am: 16.09.2004, 12:27 Titel: |
|
|
Du kannst es ja auch mit meinem Timer versuchen der benützt den Performance Counter.
http://www.jliforum.de/board/viewtopic.php?t=2466 _________________ »If the automobile had followed the same development cycle as the computer, a Rolls-Royce would today cost $100, get a million miles per gallon, and explode once a year, killing everyone inside.«
– Robert X. Cringely, InfoWorld magazine |
|
Nach oben |
|
|
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 16.09.2004, 14:48 Titel: |
|
|
@MATTT:
Ja, ich weiß, dass er einen Frame nicht in einer Millisekunde darstellen kann, das Komische ist ja nur, dass, wenn ich die Timerabfrage wegmache es flüssig läuft, obwohl er ja eh nicht jede Millisekunde dort ankommt. Ich habe mal die 2 Programme hochgeladen, einmal mit und einmal ohne Timerabfrage (Springen mit Leertaste):
http://www.oliversseite.000k.net/jumping.rar |
|
Nach oben |
|
|
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 16.09.2004, 16:17 Titel: |
|
|
Komisch, wenn ich als Bildwiedherholungsfrequenz 60 statt 75 einstelle bewegt es sich flüssig?
Steckt da irgendeine Logik dahinter??? |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 16.09.2004, 19:52 Titel: |
|
|
Das klingt stark danach, dass vsync dahinter steckt.
Vielleicht funzt es wie gewünscht auch bei anderer Frequenz, wenn du es deaktivierst _________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 17.09.2004, 12:20 Titel: |
|
|
Dumme Frage aber was ist denn das? |
|
Nach oben |
|
|
OLiver Super JLI'ler
Alter: 33 Anmeldedatum: 29.06.2003 Beiträge: 306 Wohnort: Jena Medaillen: Keine
|
Verfasst am: 17.09.2004, 12:29 Titel: |
|
|
Gut hat sich geklärt aber wie kann man das abstellen? |
|
Nach oben |
|
|
TheMillenium Dark JLI'ler
Anmeldedatum: 21.07.2002 Beiträge: 1427 Wohnort: World Medaillen: Keine
|
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 17.09.2004, 19:34 Titel: |
|
|
Entweder bei der DirectX initialisierung, oder beim anzeigen des Bildschirms (warten auf nächstes Bild, oder sofort anzeigen)
Ich würde auch die Variante aus dem zweiten Buch bevorzugen. Ohne Framebegrenzung oder so: Einfach die Zeit der letzten Frame messen und alle Bewegungen davon abhängig machen. Ungefähr so:
Position += 5*(Dauer der letzten Frame)
Dann ist es immer gleich schnell, egal wie viele Frames und eigentlich immer flüssig.
Einfach die Funktion der Systemzeit anschauen, am Anfang und am ENde der Frame messen und differenz ausrechnen. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 17.09.2004, 20:09 Titel: |
|
|
Jonathan_Klein hat Folgendes geschrieben: | Ich würde auch die Variante aus dem zweiten Buch bevorzugen. Ohne Framebegrenzung oder so: Einfach die Zeit der letzten Frame messen und alle Bewegungen davon abhängig machen. Ungefähr so:
Position += 5*(Dauer der letzten Frame)
Dann ist es immer gleich schnell, egal wie viele Frames und eigentlich immer flüssig.
Einfach die Funktion der Systemzeit anschauen, am Anfang und am ENde der Frame messen und differenz ausrechnen. |
Das hat allerdings (manchmal) einen kleinen Nachteil.
Dazu müsste man auf jeden Fall Fließkommavariablen benutzen.
Denn wenn du z.B. (bei einem 2D-Spiel) vorgesehen hast, ein Objekt alle 100 Millisekunden um einen Pixel zu bewegen, was machst du dann nach 50 Millisekunden?
_________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|