Ir ao conteúdo
  • Cadastre-se

Vinicius Biavatti

Membro Júnior
  • Posts

    4
  • Cadastrado em

  • Última visita

Reputação

1
  1. Pseudo 3D Olá a todos. Falarei a respeito de algo interessante na programação, o pseudo 3D. O Pseudo 3D é um método utilizado para renderização de um ambiente com uma sensação de profundidade (eixo Z) porém o efeito é apenas ilusão. Este método de renderização era utilizado em muitos jogos antigos como por exemplo, os jogos de corrida onde a pista da corrida parecia ter uma profundidade. Existem tipos parecidos de renderização como o "Mode 7" onde a renderização já possui mais recursos como por exemplo, a Rotação. Gostaria de falar a respeito com o pessoal do forum, para pedir se alguém possui algum material explicativo ou algum tutorial onde ensine o básico sobre esta renderização. Bem bacana ter conhecimento para ver como na realidade funciona o openGL por baixo dos panos. Sei que deve existir uma lógica bem básica para isto e quero aprender, para assim, programar algo em JAVA. Gostaria também de saber se existe um nome específico para este tipo de renderização. Código: Podemos utilizar uma simples JFrame em java, criar um Thread, más a lógica para que possamos gerar este eixo Z, e movimentar as faixas geradas para dar impressão 3D é o que preciso. O assunto é um pouco complicado para ser encontrado na internet, más o que achei foi o conteúdo deste site, porém ainda sim é um tanto complexo a explicação. http://www.extentofthejam.com/pseudo/ Se puderem disponibilizar algo básico em java com esta lógica utilizada ajudará muito. Evolução: Tentei reproduzir um efeito simples em Pseudo3D da mesma forma utilizar para estes jogos antigos. Obtive o seguinte resultado: package pseudo3d; /** * * @author Vinicius */ public class Pseudo3D { public static void main(String[] args) { new Tela(); } } package pseudo3d; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.image.BufferedImage; import javax.swing.JFrame; /** * * @author Vinicius */ public class Tela extends JFrame implements Runnable, KeyListener{ //Constantes - Tamanho public static final int LARGURA = 800; public static final int ALTURA = 600; public static final int CENTRO_LARGURA = LARGURA / 2; public static final int CENTRO_ALTURA = ALTURA / 2; //Constantes - Evento public static final int PARADO = 0; public static final int CIMA = 1; public static final int BAIXO = 2; public static final int ESQUERDA = 3; public static final int DIREITA = 4; //Atributos - Imagem private BufferedImage imagem; private Graphics grafico; private Render3D render3D; //Atributos - Evento private int evento = PARADO; private int deslocamentoX = 0, deslocamentoZ = 0; /* * Construtor */ public Tela() { this.setTitle("Pseudo-3D v1.0"); this.setSize(LARGURA, ALTURA); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocationRelativeTo(null); this.addKeyListener(this); this.setVisible(true); this.imagem = new BufferedImage(LARGURA, ALTURA, BufferedImage.TYPE_INT_RGB); this.grafico = this.imagem.getGraphics(); new Thread(this).start(); } /** * Calcular fps do sistema. * <p> * <code>long tempo = System.currentTimeMillis(); </code> * <p> * <code>while(System.currentTimeMillis() - tempo < 30);</code> */ public void fps() { long tempo = System.currentTimeMillis(); while(System.currentTimeMillis() - tempo < 30); //System.out.println("fps: " + (System.currentTimeMillis() - tempo)); } /** * Verificar evento de movimentação. * Irá realizar validação de limite. */ private void evento() { switch(this.evento) { case CIMA: this.deslocamentoZ++; break; case ESQUERDA: this.deslocamentoX-= 40; break; case DIREITA: this.deslocamentoX+= 40; break; } if(deslocamentoZ > 5) { deslocamentoZ = 0; } } @[member=override] public void run() { this.render3D = new Render3D(this); while(true) { this.fps(); this.render3D.renderTeto(deslocamentoZ); this.render3D.renderPiso(deslocamentoZ); this.render3D.renderProfundidadeTeto(deslocamentoX); this.render3D.renderProfundidadePiso(deslocamentoX); this.repaint(); this.evento(); } } @[member=override] public void keyTyped(KeyEvent e) { } @[member=override] public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_UP: this.evento = CIMA; break; case KeyEvent.VK_DOWN: this.evento = BAIXO; break; case KeyEvent.VK_LEFT: this.evento = ESQUERDA; break; case KeyEvent.VK_RIGHT: this.evento = DIREITA; break; } } @[member=override] public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_UP: case KeyEvent.VK_DOWN: case KeyEvent.VK_LEFT: case KeyEvent.VK_RIGHT: this.evento = PARADO; break; } } @[member=override] public void paint(Graphics g) { g.drawImage(this.imagem, 0, 0, this); } /* * Get e Set */ public BufferedImage getImagem() { return imagem; } public void setImagem(BufferedImage imagem) { this.imagem = imagem; } public Graphics getGrafico() { return grafico; } public void setGrafico(Graphics grafico) { this.grafico = grafico; } } package pseudo3d; import java.awt.Color; /** * * @author Vinicius */ public class Render3D { //Atributos - Imagem private Tela tela; /** * Construtor da classe. Passar uma tela para que seja renderizado * as linhas bidimensionais. * @param tela */ public Render3D(Tela tela) { this.tela = tela; } /** * Renderizar Teto na tela em perpectiva. Passar como parâmetro o deslocamento. * Passar 0 como valor do parâmetro para não fornecer deslocamento. * <p> * Utilizará variável "Z" para calcular a profundidade * @param deslocamento */ public void renderTeto(int deslocamento) { int z = 2 + deslocamento; for(int i = this.tela.CENTRO_ALTURA; i >= 0; i--) { if(i == (this.tela.CENTRO_ALTURA - z)) { this.tela.getGrafico().setColor(Color.BLACK); z *= 2; } else { this.tela.getGrafico().setColor(Color.GRAY); } this.tela.getGrafico().drawLine(0, i, this.tela.LARGURA, i); } } /** * Renderizar Piso na tela em perpectiva. Passar como parâmetro o deslocamento. * Passar 0 como valor do parâmetro para não fornecer deslocamento. * <p> * Utilizará variável "Z" para calcular a profundidade * @param deslocamento */ public void renderPiso(int deslocamento) { int z = 2 + deslocamento; for(int i = this.tela.CENTRO_ALTURA; i < this.tela.ALTURA; i++) { if(i == (this.tela.CENTRO_ALTURA + z)) { this.tela.getGrafico().setColor(Color.BLACK); z *= 2; } else { this.tela.getGrafico().setColor(Color.DARK_GRAY); } this.tela.getGrafico().drawLine(0, i, this.tela.LARGURA, i); } } /** * Renderizar profundidade do Teto na tela em perpectiva. Passar como parâmetro o deslocamento. * Passar 0 como valor do parâmetro para não fornecer deslocamento. * <p> * Utilizará variável "Z" para calcular a profundidade * @param deslocamento */ public void renderProfundidadeTeto(int deslocamento) { this.tela.getGrafico().setColor(Color.BLACK); for(int i = (this.tela.ALTURA * this.tela.LARGURA) * -1; i < (this.tela.LARGURA * this.tela.ALTURA); i++) { if((i + deslocamento) % 600 == 0) { this.tela.getGrafico().drawLine(i, 0, this.tela.CENTRO_LARGURA, this.tela.CENTRO_ALTURA); } } } /** * Renderizar profundidade do Piso na tela em perpectiva. Passar como parâmetro o deslocamento. * Passar 0 como valor do parâmetro para não fornecer deslocamento. * <p> * Utilizará variável "Z" para calcular a profundidade * @param deslocamento */ public void renderProfundidadePiso(int deslocamento) { this.tela.getGrafico().setColor(Color.BLACK); for(int i = (this.tela.ALTURA * this.tela.LARGURA) * -1; i < (this.tela.LARGURA * this.tela.ALTURA); i++) { if((i + deslocamento) % 600 == 0) { this.tela.getGrafico().drawLine(i, this.tela.ALTURA, this.tela.CENTRO_LARGURA, this.tela.CENTRO_ALTURA); } } } } Obs: Já fiz uma postagem no fórum referente a técnicas de renderização em 3D utilizando Ray Casting, e o que encontrei na internet foi um tutorial super complexo. Procurei até demais para encontrar uma simples classe java que me ajudasse a aprender, com um código básico, simples e muito melhor que o código complexo. Estou aqui para solicitar algo básico e se puderem ajudar estarei grato. Demonstração: Este app foi desenvolvido por um gringo. Feito em javascript, e por possuir muitos recursos, não ficou bom para ter uma noção e sim, bom para se perder no código. http://codeincomplete.com/projects/racer/v1.straight.html
  2. Olá Galera! Finalmente desenvolvi meu primeiro RAYCASTING! Procurei bastante na internet, corri atrás e deu certo. Fiz algo bem básico más para mim já é interessante para compartilhar com vocês: Irei disponibilizar o código e a referência de onde consegui pegar um código para mim se basear. Agradeço ao Patrick Kelly! Obrigado irmão! Thanks brother Sucessfully por you Código: ** Comentei ele bastante para ficar bem fácil de entender, logo disponibilizarei ele sem os comentários pois olhando com essa montueira de comentários parece ser um código phodastico! package raycasting;import java.awt.Color;import java.awt.Graphics;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.awt.image.BufferedImage;import javax.swing.JFrame;public class RayCasting extends JFrame implements Runnable, KeyListener{ //Constantes - Tamanho da tela public static final int WIDTH = 800; public static final int HEIGHT = 600; //Constantes - Centro da tela public static final int CENTER_WIDTH = WIDTH / 2; public static final int CENTER_HEIGHT = HEIGHT / 2; //Constantes - Angulos public static final int ANGULO720 = 9600; public static final int ANGULO360 = 4800; public static final int ANGULO180 = 2400; public static final int ANGULO90 = 1200; public static final int ANGULO60 = 800; //Atribuido para que o FOV (Angulo de visão do personagem) seja um angulo de 60° public static final int ANGULO30 = 400; public static final int ANGULO15 = 200; public static final int ANGULO6 = 80; //Constantes - Movimentação (EVENTO) public static final int CIMA = 1; public static final int BAIXO = 2; public static final int ESQUERDA = 3; public static final int DIREITA = 4; public static final int PARADO = -1; //Evento do personagem (Parado = -1, andando para frente = 1...) private int personagemEvento = PARADO; //Gráficos e Imagem private BufferedImage imagem; private Graphics grafico; //Mapa private int[][] mapa; //Array de cores para as paredes private Color[] cores = new Color[]{Color.GREEN, Color.RED, Color.BLUE, Color.ORANGE, Color.WHITE, Color.YELLOW, Color.BLACK}; /* * Construtor */ public RayCasting() { //Iniciando atributos de imagem e gráfico com o tamanho da tela onde será renderizado this.imagem = new BufferedImage(this.WIDTH, this.HEIGHT, BufferedImage.TYPE_INT_RGB); this.grafico = imagem.getGraphics(); //Criando mapa - Vista de cima (15 x 15) this.mapa = new int[][]{{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,2,2,2,2,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,2,0,0,0,5,5,5,0,1}, {1,0,0,2,2,0,2,0,0,0,5,0,0,0,1}, {1,0,0,0,0,0,2,0,0,0,5,0,0,0,1}, {1,0,2,2,2,2,2,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,1,1,1,0,0,0,1}, {1,0,0,0,0,0,0,0,1,1,1,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,6,0,0,0,0,0,0,0,0,4,0,1}, {1,6,0,6,0,0,0,0,4,4,4,4,4,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,6,0,6,0,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} }; //Criando Janela a partir desta classe ("extends JFrame") this.setTitle("RayCasting JAVA"); this.setSize(this.WIDTH,this.HEIGHT); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); //Adicionar integração com os botões ("implements KeyListener") this.addKeyListener(this); //Iniciando Thread para rodar método run() new Thread(this).start(); } /* * Método conversor de Angulo para Radiano (Para que se possa trabalhar em radiano (Seno, Cosseno...)) */ public double converterAnguloRadiano(int angulo) { //Fórmula para conversão double radiano = ((double)angulo * (Math.PI / this.ANGULO180)); return radiano; } /* * Métodos run "Thread" */ @[member="override"] public void run() { //Criar posição inicial do personagem (posição X, posição Y e angulo do personagem "Angulo de visão") double posicaoPersonagemX = 8; double posicaoPersonagemY = 8; int anguloPersonagem = 0; //Angulo para lançamentos dos raios no devido angulo de visão do personagem. Definido no sistema de 60° o FOV. //60° seria o centro da visão portando, para começar do lado esquerdo para o lado direito, é feita a diminuição de 30° //Ao diminuir 30°, e passar pelo lançamento de raios conforme tamanho definido para 800 (this.WIDTH), é aumentado //os graus suficientes para equivaler 60° pois 800 equivale a 60° // -30° 60° +30° // \______|______/ // \ | / // \ | / // \ | / // \ | / // \ | / // \|/ int anguloRaio; //=================================// //Loop para funcionamento da Thread// //=================================// while(true) { //Decrementar angulo para realizar o lançamento dos raios (-30° oara após o lançamento de 800 raios, totalizar em 60°) anguloRaio = anguloPersonagem - this.ANGULO30; //=================================================================================================// //Iniciar lançamento de raios para buscar uma parede no mapa, calcular sua distância e renderiza-la// //=================================================================================================// for(int raio = 0; raio < this.ANGULO60; raio++) { //Posição inicial dos raios (Obviamente é a posição do personagem) double posicaoRaioX = posicaoPersonagemX; double posicaoRaioY = posicaoPersonagemY; //Etapa para descobrir valor de X e assim efetuar a leitura do caminho do raio lançado, dentro do mapa. //Irá ser criado uma parte de um círculo (60°) para ser jogado os 800 raios double etapaX = Math.cos(this.converterAnguloRadiano(anguloRaio)) / 8; double etapaY = Math.sin(this.converterAnguloRadiano(anguloRaio)) / 8; //====================================================================================================================\\ //Iniciar variáveis para correr no loop. Parede para quando encontrar uma parede e distância para calcular a distancia\\ //até encontrar parede \\ //====================================================================================================================\\ int parede = 0; int distancia = 1; //Atribuir um para que seja no mínimo 1 a distância do personagem até a parede. //Loop para procurar uma parede no mapa e calcular uma distância até a parede. while(parede == 0) { //Realizar um traçamento do raio na incrementação das etapas calculadas no angulo posicaoRaioX += etapaX; posicaoRaioY += etapaY; //Descobrir posição no mapa. Se a posição na matriz for 1 então encontrou uma parede e sai do loop parede = this.mapa[(int)posicaoRaioX][(int)posicaoRaioY]; //Aumentar distância distancia = distancia + 1; //System.out.println("posicaoRaioX " + posicaoRaioX + "posicaoRaioY " + posicaoRaioY + " parede " + parede + " distancia " + distancia); } //Transformar distância em um bom redimensionamento para a altura da parede int alturaParede = (int)(1024 / distancia); //=====================================================// //Desenhar LINHAS para representar o céu, parede e chão// //=====================================================// //Céu //Atribuir cor azul this.grafico.setColor(Color.CYAN); this.grafico.drawLine(raio, 0, raio, CENTER_HEIGHT - alturaParede); //Parede //Atribuir cor dependendo do numero encontrado no mapa this.grafico.setColor(this.cores[parede - 1]); this.grafico.drawLine(raio, CENTER_HEIGHT - alturaParede, raio, CENTER_HEIGHT + alturaParede); //Chão //Atribuir cor cinza this.grafico.setColor(Color.DARK_GRAY); this.grafico.drawLine(raio, CENTER_HEIGHT + alturaParede, raio, this.HEIGHT); //==================// //Incrementar Angulo// //==================// anguloRaio = anguloRaio + 1; } //Repintar o cenário this.repaint(); //==========================// //Movimentação do personagem// //==========================// double posicaoPersonagemAntigaX; //Para tratar colisões caso entrar em uma área do mapa que seja maior que 0, voltar double posicaoPersonagemAntigaY; //para posição antiga switch(this.personagemEvento) { case CIMA: posicaoPersonagemAntigaX = posicaoPersonagemX; //Colisão posicaoPersonagemAntigaY = posicaoPersonagemY; //Colisão //Incrementar posição para andar para frente (/ 128 para diminuir a velocidade de caminhada) posicaoPersonagemX += (Math.cos(this.converterAnguloRadiano((int)anguloPersonagem)) / 128); posicaoPersonagemY += (Math.sin(this.converterAnguloRadiano((int)anguloPersonagem)) / 128); //Verificar colisão if(this.mapa[(int)posicaoPersonagemX][(int)posicaoPersonagemY] > 0) { posicaoPersonagemX = posicaoPersonagemAntigaX; posicaoPersonagemY = posicaoPersonagemAntigaY; } break; case BAIXO: posicaoPersonagemAntigaX = posicaoPersonagemX; //Colisão posicaoPersonagemAntigaY = posicaoPersonagemY; //Colisão //Incrementar posição para andar para trás (/ 128 para diminuir a velocidade de caminhada) posicaoPersonagemX -= (Math.cos(this.converterAnguloRadiano((int)anguloPersonagem)) / 128); posicaoPersonagemY -= (Math.sin(this.converterAnguloRadiano((int)anguloPersonagem)) / 128); //Verificar Colisão if(this.mapa[(int)posicaoPersonagemX][(int)posicaoPersonagemY] > 0) { posicaoPersonagemX = posicaoPersonagemAntigaX; posicaoPersonagemY = posicaoPersonagemAntigaY; } break; case ESQUERDA: //Diminuir o angulo do personagem (/ 16 para diminuir a velocidade de virada) anguloPersonagem -= (this.ANGULO6 / 16); break; case DIREITA: //Aumentar o angulo do personagem (/ 16 para diminuir a velocidade de virada) anguloPersonagem += (this.ANGULO6 / 16); break; } } } /* * Método para pintura da imagem (BufferedImage). "Subtituir método" */ @[member="override"] public void paint(Graphics g) { //Desenha imagem nas coordenadas x = 0, y = 0, nesta tela g.drawImage(this.imagem, 0, 0, this); } /* * Métodos para movimentação */ @[member="override"] public void keyTyped(KeyEvent e) { } @[member="override"] public void keyPressed(KeyEvent e) { //Condições para achar qual tecla foi clicada switch(e.getKeyCode()) { case KeyEvent.VK_UP: this.personagemEvento = CIMA; break; case KeyEvent.VK_DOWN: this.personagemEvento = BAIXO; break; case KeyEvent.VK_LEFT: this.personagemEvento = ESQUERDA; break; case KeyEvent.VK_RIGHT: this.personagemEvento = DIREITA; break; } } @[member="override"] public void keyReleased(KeyEvent e) { //Condições para achar qual tecla foi clicada switch(e.getKeyCode()) { case KeyEvent.VK_UP: this.personagemEvento = PARADO; break; case KeyEvent.VK_DOWN: this.personagemEvento = PARADO; break; case KeyEvent.VK_LEFT: this.personagemEvento = PARADO; break; case KeyEvent.VK_RIGHT: this.personagemEvento = PARADO; break; } } /* * Main */ public static void main(String[] args) { new RayCasting(); }} Imagens: Em anexo o .jar com o codigo! Referencia de aprendizado! Mais uma vez muito obrigado! http://www.iol.ie/~kellyswd/Patrick/raycaster/ RayCasting.rar
  3. Muito Obrigado. Irei tentar encontrar algo para aprendizado. Más, se alguém puder postar um mini-algoritmo como exemplo aqui no tópico ajudará bastante. Fico no aguardo de mais comentários
  4. Olá Pessoal do Clube do Hardware! 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); 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: Pode ver que é bem simples para um bom começo . 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: 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[][]{ {2,2,2,2,2,2,2,2,2,2,2,0,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,0,0,0,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,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,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,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,0,0,0,0,0,0,0,0,0,0,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, 300, 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 xPos, int yPos,int x, int y) { 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() { //Posição x da parede int posicaoX = 0; int tamanhoParede = 35; int alturaParede = 250; //Varrer Mapa for(int y = 0; y < mapa.length; y++) { //PosicaoX = 0 para colocar p´roxima coluna de paredes posicaoX = 0; for(int x = 0; x < mapa.length; x++) { //Verificar se é parede if(mapa[y][x] == 2) { //Calcular Hipotenusa double catetoOposto = this.jogadorY - y; double catetoAdjacente = this.jogadorX - x; double hipotenusa = (catetoOposto * catetoOposto) + (catetoAdjacente * catetoAdjacente); //Deixar Hipotenusa sempre positivo if(hipotenusa < 0) { hipotenusa = hipotenusa * -1; } //Diminuir valor da hipotenusa hipotenusa = hipotenusa * 0.18; //Imprimir Hipotenusa System.out.println("Hipotenusa: " + hipotenusa); //Definir altura da parede int alturaParedeView = (int)(alturaParede - (hipotenusa*5)); //Definir posicao Y para colocar parede int posicaoY = (int)(300 - alturaParedeView/2); //Desenhar Paredes this.render(posicaoX, posicaoY, tamanhoParede, alturaParedeView); } //Incrementar posicao conforme tamanho do retangulo e tamanho da tela //800 / 23 ~= 35 posicaoX += tamanhoParede; } } } Este é um exemplo de saida do programa: Isto é básico e programei para dar início. Anexei o código todo a este tópico se quiserem dar uma olhada. 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 . 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. RayCasting.rar

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...