+ All Categories
Home > Documents > Speed Typing Game C++ Prototype - All the source code

Speed Typing Game C++ Prototype - All the source code

Date post: 10-Apr-2015
Category:
Upload: kajus
View: 2,064 times
Download: 18 times
Share this document with a friend
Description:
Download des Source Codes für das Spiel unter: http://media-it.blogspot.com/2008/02/speed-typing-game.html-- Alle Klassen (siehe PDF) --const.hmain.hmain.cpptext3d.htext3d.cppimageloader.himageloader.cppvec3f.hvec3f.cppWord.hWord.cppdate 2008-01-20
47
project: speed typing game (former “Sponge Bob’s Words”) author: (c) 2008 Kai Kajus Noack. All rights reserved. website: http://media-it.blogspot.com/2008/02/speed-typing-game.html License: CREATIVE COMMONS Attribution-Noncommercial-Share Alike 3.0 Germany You may not use this file except in compliance with the License. You may obtain a copy of the License at: http://creativecommons.org/licenses/by-nc-sa/3.0/de/deed.de Es ist Ihnen gestattet: das Werk vervielfältigen, verbreiten, öffentlich zugänglich zu machen Abwandlungen bzw. Bearbeitungen des Inhaltes anzufertigen zu den folgenden Bedingungen: • Namensnennung. Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen. • Keine kommerzielle Nutzung. Dieses Werk darf nicht für kommerzielle Zwecke verwendet werden. • Weitergabe unter gleichen Bedingungen. Wenn Sie den lizenzierten Inhalt bearbeiten oder in anderer Weise umgestalten, verändern oder als Grundlage für einen anderen Inhalt verwenden, dürfen Sie den neu entstandenen Inhalt nur unter Verwendung von Lizenzbedingungen weitergeben, die mit denen dieses Lizenzvertrages identisch oder vergleichbar sind. - Im Falle einer Verbreitung müssen Sie anderen die Lizenzbedingungen, unter welche dieses Werk fällt, mitteilen. Am Einfachsten ist es, einen Link auf diese Seite einzubinden. - Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern Sie die Einwilligung des Rechteinhabers dazu erhalten. - Diese Lizenz lässt die Urheberpersönlichkeitsrechte unberührt.
Transcript
Page 1: Speed Typing Game C++ Prototype - All the source code

project: speed typing game (former “Sponge Bob’s Words”)

author: (c) 2008 Kai Kajus Noack. All rights reserved.

website: http://media-it.blogspot.com/2008/02/speed-typing-game.html

License:

CREATIVE COMMONS Attribution-Noncommercial-Share Alike 3.0 Germany

You may not use this file except in compliance with the License. You may obtain a copy of the License at:

http://creativecommons.org/licenses/by-nc-sa/3.0/de/deed.de

Es ist Ihnen gestattet:

� das Werk vervielfältigen, verbreiten, öffentlich zugänglich zu machen

� Abwandlungen bzw. Bearbeitungen des Inhaltes anzufertigen � zu den folgenden Bedingungen:

• Namensnennung.

Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.

• Keine kommerzielle Nutzung.

Dieses Werk darf nicht für kommerzielle Zwecke verwendet werden.

• Weitergabe unter gleichen Bedingungen. Wenn Sie den lizenzierten Inhalt bearbeiten oder in anderer Weise

umgestalten, verändern oder als Grundlage für einen anderen Inhalt

verwenden, dürfen Sie den neu entstandenen Inhalt nur unter Verwendung von Lizenzbedingungen weitergeben, die mit denen dieses

Lizenzvertrages identisch oder vergleichbar sind.

- Im Falle einer Verbreitung müssen Sie anderen die Lizenzbedingungen,

unter welche dieses Werk fällt, mitteilen. Am Einfachsten ist es, einen Link auf diese Seite einzubinden.

- Jede der vorgenannten Bedingungen kann aufgehoben werden, sofern

Sie die Einwilligung des Rechteinhabers dazu erhalten.

- Diese Lizenz lässt die Urheberpersönlichkeitsrechte unberührt.

Page 2: Speed Typing Game C++ Prototype - All the source code

const.h — Printed on 29.12.2008, 13:26:58 — Page 1

#ifndef CONSTS_H_INCLUDED

#define CONSTS_H_INCLUDED

// unsere Konstantent für das Spiel

static const float PI = 3.14159265L;

static const int WINWIDTH = 800;

static const int WINHEIGHT = 600;

static const int WORTANZAHL = 2000;

static const int MAXWORTLAENGE = 15;

static const int COUNTDOWN = 60;

static const int MAXBLITZE = 10;

#endif

Page 3: Speed Typing Game C++ Prototype - All the source code

main.h — Printed on 29.12.2008, 13:29:14 — Page 1

#ifndef MAIN_H_

#define MAIN_H_

class game

{

public:

Game();

virtual ~Game();

};

void initRendering(void);

#endif

Page 4: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1

/****************************************************** * Kai Kajus Noack * * Project: "Game: SpongeBob's Words" * * Date: 2008-01-20 * ******************************************************/

#include <iostream>

#include <stdlib.h>

#include <GL/glut.h>

#include <GL/gl.h>

#include "text3d.h"

// selbstdefinierte Konstanten#include "const.h"

// zum Dateieinlesen#include <fstream>

#include <iomanip>

// für Casting int zu String#include <sstream>

#include <string>

// für Texturen#include "imageloader.h"

// der Timer#include <time.h>

// trigonometrische Funktionen#include <math.h>

// Objekt: Wort (Spielelement)#include "Word.h"

// vektor-klasse zum zeichnen#include <vector>

#include "vec3f.h"

using namespace std;

bool blitz = false;

bool psychomode = false;

bool startScreen = true;

bool gameOver = false;

// Alpha-Würfel *** STARTconst float BOX_SIZE = 7.0f; // Seitenlänge des Würfelsconst float ALPHA = 0.6f; // Durchsichtigkeit der Flächen

// Vektoren geben Richtungen der Seitenfläche anstruct Face {

Vec3f up;

Vec3f right;

Vec3f out;

};

// Seitenfläche Alpha-Würfelstruct Cube {

Face top;

Face bottom;

Face left;

Face right;

Face front;

Face back;

};

// Rotation des Vektors entsprechend der Gradangabe um die gegebene AchseVec3f rotate(Vec3f v, Vec3f axis, float degrees) {

axis = axis.normalize();

float radians = degrees * PI / 180;

Page 5: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 2

float s = sin(radians);

float c = cos(radians);

return v * c + axis * axis.dot(v) * (1 - c) + v.cross(axis) * s;

}

// Rotation der Seitenflächevoid rotate(Face &face, Vec3f axis, float degrees) {

face.up = rotate(face.up, axis, degrees);

face.right = rotate(face.right, axis, degrees);

face.out = rotate(face.out, axis, degrees);

}

// Rotation des Würfelsvoid rotate(Cube &cube, Vec3f axis, float degrees) {

rotate(cube.top, axis, degrees);

rotate(cube.bottom, axis, degrees);

rotate(cube.left, axis, degrees);

rotate(cube.right, axis, degrees);

rotate(cube.front, axis, degrees);

rotate(cube.back, axis, degrees);

}

// Vektoren-Initialisierung für die Seitenflächenvoid initCube(Cube &cube) {

cube.top.up = Vec3f(0, 0, -1);

cube.top.right = Vec3f(1, 0, 0);

cube.top.out = Vec3f(0, 1, 0);

cube.bottom.up = Vec3f(0, 0, 1);

cube.bottom.right = Vec3f(1, 0, 0);

cube.bottom.out = Vec3f(0, -1, 0);

cube.left.up = Vec3f(0, 0, -1);

cube.left.right = Vec3f(0, 1, 0);

cube.left.out = Vec3f(-1, 0, 0);

cube.right.up = Vec3f(0, -1, 0);

cube.right.right = Vec3f(0, 0, 1);

cube.right.out = Vec3f(1, 0, 0);

cube.front.up = Vec3f(0, 1, 0);

cube.front.right = Vec3f(1, 0, 0);

cube.front.out = Vec3f(0, 0, 1);

cube.back.up = Vec3f(1, 0, 0);

cube.back.right = Vec3f(0, 1, 0);

cube.back.out = Vec3f(0, 0, -1);

}

// Ist uns face1 oder face2 zugewandtbool compareFaces(Face* face1, Face* face2) {

return face1->out[2] < face2->out[2];

}

// Eckpunkte der Seitenflächevoid faceVertices(Face &face, Vec3f* vs) {

vs[0] = BOX_SIZE / 2 * (face.out - face.right - face.up);

vs[1] = BOX_SIZE / 2 * (face.out - face.right + face.up);

vs[2] = BOX_SIZE / 2 * (face.out + face.right + face.up);

vs[3] = BOX_SIZE / 2 * (face.out + face.right - face.up);

}

void drawTopFace(Face &face) {

Page 6: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 3

Vec3f vs[4];

faceVertices(face, vs);

glDisable(GL_TEXTURE_2D);

glBegin(GL_QUADS);

glColor4f(1.0f, 1.0f, 0.0f, ALPHA);

glNormal3f(face.out[0], face.out[1], face.out[2]);

glVertex3f(vs[0][0], vs[0][1], vs[0][2]);

glVertex3f(vs[1][0], vs[1][1], vs[1][2]);

glVertex3f(vs[2][0], vs[2][1], vs[2][2]);

glVertex3f(vs[3][0], vs[3][1], vs[3][2]);

glEnd();

}

void drawBottomFace(Face &face) {

Vec3f vs[4];

faceVertices(face, vs);

glDisable(GL_TEXTURE_2D);

glBegin(GL_QUADS);

glColor4f(1.0f, 0.0f, 1.0f, ALPHA);

glNormal3f(face.out[0], face.out[1], face.out[2]);

glVertex3f(vs[0][0], vs[0][1], vs[0][2]);

glVertex3f(vs[1][0], vs[1][1], vs[1][2]);

glVertex3f(vs[2][0], vs[2][1], vs[2][2]);

glVertex3f(vs[3][0], vs[3][1], vs[3][2]);

glEnd();

}

void drawLeftFace(Face &face) {

Vec3f vs[4];

faceVertices(face, vs);

glDisable(GL_TEXTURE_2D);

glBegin(GL_QUADS);

glNormal3f(face.out[0], face.out[1], face.out[2]);

glColor4f(0.0f, 1.0f, 1.0f, ALPHA);

glVertex3f(vs[0][0], vs[0][1], vs[0][2]);

glVertex3f(vs[1][0], vs[1][1], vs[1][2]);

glColor4f(0.0f, 0.0f, 1.0f, ALPHA);

glVertex3f(vs[2][0], vs[2][1], vs[2][2]);

glVertex3f(vs[3][0], vs[3][1], vs[3][2]);

glEnd();

}

void drawRightFace(Face &face) {

Vec3f vs[4];

faceVertices(face, vs);

glDisable(GL_TEXTURE_2D);

glBegin(GL_QUADS);

glNormal3f(face.out[0], face.out[1], face.out[2]);

glColor4f(1.0f, 0.0f, 0.0f, ALPHA);

glVertex3f(vs[0][0], vs[0][1], vs[0][2]);

glVertex3f(vs[1][0], vs[1][1], vs[1][2]);

glColor4f(0.0f, 1.0f, 0.0f, ALPHA);

glVertex3f(vs[2][0], vs[2][1], vs[2][2]);

glVertex3f(vs[3][0], vs[3][1], vs[3][2]);

glEnd();

}

void drawFrontFace(Face &face, GLuint textureId) {

Vec3f vs[4];

faceVertices(face, vs);

glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, textureId);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

Page 7: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 4

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glColor4f(1.0f, 1.0f, 1.0f, ALPHA);

glBegin(GL_QUADS);

glNormal3f(face.out[0], face.out[1], face.out[2]);

glTexCoord2f(0, 0);

glVertex3f(vs[0][0], vs[0][1], vs[0][2]);

glTexCoord2f(0, 1);

glVertex3f(vs[1][0], vs[1][1], vs[1][2]);

glTexCoord2f(1, 1);

glVertex3f(vs[2][0], vs[2][1], vs[2][2]);

glTexCoord2f(1, 0);

glVertex3f(vs[3][0], vs[3][1], vs[3][2]);

glEnd();

}

void drawBackFace(Face &face, GLuint textureId) {

Vec3f vs[4];

faceVertices(face, vs);

glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, textureId);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glColor4f(1.0f, 1.0f, 1.0f, ALPHA);

glBegin(GL_QUADS);

glNormal3f(face.out[0], face.out[1], face.out[2]);

glTexCoord2f(0, 0);

glVertex3f(vs[0][0], vs[0][1], vs[0][2]);

glTexCoord2f(0, 1);

glVertex3f(vs[1][0], vs[1][1], vs[1][2]);

glTexCoord2f(1, 1);

glVertex3f(vs[2][0], vs[2][1], vs[2][2]);

glTexCoord2f(1, 0);

glVertex3f(vs[3][0], vs[3][1], vs[3][2]);

glEnd();

}

// Seitenfläche auf Würfel zeichnenvoid drawFace(Face* face, Cube &cube, GLuint textureId) {

if (face == &(cube.top)) { drawTopFace(cube.top); }

else if (face == &(cube.bottom)) { drawBottomFace(cube.bottom); }

else if (face == &(cube.left)) { drawLeftFace(cube.left); }

else if (face == &(cube.right)) { drawRightFace(cube.right); }

else if (face == &(cube.front)) { drawFrontFace(cube.front, textureId); }

else { drawBackFace(cube.back, textureId); }

}

// Alpha-Würfel *** ENDE

Cube _cube; // der Würfel

// Timer-Variablenint minutes, sek, recentTime;

// Spielzeit in Sekundenclock_t startTime, endTime;

// Spielmodus: Training oder Countdownstring gamemode;

// Spielzeitint countDownTime = COUNTDOWN;

string timeSpent;

// Arrays + String + Zähler für Keyboard-Eingabe des Spielers

Page 8: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 5

char keyboardInput[MAXWORTLAENGE];

string eingabewort;

unsigned char* keys = new unsigned char[MAXWORTLAENGE];

int inputChar = 0;

// Statistisch mitzählenint charCounter = 0;

int wordCounter = 0;

int wordFalse = 0;

int wordRight = 0;

// Arrays für eingelesene Stringschar allWords[WORTANZAHL][MAXWORTLAENGE];

string alleWoerter[WORTANZAHL];

// Zufallszahl für Wortauswahlint randomNr = 0;

// Punkte speichernint scoreInt = 0;

string score;

// das Wort auf dem BildschirmWord *wort;

string createNewWord(void) {

// initialisieren eines Random (notwendig für nä. Fkt.aufruf)srand ( time(NULL) );

// generate random numberrandomNr = rand() % WORTANZAHL;

// zu lange Wörter ggf. kürzenif((alleWoerter[randomNr]).length()>=(unsigned)MAXWORTLAENGE) {

return (alleWoerter[randomNr]).substr(0,MAXWORTLAENGE-1);

}

return allWords[randomNr];

}

// Stream zwecks Umwandlung von int zu stringstringstream out;

string setScore(int scoredValue){

// Punktzahl + 1scoreInt+=scoredValue;

// stream bereinigenout.str("");

out.clear();

// neue Punkte in den Stream schreibenout << "Score: " << scoreInt;

return out.str();

}

void resetInputState(void) {

// bisherige Eingaben löscheneingabewort.clear();

for (int j = 0; j < MAXWORTLAENGE; j++) {

keyboardInput[j] = '\0';

}

// Position des Wortes auf Bildschirm zurücksetzenwort->resetWordPos();

}

// Textur-LoaderGLuint loadTexture(Image *image) {

GLuint texture;

Page 9: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 6

glGenTextures(1, &texture);

// Textur den Bilddaten zuordnenglBindTexture(GL_TEXTURE_2D, texture);

// Mappen des Bildes auf die Textur (Bild nach OpenGL laden)glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height, 0, GL_RGB,

GL_UNSIGNED_BYTE, image->pixels); //The actual pixel data// Textur-ID zurückgebenreturn texture;

}

// 3D-Text bereinigenvoid cleanup() {

t3dCleanup();

}

/**** TEXTUREN ****/GLuint _textureIdFloor;

GLuint _textureIdSponge;

// weitere Spielvariablen (Winkel)float _angle = 0.0f;

float _angle2 = 0.0f;

// Var. für: Verschiebung Würfel in X-Richtung je nach Punktzahl des Spielers float offsetX = 1.0;

// Rendern vorbereitenvoid initRendering() {

glEnable(GL_DEPTH_TEST);

glEnable(GL_COLOR_MATERIAL);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);

glEnable(GL_LIGHT1);

glEnable(GL_NORMALIZE);

glShadeModel(GL_SMOOTH);

glEnable(GL_FOG);

glClearColor(0.1f, 0.1f, 0.15f, 1);

// Initialisierung der 3D-Schriftent3dInit();

// Bild in Textur ladenImage* image = loadBMP("img/floor.bmp");

_textureIdFloor = loadTexture(image);

// image-objekt löschen, dann neu ladendelete image;

image = loadBMP("img/spongebob.bmp");

_textureIdSponge = loadTexture(image);

delete image;

}

/**** PARTIKEL START ****/const int ParticleCount = 500;

typedef struct {

double Xpos;

double Ypos;

double Zpos;

double Xmov;

double Zmov;

double Red;

Page 10: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 7

double Green;

double Blue;

double Direction;

double Acceleration;

double Deceleration;

double Scalez;

bool Visible;

}PARTICLES;

PARTICLES Particle[ParticleCount];

void glCreateParticles (void) {

int i;

for (i = 1; i < ParticleCount; i++) {

Particle[i].Xpos = 0;

Particle[i].Ypos = -5;

Particle[i].Zpos = -5;

Particle[i].Xmov = (((((((2 - 1 + 1) * rand()%11) + 1) - 1 + 1) * rand()%11) + 1) * 0.005) -

(((((((2 - 1 + 1) * rand()%11) + 1) - 1 + 1) * rand()%11) + 1) * 0.005);

Particle[i].Zmov = (((((((2 - 1 + 1) * rand()%11) + 1) - 1 + 1) * rand()%11) + 1) * 0.005) -

(((((((2 - 1 + 1) * rand()%11) + 1) - 1 + 1) * rand()%11) + 1) * 0.005);

Particle[i].Red = 1;

Particle[i].Green = 1;

Particle[i].Blue = 1;

Particle[i].Scalez = 0.25;

Particle[i].Direction = 0;

Particle[i].Acceleration = ((((((8 - 5 + 2) * rand()%11) + 5) - 1 + 1) * rand()%11) + 1) * 0.02;

Particle[i].Deceleration = 0.0025;

}

}

void glUpdateParticles (void) {

int i;

for (i = 1; i < ParticleCount; i++) {

glColor3f (Particle[i].Red, Particle[i].Green, Particle[i].Blue);

Particle[i].Ypos = (Particle[i].Ypos + Particle[i].Acceleration - Particle[i].Deceleration)*0.8; // 0.8 -> cool particle effect

Particle[i].Deceleration = Particle[i].Deceleration + 0.0025;

Particle[i].Xpos = Particle[i].Xpos + Particle[i].Xmov;

Particle[i].Zpos = Particle[i].Zpos + Particle[i].Zmov;

Particle[i].Direction = Particle[i].Direction + ((((((int)(0.5 - 0.1 + 0.1) * rand()%11) + 1) - 1 + 1)

* rand()%11) + 1);

if (Particle[i].Ypos < -5) {

Particle[i].Xpos = 0;

Particle[i].Ypos = -5;

Particle[i].Zpos = -5;

Particle[i].Red = 1;

Particle[i].Green = 1;

Particle[i].Blue = 1;

Particle[i].Direction = 0;

Particle[i].Acceleration = ((((((8 - 5 + 2) * rand()%11) + 5) - 1 + 1) * rand()%11) + 1) *

0.02;

Particle[i].Deceleration = 0.0025;

}

}

}

void glDrawParticles (void) {

glPushMatrix();

glTranslatef(0.0f, 10.0f, -9.0f);

glRotatef(180.0f, 0.0f, 0.0f, 1.0f);

glColor3f(1.0f, 0.5f, 0.0f);

Page 11: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 8

int i;

glDisable(GL_LIGHTING); // zusätzlich hinzugefügtglDisable(GL_TEXTURE_2D);

for (i = 1; i < ParticleCount; i++) {

glPushMatrix();

glTranslatef (Particle[i].Xpos, Particle[i].Ypos, Particle[i].Zpos);

glRotatef (Particle[i].Direction - 90, 0, 0, 1);

glScalef (Particle[i].Scalez, Particle[i].Scalez, Particle[i].Scalez);

glDisable (GL_DEPTH_TEST);

glEnable (GL_BLEND);

// Erklärung http://wiki.delphigl.com/index.php/GlBlendFuncglBlendFunc (GL_DST_COLOR, GL_ZERO);

glBegin (GL_QUADS);

glTexCoord2d (0, 0);

glVertex3f (-1, -1, 0);

glTexCoord2d (1, 0);

glVertex3f (1, -1, 0);

glTexCoord2d (1, 1);

glVertex3f (1, 1, 0);

glTexCoord2d (0, 1);

glVertex3f (-1, 1, 0);

glEnd();

glBlendFunc (GL_ONE, GL_ONE);

glBegin (GL_QUADS);

glTexCoord2d (0, 0);

glVertex3f (-1, -1, 0);

glTexCoord2d (1, 0);

glVertex3f (1, -1, 0);

glTexCoord2d (1, 1);

glVertex3f (1, 1, 0);

glTexCoord2d (0, 1);

glVertex3f (-1, 1, 0);

glEnd();

glEnable(GL_DEPTH_TEST);

glPopMatrix();

}

glEnable(GL_LIGHTING);

glPopMatrix();

}

