Partage
  • Partager sur Facebook
  • Partager sur Twitter

Aide concernant angle de vue, jeu 2d-3d

    16 février 2023 à 20:44:41

    Bonsoir, je suis en train de crer un jeu 2D simulant la 3D aussi appelé raycasting. JE viens de créer la map en 2D, je l'affiche correctement avec draw_minimap.

    Maintenant, je suis un tuto pour pouvoir déplacer mon player correctement selon l'angle de vue, je n'ai aucun problème dès le lancement du programme pour reculer ou avancer definit par TOP et BOTTOM dans mon code, mais dès lors que je change l'angle de vue avec les flèches de gauche et droite definit par LEFT et RIGHT dans mon code, mon player ne se déplace plus correctement lorsque je recule et j'arrive pas à comprendre pourquoi!!

    Aussi, outre ce problème, j'en ai un autre mais plus minime, lorsque mon angle de vue est diagonal, mon player n'avance pas correctement en diagonale il avance en escalier si vous voyez ce que je veux dire et là aussi je comprend pas pourquoi même si je pense que cela viens des double que j'utilise et que je les cast mal sans doute

    Voici les constantes définit dans mon .h

    # define WIDTH	1280
    # define HEIGHT	720
    
    # define GAME_WIDTH		WIDTH - (WIDTH / 4)
    # define GAME_HEIGHT	HEIGHT - (HEIGHT / 2)
    
    # define ROTATION_SPEED	2. * (M_PI / 180.)
    # define MOVE_SPEED	2.

    main.c

    #include <stdio.h>
    #include "./includes/cub3d.h"
    
    void	mlx_put_pixel(t_mlx mlx, int x, int y, int color)
    {
    	char	*dst;
    
    	dst = mlx.addr + (y * mlx.line_length[mlx.index] + x * (mlx.bits_per_pixel[mlx.index] / 8));
    	*(unsigned int *)dst = color;
    }
    
    static
    void	get_playerpos(t_data *data)
    {
    	for (int i = 0; i < data -> map.height; i++)
    	{
    		for (int j = 0; data -> map.map[i][j]; j++)
    		{
    			if (data -> map.map[i][j] == 'N')
    			{
    				data -> player.y = i;
    				data -> player.x = j;
    				return ;
    			}
    		}
    	}
    }
    
    static
    int	quit(t_data *data)
    {
    	mlx_loop_end(data -> mlx_ptr);
    	return (EXIT_SUCCESS);
    }
    
    static
    int	key_hook(int keycode, t_data *data)
    {
    	if (keycode == ESC)
    		mlx_loop_end(data -> mlx_ptr);
    	if (keycode == TOP || keycode == W)
    		data -> player.walk_direction = + 1;
    	if (keycode == DOWN || keycode == S)
    		data -> player.walk_direction = - 1;
    	if (keycode == LEFT || keycode == A)
    		data -> player.view_direction = - 1;
    	if (keycode == RIGHT || keycode == D)
    		data -> player.view_direction = + 1;
    	draw_minimap(data);
    	if (keycode == TOP || keycode == W)
    		data -> player.walk_direction = 0;
    	if (keycode == DOWN || keycode == S)
    		data -> player.walk_direction = 0;
    	if (keycode == LEFT || keycode == A)
    		data -> player.view_direction = 0;
    	if (keycode == RIGHT || keycode == D)
    		data -> player.view_direction = 0;
    	print_map(*data);
    	return (0);
    }
    
    static
    int	lunch_game(t_data *data)
    {
    	if (init_mlx(data))
    		return (EXIT_FAILURE);
    	if (init_map(data))
    		return (EXIT_FAILURE);
    	draw_game(data);
    	if (init_minimap(data))
    		return (EXIT_FAILURE);
    	draw_minimap(data);
    	if (init_gameplay(data))
    		return (EXIT_FAILURE);
    	// draw_gameplay(data, 1);
    	mlx_hook(data -> win_ptr, CLOSE, 0, & quit, data);
    	mlx_hook(data -> win_ptr, 1, 1UL << 0, & key_hook, data);
    	mlx_key_hook(data -> win_ptr, & key_hook, data);
    	mlx_loop(data -> mlx_ptr);
    	return (0);
    }
    
    int	main(int ac, char **av, char **env)
    {
    	static t_data	data = {0, .player.rotation_angle = M_PI / 2.};
    	int				ret;
    
    	if (!env || !*env || ac != 2)
    		return (EXIT_FAILURE);
    	data.map.filename = av[1];
    	ret = parse_map(& data.map);
    	if (ret == EXIT_SUCCESS)
    	{
    		get_playerpos(& data);
    		print_map(data);
    		lunch_game(& data);
    	}
    	else
    		ft_printf("{blue}-->{yellow}Parsing: {red}%d{reset}\n", ret);
    	free_cub3d(& data);
    	return (EXIT_SUCCESS);
    }
    

    draw.c

    void	draw_ray(t_data *data)
    {
    	const int	y = data -> player.y;
    	const int	x = data -> player.x;
    	bresenham_line(data -> mlx, x * BLOC_SIZE,
    								y * BLOC_SIZE,
    								(x + cos(data -> player.rotation_angle) * 5) * BLOC_SIZE,
    								(y + sin(data -> player.rotation_angle) * 5) * BLOC_SIZE);
    }
    
    void	draw_bloc(t_mlx mlx, const int y, const int x, const int color)
    {
    	for (int h = 0; h < BLOC_SIZE; h++)
    		for (int w = 0; w < BLOC_SIZE; w++)
    			mlx_put_pixel(mlx, w + (x * BLOC_SIZE), h + (y * BLOC_SIZE), color);
    }
    
    void	draw_minimap(t_data *data)
    {
    	static const int	colors[2] = {0xFFF, 0x000};
    	const int			height = data -> map.height;
    	const int			width = data -> map.width;
    	char				**map;
    
    	map = data -> map.map;
    	data -> mlx.img = data -> img_map;
    	data -> mlx.addr = data -> map_addr;
    	data -> mlx.index = MLX_IMG_MINIMAP;
    
    	data -> player.rotation_angle += data -> player.view_direction * ROTATION_SPEED;
    	double moveStep = data -> player.walk_direction * MOVE_SPEED;
    	data -> player.x = data -> player.x + cos(data -> player.rotation_angle) * moveStep;
    	data -> player.y = data -> player.y + sin(data -> player.rotation_angle) * moveStep;
    	for (int y = 0; y < height; y++)
    		for (int x = 0; map[y][x]; x++)
    				draw_bloc(data -> mlx, y, x, colors[map[y][x] == WALL]);
    	draw_bloc(data -> mlx, data -> player.y, data -> player.x, 0xF4FF0F);
    	draw_ray(data);
    	mlx_put_image_to_window(data -> mlx_ptr, data -> win_ptr, data -> mlx.img,
    							(WIDTH / 2) - ((data -> map.width * BLOC_SIZE) / 2),
    							(HEIGHT / 4) - ((data -> map.height *  BLOC_SIZE) / 2));
    }
    
    void	draw_game(t_data *data)
    {
    	const int	mid = HEIGHT / 2;
    	int			*colors;
    	int			color;
    
    	colors = (int [2]){set_rgb(data -> map.color_ceil), set_rgb(data -> map.color_floor)};
    	data -> mlx.img = data -> img;
    	data -> mlx.addr = data -> addr;
    	data -> mlx.index = MLX_IMG_MAP;
    	for (int y = 0; y < HEIGHT; y++)
    		for (int x = 0; x < WIDTH; x++)
    			mlx_put_pixel(data -> mlx, x, y, colors[y >= mid]);
    	mlx_put_image_to_window(data -> mlx_ptr, data -> win_ptr, data -> mlx.img, 0, 0);
    }
    

    ET l'algo de Bresenham pour dessiner une droite

    void bresenham_line(t_mlx mlx, int x0, int y0, int x1, int y1)
    {
        int	dx;
        int	sx;
        int	dy;
        int	sy;
        int	err;
        int	e2;
    	
    	dx = abs(x1 - x0);
    	sx = x0 < x1 ? 1 : -1;
    	dy = -abs(y1 - y0);
    	sy = y0 < y1 ? 1 : -1;
    	err = dx + dy;
    	while (1)
    	{
    		mlx_put_pixel(mlx, x0, y0, 0xF14457);    
    		if (x0 == x1 && y0 == y1) 
    			break;
    		e2 = 2 * err;
    		if (e2 >= dy) 
    		{
    			err += dy;
    			x0 += sx;
    		}
    		if (e2 <= dx) 
    		{
    			err += dx;
    			y0 += sy;
    		}
    	}
    }
    


    Si qqn peut m'aider svp

    • Partager sur Facebook
    • Partager sur Twitter
      10 mars 2023 à 17:54:18

      • Bonjour,

        Lorsque vous changez l'angle de vue avec les touches gauche et droite, vous modifiez la variable data->player.view_direction. Cependant, vous ne mettez pas à jour la variable data->player.rotation_angle, qui est utilisée pour calculer les coordonnées du rayon de chaque colonne lors du lancement du raycasting. Assurez-vous que data->player.rotation_angle est correctement mis à jour lorsque vous modifiez data->player.view_direction.

      • Lorsque vous avancez en diagonale, il est normal que le mouvement ne soit pas fluide, car vous ne déplacez pas le joueur d'une distance constante à chaque fois. Si vous voulez un mouvement fluide en diagonale, vous devez diviser le déplacement en deux mouvements séparés : un mouvement horizontal suivi d'un mouvement vertical (ou vice versa). Par exemple, si le joueur doit avancer d'une distance de 1 à la fois, vous pouvez diviser le mouvement en un déplacement horizontal de 0,7 (1/sqrt(2)) suivi d'un déplacement vertical de 0,7.

      • Assurez-vous également que vous calculez correctement les coordonnées du joueur et du rayon en fonction de l'angle de vue. Si vous avez des problèmes avec des valeurs flottantes, il est possible que le problème soit dû à des erreurs d'arrondi. Essayez d'utiliser des fonctions telles que round() ou floor() pour arrondir les valeurs à des entiers si nécessaire.

      • Partager sur Facebook
      • Partager sur Twitter

      Hello, World !

      Aide concernant angle de vue, jeu 2d-3d

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown