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.
Fichier : examples/prog7.cpp /*
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();
} Ce document a été traduit de LaTeX par HeVeA |