void initParticles() {

glEnable(GL_TEXTURE_2D);

glEnable(GL_DEPTH_TEST);

glCreateParticles();

}

/**** PARTIKEL ENDE ****/

void paintFlyingCube() {

// Optional:// Rotes ambientes Licht neben Würfel hinzufügen// GLfloat ambientColor[] = {0.2f, 0.2f, 0.2f, 1.0f};// glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);// GLfloat lightColor1[] = {1.5f, 0.5f, 0.5f, 1.0f};// GLfloat lightPos1[] = {2.0f, 0.0f, 2.0f, 1.0f};// glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1);// glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);

glPushMatrix();

glTranslatef(-8.0f, 0.0f, 0.0f);

glRotatef(_angle, 0.0f, 1.0f, 0.0f);

glColor3f(1.0f, 1.0f, 0.0f);

Page 12: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 9

glBegin(GL_QUADS);

// Smooth Shading (für jeden Punkt eine eigene Normale!)// FrontglNormal3f(-1.0f, 0.0f, 1.0f);

glVertex3f(-1.5f+offsetX, -1.0f, 1.5f);

glNormal3f(1.0f, 0.0f, 1.0f);

glVertex3f(1.5f+offsetX, -1.0f, 1.5f);

glNormal3f(1.0f, 0.0f, 1.0f);

glVertex3f(1.5f+offsetX, 1.0f, 1.5f);

glNormal3f(-1.0f, 0.0f, 1.0f);

glVertex3f(-1.5f+offsetX, 1.0f, 1.5f);

// RechtsglNormal3f(1.0f, 0.0f, -1.0f);

glVertex3f(1.5f+offsetX, -1.0f, -1.5f);

glNormal3f(1.0f, 0.0f, -1.0f);

glVertex3f(1.5f+offsetX, 1.0f, -1.5f);

glNormal3f(1.0f, 0.0f, 1.0f);

glVertex3f(1.5f+offsetX, 1.0f, 1.5f);

glNormal3f(1.0f, 0.0f, 1.0f);

glVertex3f(1.5f+offsetX, -1.0f, 1.5f);

// HintenglNormal3f(-1.0f, 0.0f, -1.0f);

glVertex3f(-1.5f+offsetX, -1.0f, -1.5f);

glNormal3f(-1.0f, 0.0f, -1.0f);

glVertex3f(-1.5f+offsetX, 1.0f, -1.5f);

glNormal3f(1.0f, 0.0f, -1.0f);

glVertex3f(1.5f+offsetX, 1.0f, -1.5f);

glNormal3f(1.0f, 0.0f, -1.0f);

glVertex3f(1.5f+offsetX, -1.0f, -1.5f);

// LinksglNormal3f(-1.0f, 0.0f, -1.0f);

glVertex3f(-1.5f+offsetX, -1.0f, -1.5f);

glNormal3f(-1.0f, 0.0f, 1.0f);

glVertex3f(-1.5f+offsetX, -1.0f, 1.5f);

glNormal3f(-1.0f, 0.0f, 1.0f);

glVertex3f(-1.5f+offsetX, 1.0f, 1.5f);

glNormal3f(-1.0f, 0.0f, -1.0f);

glVertex3f(-1.5f+offsetX, 1.0f, -1.5f);

glEnd();

glPopMatrix();

}

int blitzZaehler = 0;

void blitzen() {

// Blitz-Effekt im Hintergrundif (0==blitzZaehler%2) glClearColor(2.0f, 2.0f, 2.0f, 1);

else glClearColor(0.1f, 0.1f, 0.15f, 1);

blitzZaehler++;

// auf 5 Blitze beschränkenif (blitzZaehler>MAXBLITZE) {

blitz = false;

blitzZaehler=0;

glClearColor(0.1f, 0.1f, 0.15f, 1);

}

}

// Tastatur-Eingaben des Spielers prüfenvoid checkUserInput() {

wordCounter++;

// bei korrekter Eingabe

Page 13: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 0

if ( !(wort->name.compare(eingabewort)) ) {

wordRight++;

score = setScore(1);

blitz = true;

resetInputState();

wort->name = createNewWord();

// Würfel verschiebt sichoffsetX+= 0.5;

}

// Spezial: Eingabe zur Aktivierung der Psychomode-Grafik ;)else if ( ! (eingabewort.compare("000")) ) {

psychomode = !psychomode;

resetInputState();

}

// bei Falschschreibung des Worteselse if ( wort->name.compare(eingabewort) ) {

wordFalse++;

score = setScore(-1);

resetInputState();

wort->name = createNewWord();

// Würfel verschiebt sichoffsetX-= 0.5;

}

// wichtig für die Position xxx eingabewortinputChar = 0;

}

void handleKeypress(unsigned char key, int x, int y) {

// Startbildschirm:if (startScreen) {

switch (key) {

case 27: // Escapecleanup();

exit(0);

break;

case '1':

gamemode = "countdown";

startScreen = false;

break;

case '2':

gamemode = "training";

startScreen = false;

break;

default:

cout << "falsche Eingabe" << endl;

}

resetInputState();

}

// Spiel läuft:else if (!gameOver) {

charCounter++;

switch (key) {

case 27: // Escapecleanup();

exit(0);

break;

case '\r':

checkUserInput();

break;

default:

keyboardInput[inputChar] = key;

Page 14: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 1

eingabewort = keyboardInput;

inputChar++;

}

// Eingabe ist zu langif ((unsigned)inputChar>wort->name.length()) {

score = setScore(-1);

resetInputState();

inputChar = 0;

}

}

// wenn GameOver aktiv ist:else {

switch (key) {

case 27: // Escapecleanup();

exit(0);

break;

// Neustart des Spiels via Enter-Tastecase '\r':

// Neu-InitialisierungencharCounter = 0;

wordCounter = 0;

wordFalse = 0;

wordRight = 0;

scoreInt = 0;

score = setScore(0);

countDownTime = COUNTDOWN;

startTime = clock();

offsetX = 1.0f;

startScreen = true;

gameOver = false;

resetInputState();

break;

}

}

}

// Bodenplatte mit Wassertextur zeichnenvoid paintFloor() {

// Texturen aktivierenglEnable(GL_TEXTURE_2D);

// Flur-Textur verwendenglBindTexture(GL_TEXTURE_2D, _textureIdFloor);

// Bild nah oder fern, nutze GL_NEAREST Mapping glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// zeichne Boden mit TexturkoordinatenglBegin(GL_QUADS);

// Normalen-Vektor zeigt nach oben glNormal3f(0.0, 1.0f, 0.0f);

glTexCoord2f(0.0f, 0.0f);

glVertex3f(-7.0f, -5.0f, 5.0f);

glTexCoord2f(1.0f, 0.0f);

glVertex3f(7.0f, -5.0f, 5.0f);

glTexCoord2f(1.0f, 1.0f);

glVertex3f(25.0f, -5.0f, -25.0f);

glTexCoord2f(0.0f, 1.0f);

glVertex3f(-25.0f, -5.0f, -25.0f);

glEnd();

// Texturen deaktivierenglDisable(GL_TEXTURE_2D);

}

Page 15: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 2

// eine Veränderung der Fenstergröße beachtenvoid handleResize(int w, int h) {

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);

}

void moveAndPaintWord(string suchwort) {

glColor3f(1.0,1.0,1.0);

// zeichne das frontal zu sehende WortglPushMatrix();

// Wort bewegenglTranslatef(wort->posX, wort->posY, wort->posZ);

// optional: Wort rotieren// glRotatef(wort->angle, 0.0f, 1.0f, 0.0f);// Wort zeichnent3dDraw3D(suchwort, 0, 0, 0.2f);

glPopMatrix();

// Wortkopie als Reflexion auf dem Boden zeichnenglPushMatrix();

glTranslatef(wort->posX, wort->posY-9.0f, wort->posZ-4.0f);

glRotatef(-180.0f, 1.0f,0.0f,0.0f);

glColor4f(0.2f,0.2f,1.0f,0.5f);

t3dDraw3D(suchwort, 0, 0, 0.2f);

glColor3f(0.5f, 0.5f, 0.65f);

glPopMatrix();

glEnable(GL_NORMALIZE);

// wenn das Suchwort hinter uns ist, bringe es wieder nach vorneif (wort->posZ > 12.0) {

resetInputState();

}

}

// rechts unten im Bildschirm erscheint die Eingabe des Spielersvoid showKeyboardInput() {

glPushMatrix();

glTranslated(5.2f,-4.5f,3.0f);

glScalef(0.5f, 0.5f, 0.5f);

t3dDraw3D(eingabewort, 0, 0, 0.2f);

glPopMatrix();

}

// rechts oben erscheinen die Punkte und der Timervoid showScore() {

glColor3f(2.0f,0.0f,0.0f);

glPushMatrix();

glTranslated(5.45f,4.0f,4.0f);

glScalef(0.35f, 0.35f, 0.35f);

t3dDraw3D(score, 0, 0, 0.2f);

glPopMatrix();

}

void showTimer() {

glPushMatrix();

glTranslated(5.5f,4.4f,4.0f);

glScalef(0.3f, 0.3f, 0.3f);

glColor3f(2.0f, 0.0f, 0.0f);

t3dDraw3D(timeSpent, 0, 0, 0.2f);

glPopMatrix();

// glColor3f(0.3f, 1.0f, 0.3f);}

Page 16: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 3

// Konvertierungdouble convertRADtoANGLE(double rad) {

double angle0 = rad * 2 * PI / 360;

return angle0;

}

// Zahl rundendouble Round(double Zahl, unsigned int Stellen) {

Zahl *= pow(10, Stellen);

if (Zahl >= 0)

Zahl = floor(Zahl + 0.5);

else

Zahl = ceil(Zahl - 0.5);

Zahl /= pow(10, Stellen);

return Zahl;

}

// bei Spielstart anzeigenvoid showStartScreen() {

glDisable(GL_FOG);

