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 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 camMatrix = xMat.multiply(yMat).multiply(zMat).multiply(traMat); } // returnValue Functions public Point3D getPos() { return position; } public Point3D getRot() { return rotation; } }