Softwaretechnologie II (Teil 1): Simulation und 3D Programmierung Medienwiss./Medieninformatik AM3 Visuelle Programmierung I Referent: Janek Rudolf.

Slides:



Advertisements
Ähnliche Präsentationen
1. Etikette Was muss man tun, wenn man sieht, dass ein Ball in die Richtung von Menschen fliegt? Was hat ein Flight auf einem voll besetzten Platz zu.
Advertisements

Einführung in die Programmiersprache C/C++
Klassen - Verkettete Liste -
Hochschule Fulda – FB ET Sommersemester 2010
Forschungszentrum caesar
Sortieren I - Bubblesort -
C Tutorium – Fehlerbehandlung – Knut Stolze. 2 Grundsatz Also ist auch nach jedem Funktionsaufruf auf Fehler zu prüfen!! Jeder(!) Funktionsaufruf kann.
Professional XNA Game Programming
Suche in Texten (Stringsuche )
Ultris Version 8: Erzeugen der Formen und Anzeigen der Vorschau
Ultris V10 Bewegen, Drehen und Kollisionserkennung.
Sortierverfahren Richard Göbel.
Java: Dynamische Datentypen
Listen Richard Göbel.
REKURSION + ITERATION. Bemerkung: Die in den folgenden Folien angegebenen "Herleitungen" sind keine exakten Beweise, sondern Plausibilitätsbetrachtungen.
Strukturen. In einer Struktur kann eine beliebige Anzahl von Komponenten (Daten) mit unterschiedlichen Datentypen (im Gegensatz zu Feldern) zusammengefaßt.
Polymorphie (Vielgestaltigkeit)
Polymorphie (Vielgestaltigkeit)
V10: Bewegen der Formen und Kollisionserkennung Steuerung der Spielsteine durch Tastenbefehle (Übersicht der Befehle unter der Hilfe)
V09 Fallende Formen, Geschwindigkeitsregelung und Timing Daniel Ebner Spieleprogrammierung mit DirectX und C++
Softwaretechnologie II WS 08/09 SpieleProgrammieren UlTris V07 Reihen vorbelegen, Spielfeld anzeigen und Punktestand ausrechnen Sibylle C. Schellhorn,
Processing: Arrays & Laden von Dateien Aufbauend auf dem Beispiel: File I/O LoadFile1.
Softwaretechnologie II (Teil 1): Simulation und 3D Programmierung
Spieleprogrammierung mit DirectX und C++
V03 Laden und Speichern von Spielfeldern und der Spielfeldeditor.
Zusammenfassung Vorwoche
Wir müssen also überlegen: Implementierung der Knoten, Implementierung der Kanten, daraus: Implementierung des Graphen insgesamt. Annahme: die Knoteninhalte.
Einführung in die Programmierung Datensammlung
Einführung MySQL mit PHP
3D Programmierung Version 12 - Highscores. Die vom Spieler erzielte Punktzahl wird mit 5 vorgegebenen Punktzahlen verglichen und, falls nötig, in die.
Java programmieren mit JavaKara
Anlegen von Ordnern, speichern und Öffnen von Bildern und Briefen
Ich möchte gerne mehrere Bilder auf ein Folie
XNA 3D Tutorial Anzeigen eines Objektes. Inhalt Lernen Sie, wie Sie Modelle implementieren. Initializing Lernen Sie, wie Sie Modelle aus der Content Directory.
Universität zu Köln Institut für Historisch-Kulturwissenschaftliche Informationsverarbeitung Prof. Dr. Manfred Thaller AM 3 Übung: Softwaretechnologie.
OMRON 1 FINS Befehle schicken mit CX – Server Lite Aufgabe :
Moin. Ich benutze PPT 2002 und möchte drei Bilder nacheinander 1
Abteilung für Telekooperation Übung Softwareentwicklung 1 für Wirtschaftsinformatik Dr. Wieland Schwinger
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Tormann Lorenz Maierhofer Die Test-Umgebung Tor: 5x Roboter-Durchmesser Ball: Wird jeweils in Richtung einer zufälligen Position im Tor geschossen.
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Universität zu Köln Historisch Kulturwissenschaftliche Informationsverarbeitung WS 12/13 Softwaretechnologie II (Teil 1): Simulation und 3D Programmierung.
Von der Planung bis zum Hauptmenü Seminar: Softwaretechnologie II Dozent: Prof. Manfred Thaller Referent: Jan Bigalke.
Grundlagen der Programmierung
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Einführung in die Programmierung
Informatik 1 Letzte Übung.
Vom Umgang mit Daten. public void myProgram() { int[] saeulenWerte = new int[world.getSizeX()]; for (int i = 0; i < saeulenWerte.length; i++) { saeulenWerte[i]
PHP: Operatoren und Kontrollstrukturen
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Ein PC-Game selber machen
Unity 4.x Cookbook Softwaretechnologie II (Teil 2) - Maximilian Berndt.
SFZ Sj 13/14 GZG FN W.Seyboldt 1 SFZ FN Sj. 13/14 Python Grundlagen.
SFZ FN Sj. 13/14 Python Grundlagen InfK12 Sj 13/14 GZG FN W.Seyboldt.
Musterlösung zum Arbeitsblatt Nr. 1
Das erste Spiel Universität zu Köln
Universität zu Köln Historisch-Kulturwissenschaftliche Informationsverarbeitung Softwaretechnologie II (Teil 1): Simulation und 3D Programmierung WS 2013/14.
1 VeranstaltungThemaTeilnehmerBetreuer AINF-Lehrgang PROGRAMMIEREN Martina GREILER Wolfgang KATOLNIG Peter RENDL Helfried TUISEL Peter ZYCH Heinz STEGBAUER.
Breakanoid – Bälle & Blöcke Universität zu Köln Historisch Kulturwissenschaftliche Informationsverarbeitung WS 12/13 Übung: Visuelle Programmierung I –
 Allgemein  Speicherung der Informationen  Die Schiffsysteme › Die Struktur SShipType › Die Struktur SWeaponType  Laden aus der INI- Datei  Die Klasse.
1. Charakteranimation 2. PlugIns schreiben und laden Universität zu Köln Institut für Historisch-Kulturwissenschaftliche Informationsverarbeitung WS 2010/2011.
Zufallsprogrammierung
GAME PROGRAMMING PATTERNS – FLYWEIGHT & OBSERVER Robert Nystrom Softwaretechnologie II Teil 2 Anike Schulz.
Game Loop & Update Method Robert Nystrom – Game Programming Patterns Universität zu Köln Historisch-Kulturwissenschaftliche Informationsverarbeitung SS.
Funktionen, Felder und Parameter- übergabe. Funktionsaufruf mit Feld als Parameter: Parameter = Name des Feldes.
Tutorium Software-Engineering SS14 Florian Manghofer.
Java Programme nur ein bisschen objektorientiert.
Pointer, Arrays und verkettete Listen. Mehrdimensionale Arrays  Pointer auf ein Array von Pointern  int32 **matrix = new int32*[3];  matrix: Zeiger.
Tutorium Software-Engineering SS14 Florian Manghofer.
Ein Spiel mit der SDL - Teil I. Ein Spiel mit der SDL  kostenlose Bibliothek – Simple DirectMedia Layer Grafik darstellen Benutzereingaben abfragen Sounds.
 Präsentation transkript:

Softwaretechnologie II (Teil 1): Simulation und 3D Programmierung Medienwiss./Medieninformatik AM3 Visuelle Programmierung I Referent: Janek Rudolf

Schritt 5: Bälle hinzufügen Schritt 6: Die Blöcke Schritt 7: Versuche Schritt8: Punkte Schritt 9: Sound für das Spiel Schritt10: Hier spielt die Musik

Erstellung von Klasse CBall CGame werden 16 CBall-Variablen in einem Array hinzugefügt U.a. BOOL m_bExists, BOOL m_bGrabbed, tbVector3 m_vPosition, tbVector3 m_vVelocity

Bewegung durch Methode CBall:Move Fortbewegung des Balls: m_vVelocity x vergangene Zeit seit letztem Frame(CBall:Move) + m_vPosition

Ball kann mit Wand und Schläger kollidieren Radius des Ballmodells = 0.25 Kollision mit der Wand tritt ein wenn: x-Koordinate des Positionsvektor +/ in oder hinter der Wand liegt. Rechts: x=9.25, Links: x=-9.25, z=4.25 Kollision mit dem Schläger tritt ein wenn: xBall >xSchläger-1.25 ^xBall<xSchläger +1.25^ zBall>zSchläger -0.25^zBall<zSchläger+0.25

Indem die z-Komponente des Geschwindigkeitsvektors umgekehrt wird, prallt der Ball ab

Ist m_vPosition <= -12, geht der Ball verloren Die Variable m_bExists wird auf FALSE gesetzt Im günstigsten Fall klebt danach ein neuer Ball auf dem Schläger Ist das der Fall, wird m_bGrabbed == TRUE und die move-Methode verlassen

// Bewegt einen Ball tbResult CBall::Move(float fTime) { // Wenn der Ball klebt: abbrechen! if(m_bGrabbed) return TB_OK; // Position verändern m_vPosition += m_vVelocity * fTime; // Wenn der Ball eine Wand berührt, prallt er ab. if(m_vPosition.x f <= -9.25f) {bWall = TRUE; m_vVelocity.x *= -1.0f; m_vPosition.x = -9.0f;} // Linke Wand if(m_vPosition.x f >= 9.25f) {bWall = TRUE; m_vVelocity.x *= -1.0f; m_vPosition.x = 9.0f;} // Rechte Wand if(m_vPosition.z f >= 4.25f) {bWall = TRUE; m_vVelocity.z *= -1.0f; m_vPosition.z = 4.0f;} // Obere Wand // Auch am Schläger prallt er ab (Natürlich!). if(m_vPosition.x >= m_pGame->m_vPaddlePos.x f && m_vPosition.x m_vPaddlePos.x f && m_vPosition.z m_vPaddlePos.z f && m_vPosition.z - m_vVelocity.z * fTime >= m_pGame->m_vPaddlePos.z f) // Es gibt eine Kollision! Wir kehren die z-Komponente des Bewegungsvektors um. m_vVelocity.z *= -1.0f; if(m_vPosition.z < -12.0f) { m_bExists = FALSE; } }

Implementieren der Methode Cball::Render tbMatrixTranslation(GetAbsPosition()) verschiebt Ballmodell an richtige Stelle Absolute Position des Balls wird gebraucht in Translationsmatrix, sonst ist sie relativ zum Schläger CGame::m_pBallModel->Render rendert danach den Ball

Erster Ball bei Eintritt ins Level, Zero Memory leert Array m_aBall Erstellung eines Balls durch Methode CGame::CreateBall mit Parametern der Position, des Geschwindigkeitsvektors und dem Zustand, ob angeklebt oder nicht Erster Ball: Relative Position zum Schläger(0,0, 0,25), Geschwindigkeitsvektor (0,0,0) und Zustand = Angeklebt

Erstellung einer Liste in Form des Arrays CGame::m_aBall mit 16 Elementen Mit m_bExists prüfen ob/wie viele Bälle existieren CGame::Move geht die 16 Elemente durch, wenn die Elemente existieren, Aufruf seiner Move-Funktion und Aufruf von CBall::Render

// Erstellt einen neuen Ball int CGame::CreateBall(tbVector3 vPosition, tbVector3 vVelocity, BOOL bGrabbed) { // Freien Ball suchen for(int iBall = 0; iBall < 16; iBall++) { if(!m_aBall[iBall].m_bExists) { // Freier Ball gefunden! Ausfüllen! m_aBall[iBall].m_bExists = TRUE; m_aBall[iBall].m_pGame = this; m_aBall[iBall].m_bGrabbed = bGrabbed; m_aBall[iBall].m_vPosition = vPosition; m_aBall[iBall].m_vVelocity = vVelocity; // Index des neuen Balls liefern return iBall; } // Kein Platz mehr! return -1; }

// Wenn die Leertaste gedrückt wurde, wird der klebende Ball // abgeworfen. if(g_pbButtons[TB_KEY_SPACE] && m_aBall[0].m_bExists && m_aBall[0].m_bGrabbed) { // Sound abspielen g_pBreakanoid->m_apSound[3]->PlayNextBuffer(); // Ball abfeuern! m_aBall[0].m_bGrabbed = FALSE; // Die Position eines klebenden Balls ist immer relativ // zum Schläger. Wir wandeln sie nun in eine absolute Position um. m_aBall[0].m_vPosition += m_vPaddlePos;

// Den Bewegungsvektor des Balls berechnen wir zufällig. m_aBall[0].m_vVelocity.x = tbFloatRandom(-4.0f, 4.0f); m_aBall[0].m_vVelocity.y = 0.0f; m_aBall[0].m_vVelocity.z = tbFloatRandom(8.0f, 10.0f); // Den Bewegungsvektor des Schlägers addieren m_aBall[0].m_vVelocity += m_vPaddleVel; // Dem Ball einen kleinen "Schubs" nach vorne geben m_aBall[0].m_vPosition.z += 0.1f; }

Erstellen der Klasse CBlock mit der einzigen Methode Render Variablen : m_iEnergy: Anzahl Energiepunkte M_itype: Typ des Blocks (1 blau, 2 orange, 3 grün, 4 gelb) type= Anzahl Energiepunkte tbVector3 m_vPosition: Position des Blocks auf dem Spielfeld CGame* m_pGame: Kopie des CGame-Zeigers

Erstellen eines Arrays mit 64 CBlock-Elementen (wie bei den Bällen) ZeroMemory setzt bei betreten des Levels alle Blöcke zurück Level wird in Zeilen bzw. Strings unterteilt – Jedes Zeichen im String = ein Block 1 Zeile = 9 Zeichen/Blöcke - Mehrere Zeilen = Level Funktion CGame::CreateBlockRow um die Blockreihe zu erstellen

// Erstellt eine Reihe von Blöcken tbResult CGame::CreateBlockRow(char* pcBlocks, tbVector3 vStartPos) { int iType; // Alle Zeichen im String durchgehen for(DWORD dwChar = 0; dwChar < strlen(pcBlocks); dwChar++) { // Wenn das Zeichen kein Leerzeichen ist... if(pcBlocks[dwChar] != ' ') { // Freien Block suchen for(DWORD dwBlock = 0; dwBlock < 64; dwBlock++) { if(m_aBlock[dwBlock].m_iEnergy <= 0) { // Freier Block gefunden - ausfüllen! // Zeichen im String in einen Blocktyp umwandeln. iType = 0; if(pcBlocks[dwChar] == '1') iType = 1; else if(pcBlocks[dwChar] == '2') iType = 2; else if(pcBlocks[dwChar] == '3') iType = 3; else if(pcBlocks[dwChar] == '4') iType = 4;

// Je nach Level die Blöcke erstellen switch(iLevel) { case 1: CreateBlockRow(" ", tbVector3(-8.0f, 0.0f, 2.0f)); CreateBlockRow(" ", tbVector3(-8.0f, 0.0f, 1.0f)); CreateBlockRow("12 21", tbVector3(-8.0f, 0.0f, 0.0f)); CreateBlockRow(" ", tbVector3(-8.0f, 0.0f, -1.0f)); break; case 2: CreateBlockRow(" 222 ", tbVector3(-8.0f, 0.0f, 1.0f)); CreateBlockRow(" ", tbVector3(-8.0f, 0.0f, 0.0f)); CreateBlockRow(" ", tbVector3(-8.0f, 0.0f, -1.0f)); CreateBlockRow(" ", tbVector3(-8.0f, 0.0f, -2.0f)); break;

Prüfung in CBall::Move, ob Ball und Block kollidieren Ist das der Fall, wird dem Block ein EP abgezogen, der Ball prallt ab Problem: Welcher Block und welche Seite des Blocks wird getroffen x-oder z-Komponente des Geschwindigkeitsvektors umkehren

Zuerst Bedingung setzen, ob der Ball überhaupt mit dem Block kollidieren kann Danach berechnen, wo der Ball den Block trifft, dazu die Minimalste Distanz von den 4 Blöcken zum Ball berechnen

Bei links oder rechts vom Block, Vorzeichenveränderung der x-Komponente, Bei oben oder unten vom Block, Vorzeichenveränderung der z-Komponente nach Kollision, dem Ball einen Schub in die richtige Richtung geben

// Kollision mit den Blöcken berechnen for(DWORD dwBlock = 0; dwBlock < 64; dwBlock++) { if(m_pGame->m_aBlock[dwBlock].m_iEnergy > 0) { vBlock = m_pGame->m_aBlock[dwBlock].m_vPosition; // Befindet sich der Ball im Kollisionsbereich? if(m_vPosition.x f >= vBlock.x - 1.0f && m_vPosition.x f <= vBlock.x + 1.0f && m_vPosition.z f >= vBlock.z - 0.5f && m_vPosition.z f <= vBlock.z + 0.5f) // Entfernung des Balls von allen Blockseiten berechnen fDistLeft = fabsf(m_vPosition.x f - (vBlock.x - 1.0f)); fDistRight = fabsf(m_vPosition.x f - (vBlock.x + 1.0f)); fDistTop = fabsf(m_vPosition.z f - (vBlock.z + 0.5f)); fDistBottom = fabsf(m_vPosition.z f - (vBlock.z - 0.5f));

// Minimale Distanz berechnen fMinDist = TB_MIN(fDistLeft, TB_MIN(fDistRight, TB_MIN(fDistTop, fDistBottom))); // Wenn die Distanz zur linken oder rechten Seite am kleinsten ist... if(fMinDist == fDistLeft || fMinDist == fDistRight) { // Ball an der z-Achse abprallen lassen m_vVelocity.x *= -1.0f; // Dem Ball einen kleinen "Schubs" geben if(fMinDist == fDistLeft) m_vPosition.x -= 0.1f; else m_vPosition.x += 0.1f; } else { // Ball an der x-Achse abprallen lassen m_vVelocity.z *= -1.0f; // Dem Ball einen kleinen "Schubs" geben if(fMinDist == fDistTop) m_vPosition.z += 0.1f; else m_vPosition.z -= 0.1f; } // Dem Block einen Energiepunkt abziehen und Punkte addieren m_pGame->m_aBlock[dwBlock].m_iEnergy--; // Kollision ist immer nur mit einem einzigen Block möglich! break;

Wird ein Block zerstört (Energie =0), ermittelt tbIntRandom eine Zahl zwischen 1 und 14 Ist es eine 7, wird ein neuer Ball mit zufälliger Flugrichtung nach unten erstellt

Das Level ist geschafft, wenn alle Blöcke zerstört sind Dazu wird im m_aBlock-Array die Anzahl der Blöcke mit vorhandener Energie gezählt Sind alle Level geschafft, fängt der Spieler wieder bei Level 1 an

Variable CGame::m_iNumTries wird zu Beginn des Spiels auf 5 gesetzt In der Methode CGame:Move werden mit Hilfe einer for- Schleife die Bälle gezählt Ist die Anzahl der Bälle 0, so wird dem Spieler mit m_iTriesLeft- - ein Versuch abgezogen und ein neuer Ball auf den Schläger geklebt

Um das Spiel bei m_iTries == 0 zu beenden, hinzufügen der Variable BOOL m_bGameOver Bei TRUE wird in CGame::Render mit grüner und roter Schrift Game Over! ausgegeben

Um eine Punktzahl zu speichern, wurde bereits die Variable CGame::m_iScore erstellt Die vergangene Zeit eine Levels wird in der Variable CGame::m_fLevelTime gespeichert Umso weniger Zeit, desto mehr Punkte und pro Level Punkte extra Zudem 100 Punkte bei Treffen eines Blocks, bei Zerstörung

// Level 1 bringt Punkte, Level Punkte usw.. m_iScore += m_iLevel * 10000; // Je weniger Zeit man gebraucht hat, desto mehr Extrapunkte gibt's. // Bei x benötigten Sekunden gibt es den x-ten Teil von Punkten. m_iScore += (DWORD)( f * (1.0f / m_fLevelTime)); // Dem Block einen Energiepunkt abziehen und Punkte addieren m_pGame->m_aBlock[dwBlock].m_iEnergy--; m_pGame->m_iScore += 100; // Wenn der Block zerstört wurde, gibt es Extrapunkte if(m_pGame->m_aBlock[dwBlock].m_iEnergy <= 0) { m_pGame->m_iScore += m_pGame- >m_aBlock[dwBlock].m_iType * 1000;

Da alle Sounds schon geladen wurden, geht es nur noch um das abspielen Die Sounds, die im Array CBreakanoid::m_apSound[11] gespeichert sind, werden gebraucht für: CBreakanoid::m_apSound[2]: neuen Level betreten CBreakanoid::m_apSound[3]: Ball abfeuern CBreakanoid::m_apSound[4]: Ball geht verloren CBreakanoid::m_apSound[5]: Ball trifft Schläger CBreakanoid::m_apSound[6]: Extraball-Sound CBreakanoid::m_apSound[7]: Ball prallt an Wand ab CBreakanoid::m_apSound[8-11]: Ball trifft Block, 4 verschiedene Sounds

Das Abspielen des Sounds funktioniert, indem man PlayNextBuffer auf der tbSound_klasse aufruft Wenn der Ball einen Block berührt, wird durch Zufallsgenerator einer von 4 Tönen abgespielt: // Zufälligen "Pling"-Sound abspielen iSound = tbIntRandom(8, 11); iBuffer = g_pBreakanoid->m_apSound[iSound]- >PlayNextBuffer(); if(iBuffer != -1)

Die Musik ist als MP3(MUSIC.MP3) gespeichert Musik wird die komplette Zeit unverändert abgespielt Dafür muss die Variable tbMusic* m_pMusic in der CBreakanoid –Klasse abgelegt werden

Geladen und abgespielt wird sie in CBreakanoid::Load // Musik laden und gleich abspielen m_pMusic = new tbMusic; if(m_pMusic->Init("Data\\Music.mp3")) { // Fehler! TB_ERROR("Fehler beim Laden der Musik!", TB_ERROR); } m_pMusic->Play(); return TB_OK;

Danke für eure Aufmerksamkeit!!!