glPushMatrix();

glTranslated(0.0f,0.0f,-3.0f);

glColor3f(1.5f, 1.5f, 0.5f);

t3dDraw3D("Wahl des Modus:\n1 - Countdown\n2 - Training", 0, 0, 0.2f);

glPopMatrix();

glEnable(GL_FOG);

}

// beim Gameover anzeigenvoid showGameOver(double result) {

glPushMatrix();

glTranslated(0.0f,-2.0f,3.0f);

glRotatef(_angle, 0.5f, 1.0f, 0.5f);

_angle -= 0.5f;

glColor3f(0.2f, 0.2f, 1.0f);

t3dDraw3D("Game Over!", 0, 0, 0.2f);

glPopMatrix();

// Ausgabe des erzielten ErgebnissesglPushMatrix();

glTranslated(0.0f,1.0f+cos(convertRADtoANGLE(_angle)),0.0f);

glScalef(0.5f, 0.5f, 0.5f);

glColor3f(0.2f, 1.0f, 0.2f);

// Lösche Daten aus Streamout.str(""); out.clear();

// Schreibe neue Daten in Stream (beachte negatives oder Null-Ergebnis)if (result<=0) out << "Oh, keine Woerter richtig :(";

else out << "Super! " << scoreInt << " Punkte!\n\n " << Round(result,3) << " Sekunden pro Wort!\n\n"

<< wordRight << " von " << wordCounter << " Woertern richtig!\n" << "Fehlerquote: " << Round( ((float)(

wordFalse)/(float)(wordCounter))*100 , 2) << "%" << "\n\n" << charCounter*(60.0f/(float)COUNTDOWN)

<< " Anschlaege pro Minute";

// String aus dem Stream generieren und an Text-Zeichner übergebent3dDraw3D(out.str(), 0, 0, 0.2f);

glPopMatrix();

}

// Nebeleffekt (+ versteckte psychomode-Grafik)void paintFog(){

GLfloat fogColor[] = {0.5f, 0.5f, 0.5f, 1};

glFogfv(GL_FOG_COLOR, fogColor);

Page 17: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 4

glFogi(GL_FOG_MODE, GL_LINEAR);

glFogf(GL_FOG_START, 4.0f);

glFogf(GL_FOG_END, 25.0f);

if (psychomode) {

double r = 20.0f;

double tiefeC = 8.0f;

int stepF = 90;

glColor3f(1.0f,0.0f,0.0f);

glPushMatrix();

glTranslatef(0.0f,0.0f,-20.0f);

// eine interessante Rotation der BoxglRotatef(_angle2, cos(convertRADtoANGLE(_angle)), 0.5f, 1.0f);

for (int angl = 45; angl <= 315; angl+=stepF) {

glBegin(GL_POLYGON);

// Box wird sehr verschiedenfarbigglColor3f(cos(convertRADtoANGLE(angl)), sin(convertRADtoANGLE(angl)), 0.0f);

glVertex3f(r*cos(convertRADtoANGLE(angl)), r*sin(convertRADtoANGLE(angl)), 0.0f);

glVertex3f(r*cos(convertRADtoANGLE(angl)), r*sin(convertRADtoANGLE(angl)), tiefeC);

glVertex3f(r*cos(convertRADtoANGLE(angl+stepF)), r*sin(convertRADtoANGLE(angl+stepF)),

tiefeC);

glVertex3f(r*cos(convertRADtoANGLE(angl+stepF)), r*sin(convertRADtoANGLE(angl+stepF)),

0.0f);

glEnd ();

}

glPopMatrix();

// zeichne die von mir erdachte "cos-sin-Krone"glColor3f(1.0f,0.0f,0.0f);

glPushMatrix();

glTranslatef(0.0f,0.0f,-15.0f);

double tiefe = 25.0f;

double nextStep = 15.0f;

double radius = 5.5f;

double paintAngle, nextStage;

glRotatef(_angle2*5, 0.1f, 0.1f, 1.0f);

for (double recentAngle = 0; recentAngle <= 360; recentAngle+=nextStep) {

glColor3f(cos(convertRADtoANGLE(recentAngle)), sin(convertRADtoANGLE(recentAngle)), 0.0f);

paintAngle = convertRADtoANGLE(recentAngle);

nextStage = convertRADtoANGLE(recentAngle+nextStep);

glBegin(GL_POLYGON);

glVertex3f(radius*cos(paintAngle),radius*sin(paintAngle),0.0f);

glVertex3f(radius*cos(paintAngle),radius*sin(paintAngle),tiefe-21.0f);

glVertex3f(radius*cos(nextStage),radius*sin(nextStage),tiefe);

glVertex3f(radius*cos(nextStage),radius*sin(nextStage),0.0f);

glEnd();

}

glPopMatrix();

}

}

// Zeit ermitteln und auf Bildschirm ausgeben je nach Spielmodusstringstream outTime;

void writeTime() {

// Stream löschenoutTime.str("");

outTime.clear();

if(gamemode=="training") {

if (sek >= 60) {

sek = 0;

Page 18: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 5

minutes++;

}

if (sek < 10) outTime << "Time " << minutes << ":0" << sek << endl;

else {

outTime << "Time " << minutes << ":" << sek << endl;

}

}

else if (gamemode=="countdown") {

outTime << "Time: " << countDownTime << endl;

}

timeSpent = outTime.str();

}

// Viereck-Bild von Spongebob auf Boden zeichnenvoid paintSpongebob(){

glDisable(GL_FOG);

glPushMatrix();

glEnable(GL_TEXTURE_2D);

glTranslatef(-7.0+(float)(scoreInt/3.0),-3.0,1.0);

glRotatef(scoreInt*5,0.0,1.0,0.0);

// Spongebob-Textur anwendenglBindTexture(GL_TEXTURE_2D, _textureIdSponge);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glBegin(GL_QUADS);

glNormal3f(0.0, 1.0f, 0.0f);

glTexCoord2f(0.0f, 0.0f);

glVertex3f(0.0f, 0.0f, 3.0f);

glTexCoord2f(1.0f, 0.0f);

glVertex3f(0.0f, 0.0f, 0.0f);

glTexCoord2f(1.0f, 1.0f);

glVertex3f(3.0f, 0.0f, 0.0f);

glTexCoord2f(0.0f, 1.0f);

glVertex3f(3.0f, 0.0f, 3.0f);

glEnd();

glDisable(GL_TEXTURE_2D);

glPopMatrix();

glEnable(GL_FOG);

}

// Alpha-Würfel wird größer, je mehr Punkte der Spieler erreichtfloat cubeScale = 0.0f;

void paintAlphaCube() {

glDisable(GL_FOG);

glEnable(GL_BLEND); // alpha blending aktivierenglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Blendfunktion bestimmenglPushMatrix();

cubeScale = 1.0+(float)scoreInt/20.0;

glScalef(cubeScale,cubeScale,cubeScale);

glTranslatef(0.0f,2.0f,-35.0f+float(scoreInt));

vector<Face*> faces;

faces.push_back(&(_cube.top));

faces.push_back(&(_cube.bottom));

faces.push_back(&(_cube.left));

faces.push_back(&(_cube.right));

faces.push_back(&(_cube.front));

faces.push_back(&(_cube.back));

// Seitenflächen sortieren von hinten nach vornesort(faces.begin(), faces.end(), compareFaces);

for(unsigned int i = 0; i < faces.size(); i++) {

drawFace(faces[i], _cube, _textureIdSponge);

Page 19: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 6

}

glPopMatrix();

glEnable(GL_FOG);

}

// gesamte Szene zeichnen (im Loop)void drawScene() {

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glTranslatef(0.0f, 0.0f, -8.0f);

// Licht einstellenGLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};

GLfloat lightPos0[] = {-0.5f, 0.5f, 1.0f, 0.0f};

glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);

glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

glScalef(0.5, 0.5, 0.5);

glColor3f(0.3f, 1.0f, 0.3f);

if(!startScreen) {

// Zeit für den Trainingsmodusif (gamemode=="training") {

endTime = clock();

recentTime = (endTime - startTime)/1000;

if ( recentTime > 0) {

startTime = clock();

endTime = clock();

sek++;

}

}

// Timer für Modus Countdownif (gamemode=="countdown") {

endTime = clock();

recentTime = (endTime - startTime)/1000;

if ( recentTime > 0) {

startTime = clock();

endTime = clock();

countDownTime--;

if (countDownTime <= 0) gameOver = true;

}

}

writeTime();

glUpdateParticles();

glDrawParticles();

}

// SPIELENDEif (gameOver) {

// kalkuliere Punkte + Statistikdouble result;

if (scoreInt <= 0) result = 0;

else result = double(COUNTDOWN)/double(scoreInt);

showGameOver(result);

}

// SPIELSTARTelse if (startScreen) {

showStartScreen();

}

// SPIEL LÄUFT!

Page 20: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 7

else {

// bewege das WortmoveAndPaintWord(wort->name);

// zeige bereits eingebenes WortshowKeyboardInput();

// Grafikelemente zeichnenpaintFog();

paintFloor();

paintSpongebob();

paintFlyingCube();

paintAlphaCube();

glDisable(GL_DEPTH_TEST); // Depth Testing ausschalten (zeichnet somit nur auf Vordergrund)showTimer();

showScore();

glEnable(GL_DEPTH_TEST); // Depth Testing wieder anschaltenglDisable(GL_BLEND); // Turn Blending Off

}

// blitzen, falls Wort richtig eingegebenif (blitz==true) blitzen();

glutSwapBuffers();

}

// sich verändernde Paramter zur Belebung der Szenevoid update(int value) {

wort->posZ += 0.1f;

_angle += 1.5f;

wort->angle += 0.1f;

_angle2 += 0.2f;

// alpha cube drehenrotate(_cube, Vec3f(1, 1, 0), 1);

glutPostRedisplay();

glutTimerFunc(25, update, 0);

}

// Wortliste einlesen und verfügbar machenvoid initWordlist(void) {

// Dateiname wählenchar datei[] = "wordlist.txt";

// Datei öffnen und einlesenifstream filestream(datei, ios::in);

// wenn Einlesen erfolgreichif(filestream.good()) {

// Dateizeiger ans Ende der Datei positionierenfilestream.seekg(0L,ios::end);

// Ausgabe der Datei-Eigenschaften (Konsole)cout << "Datei: " << datei << "\t Size: " << filestream.tellg() << " Bytes" << endl;

// Dateizeiger an den Datei-Anfang positionierenfilestream.seekg(0L,ios::beg);

// lese Wort für Wort ein:for (int j = 0; j < WORTANZAHL; j++) {

filestream.getline(allWords[j],WORTANZAHL*MAXWORTLAENGE); // http://www.cplusplus.com/reference/iostream/istream/getline.html

alleWoerter[j] = allWords[j];

}

}

else

cout << "Dateifehler oder Datei nicht gefunden!" << endl;

}

Page 21: Speed Typing Game C++ Prototype - All the source code

main.cpp — Printed on 29.12.2008, 13:28:56 — Page 1 8

int main(int argc, char** argv) {

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutInitWindowSize(WINWIDTH, WINHEIGHT);

glutCreateWindow("SpongeBob's Words 1.0");

initRendering();

initWordlist();

wort = new Word(createNewWord());

score = setScore(0);

glutDisplayFunc(drawScene);

glutKeyboardFunc(handleKeypress);

glutReshapeFunc(handleResize);

glutTimerFunc(25, update, 0);

// schreibe Timer-StartzeitstartTime = clock();

// weitere InitialisierungeninitParticles();

initCube(_cube);

glutMainLoop();

return 0;

}

Page 22: Speed Typing Game C++ Prototype - All the source code

text3d.h — Printed on 29.12.2008, 13:30:14 — Page 1

/* File for "Drawing Text" lesson of the OpenGL tutorial on

* www.videotutorialsrock.com

*/

#ifndef TEXT_3D_H_INCLUDED

#define TEXT_3D_H_INCLUDED

#include <string>

//Initializes 3D text. Must be called before other functions in this header.

void t3dInit();

//Frees memory allocated for 3D text. No other functions in this header may be

//called after this one.

void t3dCleanup();

/* Draws the specified string, using OpenGL, as a set of polygons in the x-y

* plane, with the top of the letters having the greatest y coordinate. The

* normals point in the positive z direction. (If you need the normals to point

* in the positive z direction on one side of the characters and the negative z

* direction on the other, call t3dDraw3D with a very small depth.)

*

* The string is drawn left-aligned if hAlign is negative, right-aligned if it

* is positive, and centered horizontally if it is 0. The string is drawn top-

* aligned if vAlign is negative, bottom-aligned if it is positive, and centered

* vertically if it is 0.

*

* The string may have newline characters, in which case the string will be

* drawn on multiple lines as one would expect. The lines are drawn lineHeight

* times the height of the font apart. The height of the font is the "normal"

* height of capital letters, rather than the distance from the top of "normal"

* capital letters to the bottom of lowercase letters like "p".

*

* All unprintable ASCII characters (other than '\n') are drawn as spaces.

*/

void t3dDraw2D(std::string str,

int hAlign, int vAlign,

float lineHeight = 1.5f);

/* Draws the specified string, using OpenGL, using polygons as a right prism,

* where the parallel faces are letters parallel to the x-y plane, with the top

* of the letters having the greatest y coordinate.

*

* The string is drawn left-aligned if hAlign is negative, right-aligned if it

* is positive, and centered horizontally if it is 0. The string is drawn top-

* aligned if vAlign is negative, bottom-aligned if it is positive, and centered

* vertically if it is 0.

*

* The string may have newline characters, in which case the string will be

* drawn on multiple lines as one would expect. The lines are drawn lineHeight

* times the height of the font apart. The height of the font is the "normal"

* height of capital letters, rather than the distance from the top of "normal"

* capital letters to the bottom of lowercase letters like "p".

*

* The depth of the characters is depth times the height of the font. The

* characters are centered at z = 0.

*

* All unprintable ASCII characters (other than '\n') are drawn as spaces.

*/

void t3dDraw3D(std::string str,

int hAlign, int vAlign,

float depth,

float lineHeight = 1.5f);

/* Returns the draw width of the specified string, as a multiple of the height

Page 23: Speed Typing Game C++ Prototype - All the source code

text3d.h — Printed on 29.12.2008, 13:30:14 — Page 2

* of the font. The height of the font is the "normal" height of capital

* letters, rather than the distance from the top of "normal" capital letters to

* the bottom of lowercase letters like "p". The width is the same as the width

* of the longest line.

*/

float t3dDrawWidth(std::string str);

/* Returns the draw height of the specified string, as a multiple of the height

* of the font. The height of the font is the "normal" height of capital

* letters, rather than the distance from the top of "normal" capital letters to

* the bottom of lowercase letters like "p". The draw is lineHeight times one

* fewer than the number of lines in the string, plus 1.

*/

float t3dDrawHeight(std::string str, float lineHeight = 1.5f);

//Indicates that an exception occurred when setting up 3D text

class T3DLoadException {

private:

std::string message0;

public:

T3DLoadException(std::string message1);

std::string message() const;

};

#endif

Page 24: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 1

/* File for "Drawing Text" lesson of the OpenGL tutorial on

* www.videotutorialsrock.com

*/

/* The 3D font is stored in an external file called "charset", which is

* basically a compact way of representing a series of OpenGL commands for

* drawing each of the printable ASCII characters, other than the space

* character (33 to 126). The file has the following format:

*

*

*

* the characters "VTR\0FNT\0"

* float space_width (the width of ' ', relative to the height the font)

*

* float char_33_scale

* unsigned short char_33_width (width = value * scale / 65536)

* unsigned short char_33_height (height = value * scale / 65536)

* unsigned short char_33_num_verts

* unsigned short char_33_vert_1_x (x = value * scale / 65536 + scale / 2)

* unsigned short char_33_vert_1_y (y = value * scale / 65536 + scale / 2)

* unsigned short char_33_vert_2_x (x = value * scale / 65536 + scale / 2)

* unsigned short char_33_vert_2_y (y = value * scale / 65536 + scale / 2)

* ...

* unsigned short char_33_vert_n_x (x = value * scale / 65536 + scale / 2)

* unsigned short char_33_vert_n_y (y = value * scale / 65536 + scale / 2)

* unsigned short opcode_1_for_char_33_front_face

* unsigned short opcode_2_for_char_33_front_face

* ...

* unsigned short opcode_n_for_char_33_front_face

* unsigned short end_part_opcode

* unsigned short opcode_1_for_char_33_3D_part

* unsigned short opcode_2_for_char_33_3D_part

* ...

* unsigned short opcode_n_for_char_33_3D_part

* unsigned short end_part_opcode

*

* float char_34_scale

* ...

*

*

* The character models are centered at (0, 0[, 0]).

*

* unsigned shorts are represented in little-endian format. floats are

* represented using one signed character exp followed by one signed integer

* mant, presented in little-endian format. This represents the number

* mant * 2^exp if mant is positive and -(~mant * 2^exp) if mant is negative.

*

* The opcodes are as follows:

*

* 0 to num_verts - 1:

* vertex with the same index as the opcode, using the vertex on the front

* face (the one with normal (0, 0, 1))

* num_verts to 2 * num_verts - 1:

* Vertex with index opcode - num_verts, using the vertex on the back face

* (the one with normal (0, 0, -1)). This opcode is only available for the

* 3D part of each model.

* 65532:

* Normal vector. Followed by an unsigned short indicating the angle of the

* vector divided by (2 pi) times 65536. The normal vector indicated is

* (cos theta, sin theta, 0). This opcode is only available for the 3D part

* of each model.

* 65533: GL_TRIANGLE_STRIP

* 65534: GL_TRIANGLES

Page 25: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 2

* 65535: end_part

*

* Vertices must be specified in counterclockwise order, or, in the case of

* triangle strips, they must be specified such that the first three vertices

* indicate a triangle in counterclockwise order. When specifying the 2D part

* of the model, counterclockwise order is relative to the front face.

*/

#include <fstream>

#include <math.h>

#ifdef __APPLE__

#include <OpenGL/OpenGL.h>

#include <GLUT/glut.h>

#else

#include <GL/glut.h>

#endif

#include "text3d.h"

using namespace std;

T3DLoadException::T3DLoadException(string message1) : message0(message1) {

}

string T3DLoadException::message() const {

return message0;

}

namespace {

//Converts a four-character array to an integer, using little-endian form

int toInt(const char* bytes) {

return int(((unsigned char)bytes[3] << 24) |

((unsigned char)bytes[2] << 16) |

((unsigned char)bytes[1] << 8) |

(unsigned char)bytes[0]);

}

//Converts a five-character array to a float, as indicated in the comment at

//the top of this file

float toFloat(const char* buffer) {

char exp = buffer[0];

int mant = toInt(buffer + 1);

bool isNegative;

if (mant < 0) {

isNegative = true;

mant = ~mant;

}

else

isNegative = false;

float a = (2147483648u + (unsigned int)mant) *

pow(2.0f, exp) / 2147483648.0;

return isNegative ? -a : a;

}

//Converts a two-character array to an unsigned short, using little-endian

//form

unsigned short toUShort(const char* buffer) {

return (((unsigned short)((unsigned char)buffer[1])) << 8) +

(unsigned short)((unsigned char)buffer[0]);

}

Page 26: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 3

//Just like auto_ptr, but for arrays

template<class T>

class auto_array {

private:

T* array;

mutable bool isReleased;

public:

explicit auto_array(T* array_ = NULL) :

array(array_), isReleased(false) {

}

auto_array(const auto_array<T> &aarray) {

array = aarray.array;

isReleased = aarray.isReleased;

aarray.isReleased = true;

}

~auto_array() {

if (!isReleased && array != NULL) {

delete[] array;

}

}

T* get() const {

return array;

}

T &operator*() const {

return *array;

}

void operator=(const auto_array<T> &aarray) {

if (!isReleased && array != NULL) {

delete[] array;

}

array = aarray.array;

isReleased = aarray.isReleased;

aarray.isReleased = true;

}

T* operator->() const {

return array;

}

T* release() {

isReleased = true;

return array;

}

void reset(T* array_ = NULL) {

if (!isReleased && array != NULL) {

delete[] array;

}

array = array_;

}

T* operator+(int i) {

return array + i;

}

T &operator[](int i) {

return array[i];

}

Page 27: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 4

};

enum Opcodes {OP_NORMAL = 65532,

OP_TRIANGLE_STRIP,

OP_TRIANGLES,

OP_END_PART};

const float PI_TIMES_2_OVER_65536 = 2 * 3.1415926535f / 65536.0f;

class T3DFont {

private:

float spaceWidth;

float widths[94];

GLuint displayListId2D;

GLuint displayListId3D;

public:

//Loads the specified font file into a new T3DFont object

T3DFont(ifstream &input) {

char buffer[8];

input.read(buffer, 8);

if (input.fail()) {

throw T3DLoadException("Invalid font file");

}

const char header[9] = "VTR\0FNT\0";

for(int i = 0; i < 8; i++) {

if (buffer[i] != header[i]) {

throw T3DLoadException("Invalid font file");

}

}

input.read(buffer, 5);

spaceWidth = toFloat(buffer);

displayListId2D = glGenLists(94);

displayListId3D = glGenLists(94);

for(int i = 0; i < 94; i++) {

input.read(buffer, 5);

float scale = toFloat(buffer) / 65536;

input.read(buffer, 2);

float width = scale * toUShort(buffer);

input.read(buffer, 2);

float height = scale * toUShort(buffer);

scale /= height;

widths[i] = width / height;

input.read(buffer, 2);

unsigned short numVerts = toUShort(buffer);

auto_array<float> verts(new float[2 * numVerts]);

float* verts2 = verts.get();

for(int j = 0; j < numVerts; j++) {

input.read(buffer, 2);

verts2[2 * j] = scale * ((int)toUShort(buffer) - 32768);

input.read(buffer, 2);

verts2[2 * j + 1] =

scale * ((int)toUShort(buffer) - 32768);

}

//Face part of the model

glNewList(displayListId2D + i, GL_COMPILE);

glNormal3f(0, 0, 1);

input.read(buffer, 2);

Page 28: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 5

unsigned short opcode = toUShort(buffer);

switch(opcode) {

case OP_TRIANGLES:

glBegin(GL_TRIANGLES);

break;

case OP_TRIANGLE_STRIP:

glBegin(GL_TRIANGLE_STRIP);

break;

default:

throw T3DLoadException("Invalid font file");

}

//Prevents excessive iteration or infinite loops on invalid

//font files

int limit = 10000;

while(true) {

input.read(buffer, 2);

opcode = toUShort(buffer);

switch(opcode) {

case OP_TRIANGLES:

glEnd();

glBegin(GL_TRIANGLES);

break;

case OP_TRIANGLE_STRIP:

glEnd();

glBegin(GL_TRIANGLE_STRIP);

break;

case OP_END_PART:

goto BreakOuter;

default:

glVertex3f(verts2[2 * opcode],

verts2[2 * opcode + 1],

0);

break;

}

if (--limit == 0) {

glEndList();

throw T3DLoadException("Invalid font file");

}

}

BreakOuter:

glEnd();

glEndList();

//3D part of the model

glNewList(displayListId3D + i, GL_COMPILE);

glPushMatrix();

glTranslatef(0, 0, 0.5f);

glFrontFace(GL_CW);

glCallList(displayListId2D + i);

glTranslatef(0, 0, -1);

glScalef(1, 1, -1);

glFrontFace(GL_CCW);

glCallList(displayListId2D + i);

glFrontFace(GL_CW);

input.read(buffer, 2);

opcode = toUShort(buffer);

switch(opcode) {

case OP_TRIANGLES:

glBegin(GL_TRIANGLES);

Page 29: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 6

break;

case OP_TRIANGLE_STRIP:

glBegin(GL_TRIANGLE_STRIP);

break;

default:

throw T3DLoadException("Invalid font file");

}

limit = 10000;

while(true) {

input.read(buffer, 2);

opcode = toUShort(buffer);

switch(opcode) {

case OP_TRIANGLES:

glEnd();

glBegin(GL_TRIANGLES);

break;

case OP_TRIANGLE_STRIP:

glEnd();

glBegin(GL_TRIANGLE_STRIP);

break;

case OP_NORMAL:

input.read(buffer, 2);

float angle;

angle = toUShort(buffer) *

PI_TIMES_2_OVER_65536;

float x, y;

x = cos(angle);

y = sin(angle);

glNormal3f(x, y, 0);

break;

case OP_END_PART:

goto BreakOuter2;

default:

if (opcode < numVerts) {

glVertex3f(verts2[2 * opcode],

verts2[2 * opcode + 1],

0);

}

else {

glVertex3f(verts2[2 * (opcode - numVerts)],

verts2[2 * (opcode - numVerts) +

1],

-1);

}

break;

}

if (--limit == 0) {

glEndList();

throw T3DLoadException("Invalid font file");

}

}

BreakOuter2:

glEnd();

glPopMatrix();

glEndList();

}

if (input.fail()) {

throw T3DLoadException("Invalid font file");

}

input.read(buffer, 1);

Page 30: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 7

if (!input.eof()) {

throw T3DLoadException("Invalid font file");

}

}

void draw2D(char c) {

if (c >= 33 && c <= 126) {

glCallList(displayListId2D + c - '!');

}

}

void draw3D(char c) {

if (c >= 33 && c <= 126) {

glCallList(displayListId3D + c - '!');

}

}

float width(char c) {

if (c >= 33 && c <= 126) {

return widths[c - 33];

}

else {

return spaceWidth;

}

}

};

T3DFont* font = NULL; //The font used to draw 2D and 3D characters

void draw2D(char c) {

font->draw2D(c);

}

void draw3D(char c) {

font->draw3D(c);

}

void drawLine(const char* str, int hAlign, void (*drawFunc)(char)) {

glPushMatrix();

if (hAlign >= 0) {

float width = 0;

for(int i = 0; str[i] != '\n' && str[i] != '\0'; i++) {

width += font->width(str[i]);

}

glTranslatef(hAlign > 0 ? -width : -width / 2, 0, 0);

}

for(int i = 0; str[i] != '\n' && str[i] != '\0'; i++) {

float width = font->width(str[i]);

glTranslatef(width / 2, 0, 0);

drawFunc(str[i]);

glTranslatef(width / 2, 0, 0);

}

glPopMatrix();

}

void draw(const char* str,

int hAlign, int vAlign,

float lineHeight,

void (*drawFunc)(char)) {

GLint shadeModel;

glGetIntegerv(GL_SHADE_MODEL, &shadeModel);

Page 31: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 8

glShadeModel(GL_SMOOTH);

GLboolean lightsEnabled;

glGetBooleanv(GL_LIGHTING, &lightsEnabled);

GLboolean normalsWereNormalized;

glGetBooleanv(GL_NORMALIZE, &normalsWereNormalized);

if (lightsEnabled) {

glEnable(GL_NORMALIZE);

}

else {

glDisable(GL_NORMALIZE);

}

glPushMatrix();

if (vAlign >= 0) {

int numLines = 1;

for(int i = 0; str[i] != '\0'; i++) {

if (str[i] == '\n') {

numLines++;

}

}

float height = lineHeight * (numLines - 1) + 1;

glTranslatef(0, vAlign > 0 ? height : height / 2, 0);

}

glTranslatef(0, -0.5f, 0);

drawLine(str, hAlign, drawFunc);

for(int i = 0; str[i] != '\0'; i++) {

if (str[i] == '\n') {

glTranslatef(0, -lineHeight, 0);

drawLine(str + i + 1, hAlign, drawFunc);

}

}

glPopMatrix();

glShadeModel(shadeModel);

if (normalsWereNormalized) {

glEnable(GL_NORMALIZE);

}

else {

glDisable(GL_NORMALIZE);

}

}

}

void t3dInit() {

if (font == NULL) {

ifstream input;

input.open("charset", istream::binary);

font = new T3DFont(input);

input.close();

}

}

void t3dCleanup() {

delete font;

}

void t3dDraw2D(string str, int hAlign, int vAlign, float lineHeight) {

GLboolean wasCulling;

glGetBooleanv(GL_CULL_FACE, &wasCulling);

glDisable(GL_CULL_FACE);

Page 32: Speed Typing Game C++ Prototype - All the source code

text3d.cpp — Printed on 29.12.2008, 13:29:58 — Page 9

draw(str.c_str(), hAlign, vAlign, lineHeight, draw2D);

if (wasCulling) {

glEnable(GL_CULL_FACE);

}

}

void t3dDraw3D(string str,

int hAlign, int vAlign,

float depth,

float lineHeight) {

GLboolean wasCulling;

glGetBooleanv(GL_CULL_FACE, &wasCulling);

glEnable(GL_CULL_FACE);

GLint frontFace;

glGetIntegerv(GL_FRONT_FACE, &frontFace);

glPushMatrix();

glScalef(1, 1, depth);

draw(str.c_str(), hAlign, vAlign, lineHeight, draw3D);

glPopMatrix();

if (!wasCulling) {

glDisable(GL_CULL_FACE);

}

glFrontFace(frontFace);

}

float t3dDrawWidth(string str) {

float bestWidth = 0;

int i = 0;

while (str[i] != '\0') {

float width = 0;

while (str[i] != '\n' && str[i] != '\0') {

width += font->width(str[i]);

i++;

}

if (width > bestWidth) {

bestWidth = width;

}

if (str[i] != '\0') {

i++;

}

}

return bestWidth;

}

float t3dDrawHeight(string str, float lineHeight) {

int numLines = 1;

for(int i = 0; str[i] != '\0'; i++) {

if (str[i] == '\n') {

numLines++;

}

}

return (numLines - 1) * lineHeight + 1;

}

Page 33: Speed Typing Game C++ Prototype - All the source code

imageloader.h — Printed on 29.12.2008, 13:27:48 — P age 1

/* File for "Fog" lesson of the OpenGL tutorial on

* www.videotutorialsrock.com

*/

#ifndef IMAGE_LOADER_H_INCLUDED

#define IMAGE_LOADER_H_INCLUDED

//Represents an image

class Image {

public:

Image(char* ps, int w, int h);

~Image();

/* An array of the form (R1, G1, B1, R2, G2, B2, ...) indicating the

* color of each pixel in image. Color components range from 0 to 255.

* The array starts the bottom-left pixel, then moves right to the end

* of the row, then moves up to the next column, and so on. This is the

* format in which OpenGL likes images.

*/

char* pixels;

int width;

int height;

};

//Reads a bitmap image from file.

Image* loadBMP(const char* filename);

#endif

Page 34: Speed Typing Game C++ Prototype - All the source code

imageloader.cpp — Printed on 29.12.2008, 13:27:33 — Page 1

/* File for "Fog" lesson of the OpenGL tutorial on

* www.videotutorialsrock.com

*/

#include <assert.h>

#include <fstream>

#include "imageloader.h"

using namespace std;

Image::Image(char* ps, int w, int h) : pixels(ps), width(w), height(h) {

}

Image::~Image() {

delete[] pixels;

}

namespace {

//Converts a four-character array to an integer, using little-endian form

int toInt(const char* bytes) {

return (int)(((unsigned char)bytes[3] << 24) |

((unsigned char)bytes[2] << 16) |

((unsigned char)bytes[1] << 8) |

(unsigned char)bytes[0]);

}

//Converts a two-character array to a short, using little-endian form

short toShort(const char* bytes) {

return (short)(((unsigned char)bytes[1] << 8) |

(unsigned char)bytes[0]);

}

//Reads the next four bytes as an integer, using little-endian form

int readInt(ifstream &input) {

char buffer[4];

input.read(buffer, 4);

return toInt(buffer);

}

//Reads the next two bytes as a short, using little-endian form

short readShort(ifstream &input) {

char buffer[2];

input.read(buffer, 2);

return toShort(buffer);

}

//Just like auto_ptr, but for arrays

template<class T>

class auto_array {

private:

T* array;

mutable bool isReleased;

public:

explicit auto_array(T* array_ = NULL) :

array(array_), isReleased(false) {

}

auto_array(const auto_array<T> &aarray) {

array = aarray.array;

Page 35: Speed Typing Game C++ Prototype - All the source code

imageloader.cpp — Printed on 29.12.2008, 13:27:33 — Page 2

isReleased = aarray.isReleased;

aarray.isReleased = true;

}

~auto_array() {

if (!isReleased && array != NULL) {

delete[] array;

}

}

T* get() const {

return array;

}

T &operator*() const {

return *array;

}

void operator=(const auto_array<T> &aarray) {

if (!isReleased && array != NULL) {

delete[] array;

}

array = aarray.array;

isReleased = aarray.isReleased;

aarray.isReleased = true;

}

T* operator->() const {

return array;

}

T* release() {

isReleased = true;

return array;

}

void reset(T* array_ = NULL) {

if (!isReleased && array != NULL) {

delete[] array;

}

array = array_;

}

T* operator+(int i) {

return array + i;

}

T &operator[](int i) {

return array[i];

}

};

}

Image* loadBMP(const char* filename) {

ifstream input;

input.open(filename, ifstream::binary);

assert(!input.fail() || !"Could not find file");

char buffer[2];

input.read(buffer, 2);

assert(buffer[0] == 'B' && buffer[1] == 'M' || !"Not a bitmap file");

input.ignore(8);

int dataOffset = readInt(input);

Page 36: Speed Typing Game C++ Prototype - All the source code

imageloader.cpp — Printed on 29.12.2008, 13:27:33 — Page 3

//Read the header

int headerSize = readInt(input);

int width;

int height;

switch(headerSize) {

case 40:

//V3

width = readInt(input);

height = readInt(input);

input.ignore(2);

assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");

assert(readShort(input) == 0 || !"Image is compressed");

break;

case 12:

//OS/2 V1

width = readInt(input);

height = readInt(input);

input.ignore(2);

assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");

break;

case 64:

//OS/2 V2

assert(!"Can't load OS/2 V2 bitmaps");

break;

case 108:

//Windows V4

assert(!"Can't load Windows V4 bitmaps");

break;

case 124:

//Windows V5

assert(!"Can't load Windows V5 bitmaps");

break;

default:

assert(!"Unknown bitmap format");

}

//Read the data

int bytesPerRow = ((width * 3 + 3) / 4) * 4 - (width * 3% 4);

int size = bytesPerRow * height;

auto_array<char> pixels(new char[size]);

input.seekg(dataOffset, ios_base::beg);

input.read(pixels.get(), size);

//Get the data into the right format

auto_array<char> pixels2(new char[width * height * 3]);

for(int y = 0; y < height; y++) {

for(int x = 0; x < width; x++) {

for(int c = 0; c < 3; c++) {

pixels2[3 * (width * y + x) + c] =

pixels[bytesPerRow * y + 3 * x + (2 - c)];

}

}

}

input.close();

return new Image(pixels2.release(), width, height);

}

Page 37: Speed Typing Game C++ Prototype - All the source code

vec3f.h — Printed on 29.12.2008, 13:30:52 — Page 1

/* Permission is hereby granted, free of charge, to any person obtaining a copy

* of this software and associated documentation files (the "Software"), to deal

* in the Software without restriction, including without limitation the rights

* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

* copies of the Software, and to permit persons to whom the Software is

* furnished to do so, subject to the following conditions:

*

* The above notice and this permission notice shall be included in all copies

* or substantial portions of the Software.

*

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

* SOFTWARE.

*/

/* File for "Alpha Blending" lesson of the OpenGL tutorial on

* www.videotutorialsrock.com

*/

#ifndef VEC3F_H_INCLUDED

#define VEC3F_H_INCLUDED

#include <iostream>

class Vec3f {

private:

float v[3];

public:

Vec3f();

Vec3f(float x, float y, float z);

float &operator[](int index);

float operator[](int index) const;

Vec3f operator*(float scale) const;

Vec3f operator/(float scale) const;

Vec3f operator+(const Vec3f &other) const;

Vec3f operator-(const Vec3f &other) const;

Vec3f operator-() const;

const Vec3f &operator*=(float scale);

const Vec3f &operator/=(float scale);

const Vec3f &operator+=(const Vec3f &other);

const Vec3f &operator-=(const Vec3f &other);

float magnitude() const;

float magnitudeSquared() const;

Vec3f normalize() const;

float dot(const Vec3f &other) const;

Vec3f cross(const Vec3f &other) const;

};

Vec3f operator*(float scale, const Vec3f &v);

std::ostream &operator<<(std::ostream &output, const Vec3f &v);

Page 38: Speed Typing Game C++ Prototype - All the source code

vec3f.h — Printed on 29.12.2008, 13:30:52 — Page 2

#endif

Page 39: Speed Typing Game C++ Prototype - All the source code

vec3f.cpp — Printed on 29.12.2008, 13:30:28 — Page 1

/* Permission is hereby granted, free of charge, to any person obtaining a copy

* of this software and associated documentation files (the "Software"), to deal

* in the Software without restriction, including without limitation the rights

* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

* copies of the Software, and to permit persons to whom the Software is

* furnished to do so, subject to the following conditions:

*

* The above notice and this permission notice shall be included in all copies

* or substantial portions of the Software.

*

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

* SOFTWARE.

*/

/* File for "Alpha Blending" lesson of the OpenGL tutorial on

* www.videotutorialsrock.com

*/

#include <math.h>

#include "vec3f.h"

using namespace std;

Vec3f::Vec3f() {

}

Vec3f::Vec3f(float x, float y, float z) {

v[0] = x;

v[1] = y;

v[2] = z;

}

float &Vec3f::operator[](int index) {

return v[index];

}

float Vec3f::operator[](int index) const {

return v[index];

}

Vec3f Vec3f::operator*(float scale) const {

return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);

}

Vec3f Vec3f::operator/(float scale) const {

return Vec3f(v[0] / scale, v[1] / scale, v[2] / scale);

}

Vec3f Vec3f::operator+(const Vec3f &other) const {

return Vec3f(v[0] + other.v[0], v[1] + other.v[1], v[2] + other.v[2]);

}

Vec3f Vec3f::operator-(const Vec3f &other) const {

return Vec3f(v[0] - other.v[0], v[1] - other.v[1], v[2] - other.v[2]);

}

Page 40: Speed Typing Game C++ Prototype - All the source code

vec3f.cpp — Printed on 29.12.2008, 13:30:28 — Page 2

Vec3f Vec3f::operator-() const {

return Vec3f(-v[0], -v[1], -v[2]);

}

const Vec3f &Vec3f::operator*=(float scale) {

v[0] *= scale;

v[1] *= scale;

v[2] *= scale;

return *this;

}

const Vec3f &Vec3f::operator/=(float scale) {

v[0] /= scale;

v[1] /= scale;

v[2] /= scale;

return *this;

}

const Vec3f &Vec3f::operator+=(const Vec3f &other) {

v[0] += other.v[0];

v[1] += other.v[1];

v[2] += other.v[2];

return *this;

}

const Vec3f &Vec3f::operator-=(const Vec3f &other) {

v[0] -= other.v[0];

v[1] -= other.v[1];

v[2] -= other.v[2];

return *this;

}

float Vec3f::magnitude() const {

return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);

}

float Vec3f::magnitudeSquared() const {

return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];

}

Vec3f Vec3f::normalize() const {

float m = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);

return Vec3f(v[0] / m, v[1] / m, v[2] / m);

}

float Vec3f::dot(const Vec3f &other) const {

return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2];

}

Vec3f Vec3f::cross(const Vec3f &other) const {

return Vec3f(v[1] * other.v[2] - v[2] * other.v[1],

v[2] * other.v[0] - v[0] * other.v[2],

v[0] * other.v[1] - v[1] * other.v[0]);

}

Vec3f operator*(float scale, const Vec3f &v) {

return v * scale;

}

ostream &operator<<(ostream &output, const Vec3f &v) {

cout << '(' << v[0] << ", " << v[1] << ", " << v[2] << ')';

return output;

Page 41: Speed Typing Game C++ Prototype - All the source code

vec3f.cpp — Printed on 29.12.2008, 13:30:28 — Page 3

}

Page 42: Speed Typing Game C++ Prototype - All the source code

Word.h — Printed on 29.12.2008, 13:31:22 — Page 1

#ifndef WORD_H_

#define WORD_H_

#include "const.h"

using namespace std;

class Word {

public:

int id;

string name; //[MAXWORTLAENGE];

float posX;

float posY;

float posZ;

float angle;

Word(string strWord);

virtual ~Word();

string getWord();

string createNewWord(void);

void initWordlist(void);

void moveWord(void);

float getRandomNr(int min, int max);

void resetWordPos(void);

};

#endif /*WORD_H_*/

Page 43: Speed Typing Game C++ Prototype - All the source code

Word.cpp — Printed on 29.12.2008, 13:31:09 — Page 1

#include <cstring>

#include <iostream>

#include <stdlib.h>

// für datei einlesen

#include <fstream>

#include "Word.h"

using namespace std;

Word::Word(string strWord) {

name = strWord;

posX = getRandomNr(-15, 15);

// posY = getRandomNr(-5, 10);

posY = 0.0f;

posZ = -20.0f;

angle = 5.0f;

}

Word::~Word()

{

}

string Word::getWord() {

cout << "transfered word: " << name << endl;

return name;

};

float Word::getRandomNr(int min, int max) {

// Initialisierung, nötig für Zufallszahl

srand ( time(NULL) );

// generiere die Zufallszahl

return (float) ( min + ( rand() % ( max - min + 1 ) ) )+0.5f;

}

void Word::resetWordPos(void) {

posX = getRandomNr(-15, 15);

// posY = getRandomNr(-5, 10);

posY = 0.0f;

posZ = -20.0f;

angle = getRandomNr(0, 5);

}

Page 44: Speed Typing Game C++ Prototype - All the source code

Seite 1 von 4

Projekt: Spielentwicklung in OpenGL - „SpongeBob’s Words“ Student: Kai Kajus NoackDatum: 2008-01-20 1. Einleitung

Das von mir entwickelte Spiel „SpongeBob’s Words” stellt dem Spieler die Aufgabe, aus dem Hintergrund anfliegende Wörter korrekt mit der Tastatur einzugeben. Dabei stören ihn diverse grafische Objekte, indem sie ihm die Sicht auf die Wörter versperren. Am Ende des Spiels wird der Spieler mit einer statistischen Auswertung belohnt, die ihm Fehlerquotient und die Anschläge pro Minute angibt. 2. Bestandteile des Programms

Datei Beschreibung const.h enthält alle Konstanten des Spiels imageloader.cpp + .h Funktionalität zum Laden einer Bitmap-Datei main.cpp + .h Spielfunktionalität und OpenGL-Zeichnen text3d.cpp + .h 3D-Text-Zeichner vec3f.cpp + .h Vektorklassen Word.cpp + .h Word-Spielobjekt wordlist.txt stellt abzufragende Wörter bereit charset (Byte-Datei) enthält Code zur Darstellung des 3D-Textes img/floor.bmp Textur für den Untergrund des Spiels img/spongebob.bmp Textur für Spongebob-Elemente

Beim Spielstart stehen dem Spieler die Spielmodi Countdown und Training zur Verfügung. Training ist dabei endlos, der Countdown zählt 60 Sekunden abwärts. Countdown ist der spannende Teil, da dieser den Spieler unter Druck setzt. Am Ende des Spiels ist eine Statistik wie links zu sehen eingebaut, die die erbrachte Leistung analysiert.

3. Benutzereingaben im Spiel

• a - z - Eingabe der Buchstaben • Enter - Eingegebenes Wort bestätigen - Neustart des Spiels (bei Game Over) • Esc - Verlassen des Spiels

Page 45: Speed Typing Game C++ Prototype - All the source code

Seite 2 von 4

4. Effekte, Elemente und Techniken

Sämtlicher Code wurde von mir in den Cpp- und Header-Dateien ausführlich kommentiert und ist leicht nachvollziehbar. Trotzdem möchte ich kurz auf die im Spiel eingebauten Effekte, Elemente und Techniken eingehen. Die nachfolgende Grafik zeigt einen Großteil davon:

Die main()-Methode in der main.cpp nimmt zu Beginn die Initialisierungen für alle Elemente des Spiels vor und definiert die Handler-Methoden. In der initRendering() werden die Texturen geladen und sämtliche Schalter für Licht, Tiefentest, Shade-Modell, Normalen und Nebel aktiviert. In der drawScene() befinden sich die Anweisungen, ob Start- oder GameOver-Screen oder das laufende Spiel gezeichnet werden soll. Zeit + Punkte Diese Elemente sind dynamisch, werden mithilfe der text3d-Klasse gezeichnet und befinden sich stets im Vordergrund, da ich vor dem Zeichnen den GL_DEPTH_TEST ausschalte. Farblich habe ich sie rot hervorgehoben, damit sie während des Spiels leicht erkennbar sind. Für das Funktionieren des Timers und der Punkt-Anzeige sind verschiedene Zähl-, Timer- und String-Variablen sowie Stringstreams (für das Casten von Integer zu String) nötig geworden. Partikeleffekt Für den Partikeleffekt habe ich Elemente aus einem Tutorial von videotutorialsrock.com genutzt und diese implementiert. Jeder Partikel ist ein Objekt mit Positions-, Farb-, Geschwindigkeits- und Größen-Eigenschaften, die über die Methode glCreateParticles() zu Beginn des Spiels festgelegt und mit der glUpdateParticles() während des Spiels modifiziert werden. Die glDrawParticles() zeichnet die Partikelobjekte nach dem Update der Partikeldaten mit den neuen Werten. Die y-Position wurde von mir im Übrigen so verändert, dass die Partikel sich weniger stark in der Höhe, sondern sich in der Breite des „Himmels“ des Spiels verteilen. Würfel mit Alphakanal Für diesen Würfel konnte ich ebenfalls Informationen aus videotutorialsrock.com nutzen. Die Seiten-flächen (Faces) des Würfels werden als Objekte definiert und über Zuhilfenahme der Vektorklasse vec3f.cpp rotiert. Es wird geprüft, welche Seite dem Spieler zugewandt ist und daraufhin die sechs Seiten unter Berücksichtigung der Alpha-Werte gezeichnet. Die Seitenflächen des Würfels sind mit Texturen bekleidet, die ich in der main-Klasse lade (vgl. Methode loadTexture) und verfügbar mache. Zu beachten war hier, dass der Nebel (GL_FOG) vor dem Zeichnen des Alphawürfels ausgeschaltet werden musste, da dieser sonst fahl-grau aussah.

Page 46: Speed Typing Game C++ Prototype - All the source code

Seite 3 von 4

Übrigens wird der Würfel im Spielverlauf mit den richtigen Eingaben des Spielers größer skaliert und bewegt sich auf ihn zu. Anfliegendes Wort Für jedes Wort wird ein Objekt „Word“ erstellt, mit zufälligen Positions-Parametern für die x-Ebene. Der Text wird über die text3d-Klasse gezeichnet. Die Zeilenhöhe und -breite sowie die Texttiefe sind über die Methode t3dDraw3D() frei wählbar. Die 3D-Buchstaben werden aus der Byte-Datei charset ausgelesen und in der text3d-Klasse als Schriftart (Font) verwendet. Jedes Wort kommt aus dem Hintergrund. Wenn es jedoch hinter dem Spieler verschwindet, es also den Sichtbereich verlässt, erscheint es wieder von Neuem im Hintergrund. Alle zweitausend mög-lichen Wörter werden aus der wordlist.txt eingelesen (vgl. Methode initWordlist), in der main-Klasse in ein Array gelegt und dort weiter genutzt. Über eine Zufallszahl wird eins der Wörter ausgewählt und an die zeichnende Methode und an die Methoden der Spiellogik übergeben. Rotierender Würfel mit ambientem Licht Dieser Würfel wird über die Methode paintFlyingCube() erstellt. Jeder Vertex erhält seine eigene Normale, sodass durch das gewählte Smooth-Shading (vgl. Methode initRendering) ein leichter Farb-verlauf auftritt. Weiterhin wird der Würfel über eine dynamische Variable rotiert. Gegebenenfalls kann ein zusätzliches rötliches Licht gesetzt werden (vgl. Auskommentierung im Quellcode). Textur auf Textur Für die Spongebob-Platte wird eine Textur aus der „spongebob.bmp“ mittels der loadTexture()-Methode erstellt. Der Nebeleffekt (weiter unten erklärt) ist vor dem Zeichnen der Platte auszu-schalten, da ansonsten die Textur farblich sehr matt dargestellt wird. Reflexion des Wortes Die Implementierung der Reflexion (vgl. Methode moveAndPaintWord) erfolgte durch das nochmalige Zeichnen des Wortes, einer Hellblaufärbung, der Rotation um 180° um die x-Achse und der Translationen abwärts (y-Achse) und nach hinten (z-Achse). Bodenplatte mit Textur Die Bodenplatte erhält eine Wasser-Textur unter Verwendung der Bilddatei „floor.bmp“. Hier wurde im Gegensatz zur Zeichnung der ersten Textur der Nebel nicht ausgeschaltet, sodass ein in den Horizont ins Weiße verschwimmender Effekt auftritt.

Eingaben des Spielers Die Tastatureingaben des Spielers werden rechts unten gezeichnet. Hierzu wird das eingegebene Zeichen direkt an die Methode showKeyboardInput() übergeben. Die Eingaben werden über Methode checkUserInput() geprüft und entsprechend vom Programm reagiert.

Implementierung des Blitz-Effekts Sofern der Spieler das Wort richtig eingegeben und mit Enter bestätigt hat, blitzt es 5 mal hintereinander hell auf. Dieser Effekt wird über einen Boolean-Wert, eine Zählvariable und eine if-Bedingung (modular) gesteuert und generiert. Der gesamte Bildschirm wird abwechselnd kurz weiß und dann wieder normal gezeichnet, wodurch der Eindruck eines Blitzes entsteht (vgl. Methode blitzen(), glClearColor). Nebeleffekt Der Nebel wird in der Methode paintFog() angeschaltet, dessen Farbe bestimmt sowie Start- und Endwert in Richtung z-Achse gesetzt. In dieser Methode verbirgt sich übrigens auch der geheime psychomode, der mit der Tastatureingabe „000“ de-/aktiviert werden kann. Für diesen Modus habe ich mir die Sinus- und Cosinusfunktionen zu Hilfe genommen und ein kronenartiges, rotierendes Objekt geschaffen. Dieser Modus ist sehr farbenfroh ☺

Page 47: Speed Typing Game C++ Prototype - All the source code

Seite 4 von 4

Start-Screen Wie auch bei den anderen Text-Zeichnungen wird hier die Methode t3dDraw3D() verwendet und zuvor muss, wie bereits ein paar Mal aufgeführt, der Nebel ausgeschaltet werden. Game-Over-Screen und Statistik Das “Game Over” links im Bild rotiert über eine Cosinus-Funktion, der Partikeleffekt läuft weiter und die kalkulierten Statistiken werden dem Spieler dargestellt.

Weitere Methoden:

- update() dynamisiert die Werte der Objekte - convertRADtoANGLE() konvertiert Radianz-Werte in Winkel - Round() rundet auf die angegebene Anzahl an Nachkommastellen - handleResize() beachtet die Veränderung der Fenstergröße. 5. Fazit

Es hat wirklich Spaß gemacht, ein funktionierendes Spiel mit Logik und Grafik zu entwerfen, auch wenn ich dafür 15 Tage Arbeit, also etwa 70-80 Stunden investieren musste. Der Mehraufwand entstand, da C++ bisher nicht Bestandteil unseres Studiums war. Ich freue mich sehr, dass „Spongebob’s Words!“ gut bei den Kommilitonen ankommt und dazu anregt, das Spiel mehr als nur einmal zu spielen. Kai Kajus Noack 6. Quellen & Referenzen - „Computer Graphics“ Vorlesungsskripte (IMI-Master) von Herrn Dr. Eisert - „OpenGL SuperBible 4th Edition” (Wright, Lipchak, Haemel) - „OpenGL Programming Guide“ Addison Wesley - „Eine Einführung in OpenGL” der Uni Augsburg (pdf-Link) Online:

http://www.videotutorialsrock.com/ http://www.cplusplus.com/reference/ http://www.swiftless.com/tutorials/opengl/opengltuts.html http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/FAQ.html Ressourcen:

Aus www.videotutorialsrock.com wurden entnommen: - charset - imageloader.cpp - text3d.cpp - vec3f.cpp Die Spongebob-Grafik wurde modifiziert und entstammt aus: http://www.poster.de/Spongebob/Spongebob-SpongeBob-SquarePants-9962695.html


Recommended