visual rekapitulation tag 1. erstellen eines vc - projekts 1.neues projekt => win32 – projekt...
Post on 06-Apr-2016
217 Views
Preview:
TRANSCRIPT
Visual RekapitulationTag 1
Erstellen eines VC - Projekts
1. Neues Projekt => Win32 – Projekt2. Anwendungseinstellungen => leeres
Projekt
„windows.h“
• abgespeckte MFC• #define WIN32_LEAN_AND_MEAN => Compilerdirektive, die MFC
nicht zu verwenden
„WinMain()“• zentrale Methode => gesamtes Programm wird innerhalb
dieser Methode ausgeführt• int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE
hprevinstance, LPSTR lpcmdline, int ncmdshow)
Argument Bedeutung / Funktion
hinstance Handle auf Prozess => eindeutige Identifikation
hprevinstance Handle auf die aufrufende Instanz eines Prozesses
lpcmdline Zeiger auf String, welcher die Kommandozeile enthält, die dem Prozess beim Start übergeben wird
ncmdshow Gestalt des Anwendungsfensters
„MessageBox()“• int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR
lpCaption, UINT uType)
Argument Bedeutung / Funktion
hWnd Handle des aufrufenden Programms, in welchem die Messagebox angezeigt werden soll => NULL bewirkt, dass das Fenster auf dem Desktop ausgegeben wird
lpText Ausgabetext
lpCaption Titel der Messagebox
uType Gestalt der Messagebox
Windows – Datentypen
• Standarddatentypen wie bool, int usw.• weitere Datentypen:
Datentyp Definition
LPARAM 32 – Bit Wert als FunktionsparameterLPCSTR Pointer auf konstante ZeichenketteLPSTR Pointer auf ZeichenketteLRESULT 32 – Bit Rückgabewert
s. Auflistung Seite 22
Ungarische Notation
• Notationsweise, bei der Variablen eines Datentyps immer die gleiche Präfix erhalten
• Beispiele:
Datentyp Präfix
Integer i
Char c
Function Pointer fn
Handle h
s. Auflistung Seite 23
3 Phasen des Spielablaufs
1. void Game_Init(void) => Initialisierungen• Engine – Einstellungen• DirectX – Einstellungen• etc.
2. void Game_Main(void)• Game Loop => Endlosschleife, die bis zum Beenden des Spiels
durchlaufen wird• Time – Based vs. Frame – Based Rendering
3. void Game_Shutdown()• Aufräumarbeiten nach Beenden des Spiels
Rendering – Methoden
• Forderung: Ein Spiel sollte auf allen Systemen mit der gleichen Geschwindigkeit laufen, wenn diese die minimalen Hardwarevoraussetzungen erfüllen!
• 2 Möglichkeiten des Rendering => Time – Based vs. Frame – Based Rendering
• beim Frame – Based Rendering beschränkt die Framerate die Geschwindigkeit des Spiels => diese wird softwareseitig festgelegt
• beim Time – Based Rendering wird die Geschwindigkeit des Spiels durch die Zeit bestimmt, die für das Rendern eines Frames benötigt wird => unabhängig von der Framerate
Time – Based Rendering
Definitionen• Framezeit
Zeit, die für Berechnung und Darstellung einer Spielszene benötigt wird
Synchronisation der Bewegungen mit nachfolgenden Frames• Framerate
Anzahl der Frames, die pro Sekunde geschrieben werden können => Frames per Second (fps)
je höher die Framerate, desto flüssiger die Darstellung der Spielszene
Framerate = 1000.0f / dt; => dt ist die Zeitspanne, die zur Berechnung eines Frames benötigt wird
Faktor 1000.0f dient der Umrechnung von Sekunden in Millisekunden
Time – Based Rendering
Ablauf• Bestimmung der Zeitspanne dt, welche zur Berechnung eines
Frames benötigt wird• Verwendung der Methode DWORD GetTickCount(void) => liefert
die Anzahl der Millisekunden, die seit dem Hochfahren des Rechners vergangen sind
• Initialisierung einer Variablen start_time mit der Zeit des Renderbeginns => Bildung der Differenz zwischen Starttime und dem Ende der Frameberechnung => Dauer der Berechnung eines Frames
• dt = GetTickCount() – start_time;
Game – Speed Faktor
• Steuerung der Spielgeschwindigkeit• Framezeit = 0.001f * GameSpeed * dt;• Framezeit ergibt sich aus der Zeit, die für die Berechnung eines
Frames benötigt wird, multipliziert mit einem konstanten Faktor • 0.001f dient der Umrechnung von Sekunden in Millisekunden• die Bestimmung einer maximalen Framerate durch die Gleichung
Framerate = 1000.0f / dt; ist beim Time – Based Rendering nicht zwangsläufig notwendig, kann aber bei Schwankungen der Framerate helfen, Ruckler zu verhindern
Frame – Based Rendering
• softwareseitige Bremse der maximalen Framerate• ist die Zeitspanne dt kürzer als die Zeit, die sich aus der Framerate
für die Berechnung eines Frames ergibt, verharrt das Programm in einer Warteschlange
• bsw. Framerate von 30 fps => 33 ms für die Berechnung eines Frames
• while((dt = GetTickCount() – start_time)<= InvMaxFrameRate);• dadurch können auch schnellere Systeme keine höheren
Framerates erreichen
Codebeispiele Frame – Based vs. Time – Based Rendering
start_time = GetTickCount(); //Initialisierung der start_time auf Beginn des Rendervorgangsif (RenderStyle == 1) // Frame – Based Rendering
{while ((dt = GetTickCount() – start_time) <= InvMaxFrameRate);FrameRate = 1000.0f / dt; // Bestimmung der FrameRateFrameTime = 0.001f * GameSpeed * dt; //Bestimmung der Frame – Zeit}
else if (RenderStyle == 2) // Time – Based Rendering{dt = GetTickCount() – start_time;FrameRate = 1000.0f / dt; // Bestimmung der FrameRateFrameTime = 0.001f * GameSpeed * dt; //Bestimmung der Frame – Zeit}
Aufräumarbeiten
• Freigabe aller verwendeten Ressourcen• Berücksichtigung der Tatsache, dass sich das Spiel in
unterschiedlichen Zuständen befinden kann bsw. Intro, Schlacht usw.
• je nach Zustand sind andere Aufräumarbeiten zu leisten
Windows - Anwendungen
• fensterbasiertes (Fenster werden erzeugt) und ereignisorientiertes (Ereignisse werden registriert und verarbeitet) Betriebssystem
Fenster• Eigenschaften werden in der Struktur WNDCLASSEX gespeichert• Registrierung des Fensters beim Betriebssystem über Methode
RegisterClassEx()• Erzeugung durch CreateWindowEx()
Eigenschaften von Fenstern
Eigenschaften von Fenstern
// Fenstereigenschaften festlegen:winclass.cbSize = sizeof(WNDCLASSEX);winclass.style = CS_HREDRAW | CS_VREDRAW ;
//bewirkt das Neuzeichnen des Fensters nach Skalierung
winclass.lpfnWndProc= WindowProc; //Name der WindowProc() Methode, die für die Nachrichtenverarbeitung zuständig ist
winclass.cbClsExtra= 0;winclass.cbWndExtra = 0;winclass.hInstance = hinstance; //Handle der Anwendungwinclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
„CreateWindowEx()“
Ereignisverarbeitung• für jeden laufenden Prozess wird beim Start eine Message Queue
angelegt• Ereignisse des Prozesses werden in Nachrichten umgewandelt und
in der Queue eingereiht• Abruf der Nachrichten durch Methoden GetMessage() oder
PeekMessage()• für die Behandlung müssen die Nachrichten übersetzt werden =>
TranslateMessage()• Übergabe an Windows durch DispatchMessage()• für die Bearbeitung der Message startet Windows die Call – Back
Funktion WindowProc(), welche in jedem Prozess definiert sein muss
• eine Call – Back Methode ist eine Methode, welche im laufenden Prozess definiert ist, allerdings durch eine externe Anwendung gestartet wird => in diesem Fall das Betriebssystem
• bei der Deklaration des Fensters muss daher der Name der Call – Back Methode übergeben werden
Nachrichtenverarbeitung
Nachrichtenverarbeitung Codebeispiel:while(TRUE)
{if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)
{if (msg.message == WM_QUIT) break;TranslateMessage();DispatchMessage();}
Game_Main();}
//msg ist eine Strukturvariable vom Typ MSG, in welcher die Nachrichtgespeichert wird//PM_REMOVE => Nachricht wird aus der Queue entfernt
„WindowProc()“• Call – Back Methode, welche die Nachrichten aus der Queue
verarbeitetExkurs:Handle of Device Context (HDC)• der Device Context ist eine Struktur, die Informationen enthält, wie
eine Grafik – oder Textausgabe erfolgen soll => bsw. Zeichenfarbe oder Zeichensatz
• der Gerätekontext ist die Verbindung zwischen einem Windows – Programm und einem Gerätetreiber
• das Anlegen eines HDC – Objekts ist notwendig, um bsw. ein Fenster zu zeichnen
• API – Methode BeginPaint() liefert bsw. ein Handle auf den DC zurück
„WindowProc()“LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){ PAINTSTRUCT ps; //Struktur, welche die notwendigen Zeicheninformationen
beinhaltet HDC hdc; //Anlegen eines HDC - Objekts // Nachrichtenverarbeitung switch(msg)
{ case WM_CREATE: //Erzeugen des Fensters
{ return(0); } break;
case WM_PAINT: //erneutes Zeichnen des Fensters nach Skalierung{
hdc = BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps);
return(0); } break;
case WM_DESTROY: //Beenden des Programms{ PostQuitMessage(0); return(0);}
} return (DefWindowProc(hwnd, msg, wparam, lparam));
Modularisierung
• Trennung von Deklarationen und Implementationen in Header – und Implementierungsdateien
• unflexibler Quellcode durch Verwendung der 3 Methoden Game_Init(), Game_Main() und Game_Shutdown()
diese 3 Methoden rufen ihrerseits die Methoden GameInitialisierungtsRoutine(), GameMainRoutine() und GameShutdownRoutine() auf
dadurch kann das Programmgerüst in anderen Projekten wiederverwendet werden
Auflösung und Rendermode
• Einstellungen werden aus einer externen Textdatei gelesen• Speicherung der Informationen in globalen Variablen => bsw.
screenwidth und screenheight • Verwendung der Variablen als Parameter für CreateWindowEx() –
Methode =>if (!(hwnd = CreateWindowEx(NULL, WINDOW_CLASS_NAME,
"My Game Shell", WS_OVERLAPPEDWINDOW | WS_VISIBLE , 0,0, screenwidht,screenheight, NULL, NULL, hinstance, NULL)))
Auflösung und Rendermode
• Config – Datei:Possible_Resolutions:Resolution_800_600_16Resolution_800_600_32Resolution_1024_768_16Resolution_1024_768_32Resolution_Nr: 1
• Auslesen durch fscanf – Methode => int fscanf ( FILE * stream , const char * format [ , argument , ...] );
• fscanf(dateiname, „%d“, &resolution) => durchsucht die Datei „dateiname“ bis zum ersten Linefeed nach Zeichen des Typs Integer und speichert diese in der Variablen „resolution“
• InitResoultion() wird aus der Methode WinMain() aufgerufen
Rendermode
• Analoges Vorgehen zu InitResolution()• Methode InitRenderOptions() wird allerdings aus der Methode
GameMainRoutine() aufgerufen• ausgelesene Informationen sind bsw. Art der Beleuchtung, Frame –
Based vs. Time – Based Rendering oder die Maximalanzahl der Frames (nur Frame – Based Rendering)
Fragen?
top related