Bon j'ai pas reussi a trouver le bug je reeserai p-t demain si j'ai le temps.
Si y'en a qui veulent essayer, ...
#include <math.h>
#include <X11/Xlib.h>
#define XSIZE 800
#define YSIZE 600
#define FOV 90.0f
#define WALL 1
#define CARRE(a) ((a) * (a))
#define RADIAN(a) ((a) * 2 * 3.141592f / 360)
typedef struct s_mlx {
Display *dpy;
Window win;
GC v1;
GC v2;
float angle;
int level_size_x;
int level_size_y;
float pos_x;
float pos_y;
int tab[50 * 50];
} t_mlx;
typedef struct s_floatpoint {
float x;
float y;
} t_floatpoint;
typedef struct s_point {
float fx;
float fy;
int x;
int y;
} t_point;
void put_pixel(t_mlx *w, int x, int color)
{
if (color == 0xFF)
XDrawPoint(w->dpy, w->win, w->v1, x % XSIZE, x / XSIZE - 1); //plafond vert
else if (color == 0xFF0000)
XDrawPoint(w->dpy, w->win, w->v2, x % XSIZE, x / XSIZE - 1); //sol bleu
else
XDrawPoint(w->dpy, w->win, DefaultGC(w->dpy, DefaultScreen(w->dpy)), x % XSIZE, x / XSIZE - 1);
}
/*
** Affiche une ligne de l'ecran en X contenant le plafond, le mur (avec shading), et le sol, suivant la distance K du rayon [personnage -> colision mur]
*/
void draw_wall_line(t_mlx *w, int x, int k)
{
int i;
if (k > (YSIZE / 2))
k = YSIZE / 2;
for (i = 0; i < (YSIZE / 2) - k; i++)
put_pixel(w, x += XSIZE, 0xFF);
for (i = 0; i < k * 2; i++)
put_pixel(w, x += XSIZE, k);
for (i = 0; i < (YSIZE / 2) - k; i++)
put_pixel(w, x += XSIZE, 0xFF0000);
}
/*
** Calcul le vecteur du rayon a tracer suivant l'angle courant du joueur
*/
t_floatpoint return_vector(int x, double a)
{
t_floatpoint e1;
t_floatpoint e2;
e1.x = 0.5;
e1.y = (1.0 * ((XSIZE / 2) - x)) / XSIZE;
e2.x = (e1.x * cos(RADIAN(a))) - (e1.y * sin(RADIAN(a)));
e2.y = (e1.x * sin(RADIAN(a))) + (e1.y * cos(RADIAN(a)));
return (e2);
}
/*
** Fonction pas a la norme (je sais)
** affiche le monde 3D a l'ecran de X0, a XSIZE-1, en balayant le tableau en fonction du FOV du joueur (FOV = 90.0f, XSIZE = 640)
** je passe par un xsize_f parceque sinon une division d'un float par un entier tout les 2 mis en #define, ca me sort automatiquement 0
** (la aussi j'aimerais comprendre), a = angle courant incrementer a chaque ligne, ainc = incrementation suivant XSIZE et FOV
** k = distance de ma droite/rayon, kk etait utilise pour la correction de distance, genre: kk = k * cos(x * ainc) ou truc du genre, mais ca ne fonctionne pas, j'ai le meme resultat graphique
*/
void render_raycast(t_mlx *w)
{
t_floatpoint e;
t_point final;
double a;
float xsize_f;
float ainc;
int x;
float k;
float kk;
xsize_f = XSIZE;
ainc = FOV / xsize_f;
a = w->angle + (FOV / 2);
for (x = 0; x < XSIZE; x++)
{
e = return_vector(x, a);
for (k = 0; k < w->level_size_x * 2; k = k + 0.01f)
{
kk = k;
final.x = w->pos_x + e.x * kk;
final.y = w->pos_y + e.y * kk;
final.y = w->level_size_y - final.y - 1;
if ((final.x >= 0) && (final.x < w->level_size_x) &&
(final.y >= 0) && (final.y < w->level_size_y))
if (w->tab[final.y * w->level_size_x +
final.x] >= WALL)
{
draw_wall_line(w, x, YSIZE / (2 * (kk)));
break ;
}
}
a = a - ainc;
}
}
#include <stdlib.h>
int main()
{
t_mlx d_mlx;
XGCValues xv1,xv2;
XColor pix;
XColor useless;
int x;
int y;
d_mlx.dpy = XOpenDisplay(NULL);
d_mlx.win = XCreateSimpleWindow(d_mlx.dpy, DefaultRootWindow(d_mlx.dpy), 0, 0, 800, 600, 1,
BlackPixel(d_mlx.dpy, DefaultScreen(d_mlx.dpy)),
WhitePixel(d_mlx.dpy, DefaultScreen(d_mlx.dpy)));
XMapWindow(d_mlx.dpy, d_mlx.win);
XFlush(d_mlx.dpy);
XAllocNamedColor(d_mlx.dpy, DefaultColormap(d_mlx.dpy, DefaultScreen(d_mlx.dpy)),
"green", &pix, &useless);
xv1.foreground = pix.pixel;
XAllocNamedColor(d_mlx.dpy, DefaultColormap(d_mlx.dpy, DefaultScreen(d_mlx.dpy)),
"blue", &pix, &useless);
xv2.foreground = pix.pixel;
d_mlx.v1 = XCreateGC(d_mlx.dpy, DefaultRootWindow(d_mlx.dpy), GCForeground, &xv1);
d_mlx.v2 = XCreateGC(d_mlx.dpy, DefaultRootWindow(d_mlx.dpy), GCForeground, &xv2);
d_mlx.angle = 180;
d_mlx.level_size_x = d_mlx.level_size_y = 50;
d_mlx.pos_x = 20;
d_mlx.pos_y = 30;
for (y = 0; y < 50; ++y)
{
for (x = 0; x < 50; ++x)
{
d_mlx.tab[50 * y + x] = 0;
if (x == 18)
d_mlx.tab[50 * y + x] = 1;
if (y == 30 && x >= 22)
d_mlx.tab[50 * y + x] = 1;
if (y == 0 || y == 49 || x == 0 || x == 49)
d_mlx.tab[50 * y + x] = 2;
if (y == d_mlx.pos_y && x == d_mlx.pos_x)
printf("X");
else
{
if (d_mlx.tab[50 * y + x] == 1)
printf("1");
else if (d_mlx.tab[50 * y + x] == 2)
printf("@");
else
printf("0");
}
}
printf("\n");
}
XSelectInput(d_mlx.dpy, d_mlx.win, ExposureMask|KeyPressMask);
while (1)
{
XEvent xev;
XNextEvent(d_mlx.dpy, &xev);
if (xev.type = KeyPress)
{
printf("key: %u.\n", xev.xkey.keycode);
switch (xev.xkey.keycode) {
case 98: d_mlx.pos_y-=1 ; break; //haut
case 104: d_mlx.pos_y+=1 ; break; //bas
case 100: d_mlx.pos_x-=1 ; break; //g
case 102: d_mlx.pos_x+=1 ; break; //d
case 86: d_mlx.angle+=45 ; break; //g
case 82: d_mlx.angle-=45 ; break; //d
case 9: exit(0); //echap
}
printf("x: %f, y: %f, a: %f.\n", d_mlx.pos_x, d_mlx.pos_y, d_mlx.angle);
}
render_raycast(&d_mlx);
}
XCloseDisplay(d_mlx.dpy);
}
cc -o ray ray.c -I/usr/X11R6/include/ -L/usr/X11R6/lib/ -lX11 -lm
La touche echap quitte
Les touches de direction deplacent sur les axes (non pas par rapport a l'angle de vue)
Les touches +/- modifient l'angle de vue.
Et il faut appuyer sur enter lorsqu'on l'as lancé pour afficher.
good luck