There’s a lot of it, so I have put comments in.
Code:
// To control: drag your mouse to rotate, WASD/Shift/Space to navigate
// In output: time between frames, time during draw()
import java.io.*;
String scene = "test"; // unused
final static int WINDOW_WIDTH = 1440;
final static int WINDOW_HEIGHT = 810;
float rotX = 0;
float rotY = 0;
float rotZ = 0;
float camX = 0;
float camY = 0;
float camZ = 0;
int drawX = 0;
int drawY = 0;
int drawZ = 0;
int bpf = 300; // blocks per frame, laggy at high numbers
double realbpf = 300.0; // I used to have code that changes the bpf based on framerate
Boolean finishedDraw = false;
Boolean[] moveList = {false, false, false, false, false, false};
PImage grassBlock = new PImage();
HashMap<String, Integer> data = new HashMap<String, Integer>(); // stores the blocks
int tm = 0; // timer
void draw3dImage(PImage all, float size) {
PImage top = all.get(0, 0, 16, 16);
PImage s1 = all.get(16, 0, 16, 16);
PImage s2 = all.get(32, 0, 16, 16);
PImage s3 = all.get(48, 0, 16, 16);
PImage s4 = all.get(64, 0, 16, 16);
PImage bottom = all.get(80, 0, 16, 16);
if (rotX <= 1*Math.PI/6 || rotX >= 5*Math.PI/6) { // these if statements prune the non-visible sides (glitchy on bottom)
beginShape();
texture(top);
vertex(-size, -size, size, 0, 0);
vertex(size, -size, size, 16, 0);
vertex(size, -size, -size, 16, 16);
vertex(-size, -size, -size, 0, 16);
endShape(CLOSE);
}
if (rotY >= 3*Math.PI/2 || rotY <= Math.PI/2) {
beginShape();
texture(s1);
vertex(-size, -size, size, 0, 0);
vertex(size, -size, size, 16, 0);
vertex(size, size, size, 16, 16);
vertex(-size, size, size, 0, 16);
endShape(CLOSE);
}
if (rotY >= Math.PI) {
beginShape();
texture(s2);
vertex(size, -size, size, 0, 0);
vertex(size, -size, -size, 16, 0);
vertex(size, size, -size, 16, 16);
vertex(size, size, size, 0, 16);
endShape(CLOSE);
}
if (rotY <= 3*Math.PI/2 && rotY >= Math.PI/2) {
beginShape();
texture(s3);
vertex(size, -size, -size, 0, 0);
vertex(-size, -size, -size, 16, 0);
vertex(-size, size, -size, 16, 16);
vertex(size, size, -size, 0, 16);
endShape(CLOSE);
}
if (rotY <= Math.PI) {
beginShape();
texture(s4);
vertex(-size, -size, size, 0, 0);
vertex(-size, -size, -size, 16, 0);
vertex(-size, size, -size, 16, 16);
vertex(-size, size, size, 0, 16);
endShape(CLOSE);
}
if (rotX >= 1*Math.PI/3 && rotX <= 2*Math.PI/3) {
beginShape();
texture(bottom);
vertex(-size, size, -size, 0, 0);
vertex(size, size, -size, 16, 0);
vertex(size, size, size, 16, 16);
vertex(-size, size, size, 0, 16);
endShape(CLOSE);
}
}
void setup() {
size(1440, 810, P3D);
grassBlock = loadImage("grassBlock.png"); // This is a 96x16 texture. I will post it along with the code.
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 1; j++) {
for (int k = 0; k < 16; k++) {
data.put(i+","+j+","+k, 1); //puts some data into the hashmap
}
}
}
frameRate(60);
background(255, 255, 255);
hint(DISABLE_TEXTURE_MIPMAPS);
((PGraphicsOpenGL)g).textureSampling(2); // turns off antialiasing
}
void draw() {
String timeStr = (millis()-tm-16) + "";
int m1 = millis();
rotX = (rotX % TAU + TAU) % TAU;// keeps view within certain range
rotX = rotX > Math.PI/2 && rotX <= Math.PI ? (float) Math.PI/2 : rotX;
rotX = rotX < 3*((float)Math.PI)/2 && rotX >= Math.PI ? 3*((float)Math.PI)/2 : rotX;
rotY = (rotY % TAU + TAU) % TAU;
fill(0, 0, 0);
pushMatrix();
translate(WINDOW_WIDTH/2+camX, WINDOW_HEIGHT/2, camZ); // rotation point
rotateX(rotX);
rotateY(rotY); // rotates camera
rotateZ(rotZ);
for (Boolean x : moveList) {
if (x) {
background(255, 255, 255);
finishedDraw = false;
drawX = 0;
drawY = 0;
drawZ = 0;
} // detects arrow key movement
}
bpf = (int) Math.max(Math.round(realbpf), 1);
if (moveList[0]) { // all of these move you around
camZ+=5;
}
if (moveList[1]) {
camZ-=5;
}
if (moveList[2]) {
camX+=5;
}
if (moveList[3]) {
camX-=5;
}
if (moveList[4]) {
camY-=5;
}
if (moveList[5]) {
camY+=5;
}
if (!finishedDraw) {
for (int i = 0; i < bpf; i++) { // draws the blocks
if (drawX < 16) {
if (drawY < 1) {
if (drawZ < 16) {
drawZ++;
} else {
drawZ = 0;
drawY++;
}
} else {
drawY = 0;
drawX++; // for loops without for looping
}
} else {
finishedDraw = true;
}
if (data.get(drawX+","+drawY+","+drawZ) != null) {
int blockId = data.get(drawX+","+drawY+","+drawZ);
pushMatrix();
translate(drawX*96, drawY*96+camY, drawZ*96); // draws block in specific spot
switch(blockId) {
case 0:
break;
case 1:
draw3dImage(grassBlock, 48);
break;
}
popMatrix();
}
}
}
popMatrix();
strokeWeight(5);
point(WINDOW_WIDTH/2, WINDOW_HEIGHT/2, -20); // rotation point
strokeWeight(1);
fill(255, 255, 255);
rect(0, 0, 180, 60);
fill(0, 0, 0);
text(frameRate, 0, 17);
text(bpf+"bpf", 0, 37);
text(rotX + ", " + rotY + ", " + rotZ, 0, 57); // debug in top left
timeStr += " " + (millis()-m1);
println(timeStr);
tm = millis();
}
void mouseDragged() {
rotX-=(mouseY-pmouseY)*PI/180;
rotY+=(mouseX-pmouseX)*PI/180;
background(255, 255, 255);
finishedDraw = false;
drawX = 0;
drawY = 0;
drawZ = 0;
}
void keyPressed() {
if (keyCode == 87) {
moveList[0] = true;
}
if (keyCode == 83) {
moveList[1] = true;
}
if (keyCode == 65) {
moveList[2] = true;
}
if (keyCode == 68) {
moveList[3] = true;
}
if (keyCode == 16) {
moveList[4] = true;
}
if (keyCode == 32) {
moveList[5] = true;
}
}
void keyReleased() {
if (keyCode == 87) {
moveList[0] = false;
}
if (keyCode == 83) {
moveList[1] = false;
}
if (keyCode == 65) {
moveList[2] = false;
}
if (keyCode == 68) {
moveList[3] = false;
}
if (keyCode == 16) {
moveList[4] = false;
}
if (keyCode == 32) {
moveList[5] = false;
}
}
grassBlock.png: