34
Das erste Spiel Teil 3 (Scherfgen 531 - 552) Softwaretechnologie II (Teil 1): Simulation und 3D Programmierung Medienwiss./Medieninformatik AM3 Visuelle Programmierung I Referent: Janek Rudolf

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

Embed Size (px)

Citation preview

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

Das erste SpielTeil 3 (Scherfgen 531 - 552)

Softwaretechnologie II (Teil 1):

Simulation und 3D Programmierung

Medienwiss./Medieninformatik

AM3

Visuelle Programmierung I 

Referent: Janek Rudolf

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

Inhalt

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

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

Schritt 5: Bälle hinzufügen

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

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

Fortbewegung und Kollisionen des Balls

Bewegung durch Methode CBall:Move

Fortbewegung des Balls:

m_vVelocity x

vergangene Zeit seit letztem Frame(CBall:Move) + m_vPosition

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

Ball kann mit Wand und Schläger kollidieren

Radius des Ballmodells = 0.25

Kollision mit der Wand tritt ein wenn:

x-Koordinate des Positionsvektor +/- 0.25 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

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

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

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

Verlieren des Balls

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

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

// 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 - 0.25f <= -9.25f) {bWall = TRUE; m_vVelocity.x *= -1.0f; m_vPosition.x = -9.0f;} // Linke Wand

if(m_vPosition.x + 0.25f >= 9.25f) {bWall = TRUE; m_vVelocity.x *= -1.0f; m_vPosition.x = 9.0f;} // Rechte Wand

if(m_vPosition.z + 0.25f >= 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 - 1.25f &&

m_vPosition.x <= m_pGame->m_vPaddlePos.x + 1.25f &&

m_vPosition.z <= m_pGame->m_vPaddlePos.z + 0.25f &&

m_vPosition.z - m_vVelocity.z * fTime >= m_pGame->m_vPaddlePos.z + 0.25f)

// 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; }

}

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

Rendern

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

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

Die Bälle

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

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

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

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

// 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;

}

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

Abfeuern mit der Leertaste

// 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;

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

// 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;

}

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

Schritt 6: Die Blöcke

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

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

Blockreihen

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

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

// 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;

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

Levels von Breakanoid

// Je nach Level die Blöcke erstellen

switch(iLevel)

{

case 1:

CreateBlockRow(" 1 1 1 ", tbVector3(-8.0f, 0.0f, 2.0f));

CreateBlockRow("12 111 21", tbVector3(-8.0f, 0.0f, 1.0f));

CreateBlockRow("12 21", tbVector3(-8.0f, 0.0f, 0.0f));

CreateBlockRow(" 112 211 ", tbVector3(-8.0f, 0.0f, -1.0f));

break;

case 2:

CreateBlockRow(" 222 ", tbVector3(-8.0f, 0.0f, 1.0f));

CreateBlockRow(" 2 3 2 ", tbVector3(-8.0f, 0.0f, 0.0f));

CreateBlockRow(" 2 333 2 ", tbVector3(-8.0f, 0.0f, -1.0f));

CreateBlockRow("111111111", tbVector3(-8.0f, 0.0f, -2.0f));

break;

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

Kollision zwischen Ball und Block

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

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

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

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

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

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

// Kollision mit den Blöcken berechnenfor(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 + 0.25f >= vBlock.x - 1.0f && m_vPosition.x - 0.25f <= vBlock.x + 1.0f && m_vPosition.z + 0.25f >= vBlock.z - 0.5f && m_vPosition.z - 0.25f <= vBlock.z + 0.5f)

// Entfernung des Balls von allen Blockseiten berechnenfDistLeft = fabsf(m_vPosition.x + 0.25f - (vBlock.x - 1.0f));fDistRight = fabsf(m_vPosition.x - 0.25f - (vBlock.x + 1.0f));fDistTop = fabsf(m_vPosition.z - 0.25f - (vBlock.z + 0.5f));fDistBottom = fabsf(m_vPosition.z + 0.25f - (vBlock.z - 0.5f));

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

// 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;

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

Multiball

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

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

Ende des Levels/Spiels:

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

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

Schritt 7: Versuche

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“

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

Game Over !

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

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

Schritt8: Punkte

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 10000 Punkte extra

Zudem 100 Punkte bei Treffen eines Blocks, 1000-4000 bei Zerstörung

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

// Level 1 bringt 10000 Punkte, Level 2 20000 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 1000000 Punkten.

m_iScore += (DWORD)(1000000.0f * (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;

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

Schritt 9: Sound für das Spiel

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

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

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)

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

Schritt10: Hier spielt die Musik

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

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

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;

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

Danke für eure Aufmerksamkeit!!!