Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package me.jtjj222.raycasting.Rendering;
- import java.awt.image.BufferedImage;
- import java.awt.image.DataBufferInt;
- import me.jtjj222.raycasting.World;
- import me.jtjj222.raycasting.entities.Entity;
- public class Renderer {
- int[] pixelData;
- private BufferedImage backBuffer;
- int width,height;
- public static final int MAX_WALL_CHECKS = 10, DIST_TO_PROJECTION_PLANE = 3;
- int[] zBuffer = new int[width]; //store the length of walls
- public Renderer(int width, int height) {
- this.width = width;
- this.height = height;
- backBuffer = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
- pixelData = ((DataBufferInt) backBuffer.getRaster().getDataBuffer()).getData();
- }
- public final BufferedImage render(World world) {
- drawFloor(world);
- drawWalls(world);
- return backBuffer;
- }
- private void drawWalls(World world) {
- double angleBetweenCollumns = (double)world.player.FOV/(double)width;
- double playerX = world.player.posX, playerZ = world.player.posZ;
- int tileX = (int) playerX, tileZ = (int) playerZ;
- for (int collumn = -width/2; collumn < width/2; collumn++) { //0 is at the center of the screen
- double worldCollumnAngle = Entity.getAngleInRange(collumn * angleBetweenCollumns + world.player.direction);
- double hRayPosX=0, hRayPosZ=0, nextHorizontalIntersectionXDist=0, nextHorizontalIntersectionZDist=0;
- double vRayPosX=0, vRayPosZ=0, nextVerticalIntersectionXDist=0, nextVerticalIntersectionZDist=0;
- double firstHorizontalIntersectionZdist = 0, firsthorizontalIntersectionXdist = 0, firstVerticalIntersectionXdist = 0, firstVerticalIntersectionZdist = 0; //changes if the ray is up or down
- double triangleAngle = 0;
- if (worldCollumnAngle < 360 && worldCollumnAngle >= 0) {
- if (worldCollumnAngle < 90)
- triangleAngle = worldCollumnAngle;
- else if (worldCollumnAngle < 180)
- triangleAngle = 180 - worldCollumnAngle;
- else if (worldCollumnAngle < 270)
- triangleAngle = 270 - worldCollumnAngle;
- else if (worldCollumnAngle < 360)
- triangleAngle = 360 - worldCollumnAngle;
- else System.out.println("render error");
- //facing left
- if ((worldCollumnAngle < 90 && worldCollumnAngle > 0) || (worldCollumnAngle < 360 && worldCollumnAngle > 270)) {
- vRayPosX = tileX + 1;
- nextVerticalIntersectionXDist = 1;
- firstVerticalIntersectionXdist = vRayPosX - playerX;
- }
- //facing right
- else {
- vRayPosX = tileX;
- nextVerticalIntersectionXDist = -1;
- firstVerticalIntersectionXdist = playerX - vRayPosX;
- }
- //facing up
- if ((worldCollumnAngle < 180 && worldCollumnAngle > 0)) {
- hRayPosZ = tileZ + 1;
- nextHorizontalIntersectionZDist = 1;
- firstHorizontalIntersectionZdist = hRayPosZ - playerZ;
- }
- //facing down
- else {
- hRayPosZ = tileZ;
- nextHorizontalIntersectionZDist = -1;
- firstHorizontalIntersectionZdist = playerZ - hRayPosZ;
- }
- firsthorizontalIntersectionXdist = firstHorizontalIntersectionZdist /(Math.tan(Math.toDegrees(triangleAngle)));
- nextHorizontalIntersectionXDist = nextHorizontalIntersectionZDist /(Math.tan(Math.toDegrees(triangleAngle)));
- firstVerticalIntersectionZdist = firstVerticalIntersectionXdist * Math.tan(Math.toDegrees(triangleAngle));
- nextVerticalIntersectionZDist = nextVerticalIntersectionXDist * Math.tan(Math.toDegrees(triangleAngle));
- //facing left
- if ((worldCollumnAngle < 90 && worldCollumnAngle > 0) || (worldCollumnAngle < 360 && worldCollumnAngle > 270)) {
- vRayPosZ = firstVerticalIntersectionZdist + playerZ;
- }
- else {
- vRayPosZ = playerZ - firstVerticalIntersectionZdist;
- }
- //facing up
- if ((worldCollumnAngle < 180 && worldCollumnAngle > 0)) {
- hRayPosX = firsthorizontalIntersectionXdist + playerX;
- }
- else {
- hRayPosX = playerX - firsthorizontalIntersectionXdist;
- }
- //now we know the initial intersection that the ray makes, and the distance to the next intersection
- }
- else System.out.println("Render error");
- double hIntDistance = 999999, vIntDistance = 999999; //make sure if one of these isn't defined, it will not be used
- //go along the ray to find horizontal intersections
- if (worldCollumnAngle != 0 && worldCollumnAngle != 180) { //those cases have no horizontal intersections
- int i = 0;
- while (i < MAX_WALL_CHECKS) {
- if (world.isWall(hRayPosX, hRayPosZ)) {
- //found horizontal intersection
- hIntDistance = distance(hRayPosX,hRayPosZ,playerX,playerZ);
- break;
- }
- hRayPosX += nextHorizontalIntersectionXDist;
- hRayPosZ += nextHorizontalIntersectionZDist;
- if (hRayPosX < 0 || hRayPosZ > world.width) { //out of the world (should never happen)
- vIntDistance = 999999999; //make sure that this distance is never used (always larger)
- break;
- }
- i++;
- }
- }
- //find vertical intersections
- if (worldCollumnAngle != 90 && worldCollumnAngle != 270) {
- int i = 0;
- while (i < MAX_WALL_CHECKS) {
- if (world.isWall(vRayPosX, vRayPosZ)) {
- vIntDistance = distance(vRayPosX,vRayPosZ,playerX,playerZ);
- break;
- }
- vRayPosX += nextVerticalIntersectionXDist;
- vRayPosZ += nextVerticalIntersectionZDist;
- if (vRayPosX < 0 || vRayPosZ > world.height) {
- vIntDistance = 999999999; //make sure that this distance is never used (allways larger)
- break;
- }
- i++;
- }
- }
- double wallDist = 0;
- if (hIntDistance > vIntDistance) wallDist = vIntDistance;
- else wallDist = hIntDistance;
- double trueWallDist = wallDist ;//* Math.cos(triangleAngle);
- int wallheight = 200;
- int projectedWallHeight = (int) (wallheight*DIST_TO_PROJECTION_PLANE/trueWallDist);
- int startX = collumn+width/2;
- int startZ = height/2 - projectedWallHeight/2;
- int endX = startX + 1;
- int endZ = height/2 + projectedWallHeight/2;
- drawRect(startX,startZ,endX,endZ,0xFFFFFF);
- }
- }
- private void drawRect(int x0, int y0, int x1, int y1, int col) {
- for (int y = y0; y < y1; y++) {
- for (int x = x0; x < x1; x++) {
- int offset = x + y * width;
- if (offset < pixelData.length && offset > 0) pixelData[offset] = col;
- }
- }
- }
- private double distance (double ax, double az, double bx, double bz) {
- return Math.sqrt((ax-bx)*(ax-bx) + (az-bz)*(az-bz) );
- }
- private void drawFloor(World world) {
- drawCeiling(world);
- }
- private void drawCeiling(World world) {
- drawRect(0,0,width,height,0x555555);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement