Java Applet

Click on the image and use the keypad.

Controls: Use The Keypad
      Forward	  
         8
         |
Left 4 -   - 6 Right
         |
         2
       Back
	Up
	7
	
	|
	
	1
	Down

   	      Looking Down
		   9
	
	  	   |
	
		   3
   	       Looking Up



The source code is very small

import java.applet.Applet;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.awt.image.BufferedImage;
import java.awt.image.*;
import java.lang.InterruptedException;

import java.net.URL;
import java.net.URLClassLoader;

public class voxelspace extends Applet implements KeyListener {

    static int WIDTH = 512;
    static int HEIGHT = 256;
    static int DEPTH = 400;
    byte[] height;
    byte[] colorindex;
    double xp, yp;
    int hp, vp;
    double angle;
    int[] paletter;
    int[] paletteg;
    int[] paletteb;
    BufferedImage bimage;
    WritableRaster raster;
    byte[] image;

    public void keyReleased(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        char c = e.getKeyChar();
        //System.out.println(c);
        if (c == '4') {
            angle += 0.1;
        }
        if (c == '6') {
            angle -= 0.1;
        }
        if (c == '8') {
            //yp--;
            xp -= 2. * Math.sin(angle);
            yp -= 2. * Math.cos(angle);
        }
        if (c == '2') {
            xp += 2. * Math.sin(angle);
            yp += 2. * Math.cos(angle);

//                yp++;
        }
        if (c == '7') {
            hp += 2;
        }
        if (c == '1') {
            hp -= 2;
        }

        if (c == '9') {
            vp += 2;
        }
        if (c == '3') {
            vp -= 2;
        }

        repaint();


    }

    public void keyTyped(KeyEvent e) {
    }

    public void init() {
        
        bimage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        raster = bimage.getRaster();

        height = new byte[0x100000];
        colorindex = new byte[0x100000];
        xp = 512;
        yp = 800;
        hp = -50;
        vp = -100;

        image = new byte[WIDTH * HEIGHT];

        byte[] palette = new byte[256 * 3];
        paletter = new int[256];
        paletteg = new int[256];
        paletteb = new int[256];
        for (int k = 0; k < 256; k++) {
            paletter[k] = k;
            paletteg[k] = k;
            paletteb[k] = k;
        }

        File file = null;

        try {
            InputStream file_input = this.getClass().getResourceAsStream("rgb.dat");
            BufferedInputStream bfile_input = new BufferedInputStream(file_input);             
            
            
            bfile_input.read(palette);

            for (int k = 0; k < 256; k++) {
                paletter[k] = (palette[k * 3 + 0] & 0xFF) * 4;
                paletteg[k] = (palette[k * 3 + 1] & 0xFF) * 4;
                paletteb[k] = (palette[k * 3 + 2] & 0xFF) * 4;
            }

        } catch (IOException e) {
            return;
        }

        try {
            InputStream file_input = this.getClass().getResourceAsStream("heightmap.dat");
            BufferedInputStream bfile_input = new BufferedInputStream(file_input);             

            bfile_input.read(height);

        } catch (IOException e) {
            return;
        }

        try {
            InputStream file_input = this.getClass().getResourceAsStream("colormap.dat");
            BufferedInputStream bfile_input = new BufferedInputStream(file_input);             

            bfile_input.read(colorindex);

        } catch (IOException e) {
            return;
        }

        
        
        addKeyListener(this);
    }

    public void start() {

    }

    public void paint(Graphics g) {
        update(g);
    }

    public void update(Graphics g) {

        File file = null;
        Image man;
        int[] color = new int[4];

        for (int i = 0; i < WIDTH * HEIGHT; i++) {
            image[i] = 0;
        }



        for (int i = 0; i < WIDTH; i++) {
            double y3d = -DEPTH;
            double x3d = (i - WIDTH / 2) * 1.5;

            double rotx = Math.cos(angle) * x3d + Math.sin(angle) * y3d;
            double roty = -Math.sin(angle) * x3d + Math.cos(angle) * y3d;

            raycast(i, xp, yp, rotx + xp, roty + yp, y3d / Math.sqrt(x3d * x3d + y3d * y3d), raster);
        }

        int[] rasterline = new int[WIDTH * 3];


        for (int k = 0; k < HEIGHT; k++) {
            for (int i = 0; i < WIDTH; i++) {
                int ci = image[i + k * WIDTH] & 0xFF;
                rasterline[i * 3 + 0] = paletter[ci];
                rasterline[i * 3 + 1] = paletteg[ci];
                rasterline[i * 3 + 2] = paletteb[ci];
            }

            raster.setPixels(0, k, WIDTH, 1, rasterline);
        }

        g.drawImage(bimage, 0, 0, this);

    }

    public void raycast(int line, double x1, double y1, double x2, double y2, double d, WritableRaster raster) {
        int[] color = new int[4];

        double dx = x2 - x1;
        double dy = y2 - y1;

        double r = Math.sqrt(dx * dx + dy * dy);
        dx = dx / r;
        dy = dy / r;

        color[0] = 0;
        color[1] = 0;
        color[2] = 255;


        int ymin = 256;
        for (int i = 0; i < r - 20; i++) {
            color[0] = 255;
            color[1] = 255;
            color[2] = 255;

            //raster.setPixel((int)x2/2, (int)y2/2, color);
            x1 += dx;
            y1 += dy;

            int h = height[((int) y1 & 1023) * 1024 + ((int) x1 & 1023)];
            h = 256 - h;
            byte ci = colorindex[((int) y1 & 1023) * 1024 + ((int) x1 & 1023)];

            color[0] = paletter[ci & 0xFF];
            color[1] = paletteg[ci & 0xFF];
            color[2] = paletteb[ci & 0xFF];

            h = h - 128 + hp;
            //double y3 = yp-y1;
            double y3 = (double) i * Math.abs(d);
            double z3 = h / y3 * 100 - vp;

            if (z3 < 0) {
                z3 = 0;
            }
            if (z3 < HEIGHT - 1) {
                int offset = (int) z3 * WIDTH + line;
                for (int k = (int) z3; k < ymin; k++) {
                    image[offset] = ci;
                    offset += WIDTH;
                }
            }
            if (ymin > z3) {
                ymin = (int) z3;
            }
        }






    }
}