Exemple 7: un programme de labyrinthe
Ce programme est un exemple plus complet. Il génère un labyrinthe (avec un algorithme simple qui pourrait être amélioré) et donne la possibilité de naviguer à l’intérieur. Les murs, le sol et le paysage sont texturés.
Programme : examples/prog7.cpp
Sources :examples/glut-examples-src.zip
Textures :examples/glut-examples-bmp.zip
Exécutables pour Windows :examples/glut-examples-win32exe.zip
/* Un exemple un peu plus complet, où un labyrinthe est généré, puis affiché. */ #include <math.h> //#define debug #define PI 3.141592653589793 #include "application.h" #include "animation.h" #include "mazemesh.h" class Actor{ Window *Parent; public: Vect2<int> Cell; Direction Dir; Vect3<float> PositionOffset; float AngleOffset; Actor(Window *parent){ Parent=parent; Cell=vect(0,0); Dir=NORTH; PositionOffset=vect(0,0,0); AngleOffset=0; }; void bind(){ float o=PI*0.5*(-1-Dir)+AngleOffset; Vect3<float> p=vect((float) Cell.A,0.f,(float) Cell.B)+PositionOffset+vect(0.5f,0.6f,0.5f); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(100,(float) Parent->getWidth()/Parent->getHeight(),0.1,1000); gluLookAt(p.A,p.B,p.C,p.A+cos(o),p.B,p.C+sin(o),0,1,0); }; }; class ActorAnimation:public Animation{ protected: Actor *Player; public: ActorAnimation(Actor *player):Animation(500),Player(player){}; }; template<int Delta> class RotateAnimation:public ActorAnimation{ protected: void execute(int ElapsedTime,int DeltaTime){ Player->AngleOffset=PI*0.5*Delta*ElapsedTime/Length; }; void terminate(){ if (Delta==1) Player->Dir=turnLeft(Player->Dir); else Player->Dir=turnRight(Player->Dir); Player->AngleOffset=0; }; public: RotateAnimation(Actor *player):ActorAnimation(player){}; }; template<int Delta> class TranslateAnimation:public ActorAnimation{ protected: void execute(int ElapsedTime,int DeltaTime){ float r=((float) ElapsedTime)/Length*Delta; float o=PI*0.5*(-1-Player->Dir); Player->PositionOffset=vect<float>(r*cos(o),0,r*sin(o)); }; void terminate(){ switch (Player->Dir){ case NORTH: Player->Cell.B-=Delta; break; case WEST: Player->Cell.A-=Delta; break; case SOUTH: Player->Cell.B+=Delta; break; case EAST: Player->Cell.A+=Delta; break; } Player->PositionOffset=vect(0,0,0); }; public: TranslateAnimation(Actor *player):ActorAnimation(player){}; }; class MainWindow: public Window{ public: MazeGrid *Grid; Actor *Player; MazeMesh *Mesh; AnimationList<1> Animations; MainWindow(char *name):Window(name){ setDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); addCallBacks(WC_IDLE); setWidth(640); setHeight(480); setX((glutGet(GLUT_SCREEN_WIDTH)-640)/2); setY((glutGet(GLUT_SCREEN_HEIGHT)-480)/2); }; void onDisplay(){ glClear(GL_DEPTH_BUFFER_BIT); if (!Animations.execute()) removeCallBacks(WC_IDLE); Player->bind(); Mesh->bind(); glFlush(); glutSwapBuffers(); }; void onSpecial(int key,int x,int y){ switch (key){ case GLUT_KEY_LEFT: if (Animations.getCount()==0) Animations.add(new RotateAnimation<-1>(Player)); break; case GLUT_KEY_RIGHT: if (Animations.getCount()==0) Animations.add(new RotateAnimation<1>(Player)); break; case GLUT_KEY_UP: if (Animations.getCount()==0 && Grid->canMove(Player->Cell.A,Player->Cell.B,Player->Dir)) Animations.add(new TranslateAnimation<1>(Player)); break; case GLUT_KEY_DOWN: if (Animations.getCount()==0 && Grid->canMove(Player->Cell.A,Player->Cell.B,Player->Dir,1)) Animations.add(new TranslateAnimation<-1>(Player)); break; } if (Animations.getCount()>0) addCallBacks(WC_IDLE); }; void onCreate(){ Grid=new MazeGrid(10,10); Grid->generate(10000); printf("Utiliser les fleches de direction du clavier pour se diriger dans le labyrinthe\n"); Mesh=new MazeMesh(Grid); Player=new Actor(this); glEnable(GL_DEPTH_TEST); glutReportErrors(); }; }; int main(int argc,char *argv[]){ MainWindow mainWindow("Maze-3D"); Application::run(); }
Dernière modification le 18/3/2010
Ce document a été traduit de LaTeX par HeVeA