2d UI elements in a 3d environment in Processing

26 views Asked by At

I'm making a basic minecraft-style 3d game, and I'm trying to add UI. I set up the game using the built in camera() function, not peasycam, which is what all the answers I've seen are for. I want to have more control over the camera than peasycam allows. How do I create 2d objects like rectangles and text that stay static over the screen and always face the camera?

I have 4 3d vectors: one for position, one for velocity, one for camera angle, and one for camera rotation before I use trigonometry on it. I placed a sphere and a piece of text in the game (under the hud() function in draw()). I used translate() to position them, and it worked, but looking up and down shows that they do not follow camera movement.

import java.awt.Robot;
import java.awt.AWTException;

final float size = 100;
final float speed = 10;
final float look = .02;
final float playerHeight = size;
final float renderDist = 2600;

Robot robot;

PVector pos = new PVector(0, 0, 0); //position
PVector vel = new PVector(0, 0, 0); //velocity
PVector cam = new PVector(0, 0, 0); //camera angle
PVector rot = new PVector(0, 0, 0); //camera rotation

ArrayList<Block> blocks = new ArrayList<Block>();

void setup(){
  fullScreen(P3D);
  noCursor();
  
  blocks.add(new Block(0, 0, 0, color(255)));
  blocks.add(new Block(1, 0, 0, color(255, 0, 0)));
  blocks.add(new Block(0, 1, 0, color(0, 255, 0)));
  blocks.add(new Block(0, 0, 1, color(0, 0, 255)));
  genFloor(500);
  
  try {
    robot = new Robot();
  } catch (AWTException e){
    e.printStackTrace();
  }
}

void draw(){
  background(115, 189, 245);
  
  look();
  movement();
  display();
  hud();
}
class Block{
  PVector pos = new PVector();
  color thisColor = color(255);
  
  Block (int x, int y, int z, color thisColor){
    pos.x = x;
    pos.y = y;
    pos.z = z;
    this.thisColor = thisColor;
  }
  
  Block (int x, int y, int z){
    pos.x = x;
    pos.y = y;
    pos.z = z;
  }
}
void display(){
  for (Block block : blocks){
    float distance = (float)Math.pow(Math.pow(block.pos.x * size - pos.x, 2) + Math.pow(block.pos.z * size - pos.z, 2), .5);
    if (distance <= renderDist){
      pushMatrix();
      translate(size * block.pos.x, size * block.pos.y, size * block.pos.z);
      fill(block.thisColor);
      box(size);
      popMatrix();
    }
  }
}

void movement(){
  pos.x += vel.z * cam.x + vel.x * cam.z;
  pos.y += vel.y;
  pos.z += -vel.x * cam.x + vel.z * cam.z;
  
  camera(pos.x, pos.y + playerHeight, pos.z,   pos.x + cam.x, pos.y + cam.y + playerHeight, pos.z + cam.z,   0, -1, 0);
}

void keyPressed(){
  if (key == 'w'){
    vel.z = speed;
  }
  if (key == 's'){
    vel.z = -speed;
  }
  if (key == 'd'){
    vel.x = speed;
  }
  if (key == 'a'){
    vel.x = -speed;
  }
}

void keyReleased(){
  if (key == 'w' && vel.z > 0){
    vel.z = 0;
  }
  if (key == 's' && vel.z < 0){
    vel.z = 0;
  }
  if (key == 'd' && vel.x > 0){
    vel.x = 0;
  }
  if (key == 'a' && vel.x < 0){
    vel.x = 0;
  }
}

void look(){
  rot.x -= (mouseX - width/2) * look;
  rot.y += (mouseY - height/2) * look;
  
  if (rot.y < -11){
    rot.y = -11;
  }
  if (rot.y > -8){
    rot.y = -8;
  }
  
  robot.mouseMove(width/2, height/2);
  
  cam.x = (float)Math.cos(rot.x);
  cam.y = (float)Math.sin(rot.y);
  cam.z = (float)Math.sin(rot.x);
}

void genFloor(int size){
  for (int x = size/-2; x < size/2; x++){
    for (int z = size/-2; z < size/2; z++){
      blocks.add(new Block(x, -1, z));
    }
  }
}

void hud(){
  pushMatrix();
  translate(pos.x + cam.x * 100, pos.y + playerHeight + cam.y * 100, pos.z + cam.z * 100);
  fill(0);
  sphere(1);
  rotateX(radians(180));
  text("text", 0,0);
  popMatrix();
}
0

There are 0 answers