Jump to content
Fórum Script Brasil
  • 0

viniBiavatti

Question

Olá Pessoal do Fórum ScriptBrasil!



RayCasting, uma forma de gerar um ambiente 3d a partir de uma matriz 2d. Gostaria de saber se alguém do fórum tem algum tipo de tutorial em português, ou algum mina algoritmo bem BÁSICO sobre o assunto. Estou muito interessado porém tenho certas dúvidas que não acho a resposta na internet. As explicações são um pouco complicadas más estou procurando muito a respeito. Alguns requisitos que estou atrás é o conhecimento da trigonometria que é essencial para o desenvolvimento e lógica de rayCasting. Já estou me adaptando e tive algumas lógicas bem interessantes para um bom início.



O que peço para vocês é que me mandem link de algum tutorial básico, algum exemplo como um programa java com o source disponível. Estou apenas atrás de conhecimento até conseguir desenvolver meu primeiro rayCasting.



Procuro algo básico, pois o assunto trata diversas coisas como por exemplo, o "lighting" ou seja, a luminosidade de diversos pontos deste pseudo-3d. Más isto já vejo como avançado. O que quero é apenas construir uma matriz onde irei utilizar como mapa, criar um ângulo de raios para formar o campo de visão e renderizar os pontos onde estes raios entram em conflito com os pontos da matriz (paredes), e assim, criar o psudo-3d em um canvas (java).



Sobre RayCasting: Posso dizer que é uma forma de tornar um mapa em uma visão 3d, ou melhor, com aparência 3d. digamos que tenhamos uma matriz de inteiros onde servirá como mapa:

int[][] mapa = new int[][]{

{2,2,2,2,2},

{0,0,0,0,0},

{0,0,1,0,0},

{0,0,0,0,0},

{0,0,0,0,0}};



Os pontos 2 definimos como as paredes e o ponto 1, o personagem. O intuito é realizar o lançamento de raios em um certo ângulo de visão do personagem para verificar a distância de colisão da parede (2);

Simple_raycasting_with_fisheye_correctio



Quando o raio entra em colisão com a parede, é calculada a distância entre a posição do personagem com a parede. Podemos utilizar a trigonometria para calcular esta distância com o teorema de pitágoras. (hipotenusa)



Nesta imagem, percebe-se que existe algum efeito de luminosidade onde seria mais um complemento pro aprendizado. O que quero por exemplo é algo simples, como um algoritmo java tendo uma matriz, alguns métodos de calculo da distancia e etc e a renderização da matriz em um canvas. Algo básico como:

raycaster101.png



Pode ver que é bem simples para um bom começo smile.png. Veja que não tem efeitos de luminosidade e textura, apenas o chateado raycasting.

Não possui uma grid sendo "floor", teto ou chão, apenas as paredes. No caso, o cháo é apenas uma pintura verde até o centro da tela e o azul é mesma coisa.

Após o conhecimento, irei aprimorar futuramente:

raycaster201.png



Esta imagem já contém algumas sombras e etc...



Já procurei muito na internet e achei na maioria tutoriais em inglês. Aprendi algo com eles, más é um tanto complicado de entender pelo volume de código que existe, pois os tutoriais na maioria das vezes ensinam a aplicar texturar e luminosidade e etc... Já outros utilizam outras linguagens como javascript e C++ porém gostaria de tratar isto com java.



Já criei algum software para tentar entender um pouco do assunto e estou disponibilizando os métodos principais dele abaixo, junto com alguns comentários. É bem básico pois não existe algum tipo de angulação para movimentação e nova leitura de pontos para formação pseudo-3d. O algoritmo apenas realiza uma varredura da matriz (mapa) e procura por uma parede (2). Ao encontrar, ele calcula a hipotenusa das cordenadas da parede até com as cordenadas do personagem. Tendo esta hipotenusa, é definido o tamanho de um retângulo no canvas. Se a distancia é grande (longe), o retângulo é pequeno. Se a distancia é pequena (perto), o retângulo é grande.



Aqui defino meus atributos e o mapa:

public class Janela extends Canvas implements Runnable{
   
    int[] pixelsFundo;
    private BufferedImage img;
    private int[][] mapa = new int[][]{ {0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},    
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
    private int jogadorX = 11;
    private int jogadorY = 11;
   
    public Janela()
    {
        this.img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
        this.pixelsFundo = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
    }

Este é o método de renderização no canvas, onde ele irá desenhas os retângulos no componente:

Os parâmetros são a largura, altura e posição x, y do retângulo gerado no método calcular:


public void render(int x, int y, int xPos, int yPos)
    {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null)
        {
            this.createBufferStrategy(2);
            bs = this.getBufferStrategy();
        }
       
        Graphics g = bs.getDrawGraphics();
        g.drawRect(xPos,yPos,x, y);
        g.dispose();
        bs.show();
    }

Este é o método de calculo. Ele que defini a distância da parede na matriz e gera um tamanho e posição para renderização dos retângulos:

public void calcular()
    {
        int poxX = 0;
        for (int i = 0; i < mapa.length; i++)
        {
            poxX = 0;
            for(int j = 0; j < mapa.length; j++)
            {
                if(mapa[i][j] == 2)
                {
                    double catetoAdj = this.jogadorX - i;
                    double catetoOp = this.jogadorY - j;
                    double hipotenusa = catetoOp / catetoAdj;
                   
                    if(hipotenusa < 0)
                    {
                        hipotenusa = hipotenusa * -1;
                    }
                    System.out.println(hipotenusa);
                    render(37, (int)(200-(hipotenusa*50)),poxX, (int)(180+((hipotenusa*50)/2)));
                }
                poxX += 37;
            }
        }
    }

Este é um exemplo de saida do programa:

2mh5v0l.jpg



Isto é básico e programei para dar início.

Pois bem gente um breve resumo:

Gostaria de um bom tutorial ou algo que possa ensinar a programar o raycasting como por exemplo, um algoritmo pronto, básico onde so tenha a renderização das paredes e a lógica do raycasting, sem essas frescuras de luminosidade, sombra, texturas, chão, teto e etc... Como mencionei, BÁSICO. Sei que o assunto é um pouco avançado mais nem tanto quanto parece, aliás, estamos lidando com pseudo-3d, um 3d de mentira wink.png. Pessoal, espero que me ajudem, sou novo aqui no fórum e desculpe se publiquei algo incorretamente. Obrigado por tudo!



Linguagem que utilizo: JAVA

Cursando: Ciências da Computação.



Curiosidades: O Ray casting foi utilizado no primeiro jogo em pseudo-3d da história, o Wolfstein 3d.

shot1.jpg

Edited by viniBiavatti
Link to comment
Share on other sites

1 answer to this question

Recommended Posts

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      152.1k
    • Total Posts
      652k
×
×
  • Create New...