Newer
Older
EPQ-3D-renderer / src / Player.java
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;

public class Player {

    // image that represents the player's position on the board
    private BufferedImage image;
    // current position of the player on the board grid
    public Matrix camMatrix;
    public double FOV = 100;
    protected double Fpdis;
    private Point3D position = new Point3D(-30,0,0);
    private Point3D rotation = new Point3D(0,Math.PI / 2, 0);
    private Point3D direction = new Point3D(0,0,0);
    public Vector3D viewVector = new Vector3D(0,0,0);
    public double mouseSensitivity = 0.005; // radians per pixel
    // called when the player is initialised
    public Player() {
        Fpdis = Math.tanh(Math.toRadians(FOV)/2d);
    }

    // unused because the player should not be drawn
    // I'm leaving it in as a hint to buffered Images
    public void draw(Graphics g, ImageObserver observer) {
        int width = 100;
        int height = 100;

        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );

        for ( int py = 0; py < height; py++ ) {
            for ( int px = 0; px < width; px++ ) {
                // Set the pixel colour of the image n.b. x = cc, y = rc
                img.setRGB(px, py, Color.BLACK.getRGB() );
            }
        }
        g.drawImage(img, 0, 0, observer);
    }

    public void keyPressed(int key) {
        if (key == KeyEvent.VK_W && direction.x < 1) {
            direction.x += 1;
        } else if (key == KeyEvent.VK_S && -direction.x < 1) {
            direction.x += -1;
        } else if (key == KeyEvent.VK_D && direction.y < 1) {
            direction.y += 1;
        } else if (key == KeyEvent.VK_A && -direction.y < 1) {
            direction.y += -1;
        } else if (key == KeyEvent.VK_SPACE && direction.z < 1) {
            direction.z += 1;
        } else if (key == KeyEvent.VK_SHIFT && -direction.z < 1) {
            direction.z += -1;
        }
    }
    public void keyReleased(int key){
        if (key == KeyEvent.VK_W && direction.x > -1) {
            direction.x -= 1;
        } else if (key == KeyEvent.VK_S && -direction.x > -1) {
            direction.x -= -1;
        } else if (key == KeyEvent.VK_D && direction.y > -1) {
            direction.y -= 1;
        } else if (key == KeyEvent.VK_A && -direction.y > -1) {
            direction.y -= -1;
        } else if (key == KeyEvent.VK_SPACE && direction.z > -1) {
            direction.z -= 1;
        } else if (key == KeyEvent.VK_SHIFT && -direction.z > -1) {
            direction.z -= -1;
        }
    }
    public void tick(Point2D mouseRel) {
        // gets called once every tick, before the repainting process happens.
        // change rotation depending on mouse movement
        rotation.z += mouseRel.x * mouseSensitivity;
        // force z rotation to wrap around
        if(rotation.z<-Math.PI){
            rotation.z = Math.PI;
        } else if(rotation.z>Math.PI){
            rotation.z = -Math.PI;
        }
        rotation.y += mouseRel.y * mouseSensitivity;
        // max out y rotation at 0 and 90 degrees
        if(rotation.y < 0){
            rotation.y = 0;
        } else if(rotation.y > Math.PI){
            rotation.y = Math.PI;
        }
        // calculate direction vector to translate position by
        Matrix zMat = new Matrix(3, 3);
        zMat.setItems(new double[][]{
                {Math.cos(rotation.z),  Math.sin(rotation.z), 0},
                {-Math.sin(rotation.z), Math.cos(rotation.z), 0},
                {0,                      0,                     1}}
        );
        Matrix yMat = new Matrix(3, 3);
        yMat.setItems(new double[][]{
                {Math.cos(rotation.y), 0, -Math.sin(rotation.y)},
                {0,                    1, 0                    },
                {Math.sin(rotation.y), 0, Math.cos(rotation.y) }}
        );
        Matrix xMat = new Matrix(3, 3);
        xMat.setItems(new double[][]{
                {1, 0,                    0                   },
                {0, Math.cos(rotation.x), Math.sin(rotation.x)},
                {0, -Math.sin(rotation.x), Math.cos(rotation.x)}}
        );
        // calculate inverse Z mat for player movement
        Matrix izMat = new Matrix(3, 3);
        izMat.setItems(new double[][]{
                {Math.cos(-rotation.z),  Math.sin(-rotation.z), 0},
                {-Math.sin(-rotation.z), Math.cos(-rotation.z), 0},
                {0,                      0,                     1}}
        );
        // apply izMat to direction vector
        try {
            Point3D dirvec = new Point3D(0,0,0);
            izMat.multiplyPoint3to(direction, dirvec);
            position.translate(dirvec);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        Matrix traMat = new Matrix(4, 3);
        traMat.setItems(new double[][]
                {{1, 0, 0, -position.x},
                 {0, 1, 0, -position.y},
                 {0, 0, 1, -position.z}}
        );
        // multiply out camera matrix for rotation
        camMatrix = xMat.multiply(yMat).multiply(zMat);
        // calculate view vector
        /*Point3D viewPoint = new Point3D(0,0,0);
        camMatrix.multiplyPoint3to(new Point3D(0,0,1), viewPoint);
        viewVector.x = viewPoint.x;viewVector.y=viewPoint.y;viewVector.z=viewPoint.z;*/

        // add translation to camMatrix
        camMatrix = camMatrix.multiply(traMat);
    }

    // returnValue Functions
    public Point3D getPos() {
        return position;
    }
    public Point3D getRot() {
        return rotation;
    }

}