Hello all,
I would like to make a 3rd Person Shooter (or 3rd Person Player) where a player in 3D is followed by a camera. Move with mouse and wasd keys.
I found a code in the forum.
- But in the code, the player and camera are fixed in the center and it is the floor that in facts move.
I want it in another way:
- That the floor is fixed and we move the player and with it the camera (being always behind the player).
Unfortunately, the code doesn’t work. Can anyone help me debug it? I am out of my depth because the maths and rotations. Thank you so much!
This is part of a much bigger project but I made a mcve, based on the code I found.
Any help much appreciated!
Warm regards,
Chrisir
// this version with heavy new structure : not the ground moves anymore but now player plus camera move!!!
import java.awt.*;
Robot robot;
float cameraRotateX;
float cameraRotateY;
float cameraSpeed;
float angle;
boolean wPressed, sPressed, aPressed, dPressed;
PVector pressedDir = new PVector();
float accelMag;
Player player;
com.jogamp.newt.opengl.GLWindow myGLWindow;
float gridLevelY;
// ----------------------------------------------------------------------------------------
void setup() {
fullScreen(P3D);
myGLWindow=getFrame(getSurface());
accelMag = 2;
player = new Player();
gridLevelY = height/2;
cameraSpeed = TWO_PI / width;
cameraRotateY = -PI/6;
try {
robot = new Robot();
}
catch(Exception ex) {
println(ex);
}
noCursor();
}
void draw() {
background(125);
lights();
updateRotation();
beginCamera(); // ??????????????????????????
camera();
translate(player.pos.x, gridLevelY-player.bsize/2, player.pos.y); // ??? qqqq
rotateX(cameraRotateY);
rotateY(cameraRotateX);
endCamera();
translate(width/2, height/10, 0);
// pushMatrix();
player.jumpManagement();
player.display();
player.move();
decoration();
drawGrid();
// popMatrix();
angle += mouseChangeX()*0.003;
robot.mouseMove(getSketchCenterX(), getSketchCenterY());
}//func
// -----------------------------------------------------------------
void drawGrid() {
pushMatrix();
int count = 50;
// translate(-player.pos.x, gridLevelY, -player.pos.y);
translate(0, gridLevelY, 0);
stroke(255);
float size = (count -1) * player.bsize*2;
for (int i = 0; i < count; i++) {
float pos2 = map(i, 0, count-1, -0.5 * size, 0.5 * size);
line(pos2, 0, -size/2, pos2, 0, size/2);
line(-size/2, 0, pos2, size/2, 0, pos2);
}
popMatrix();
}
// -----------------------------------------------------------------
void decoration() {
pushMatrix();
// translate(-player.pos.x, 0, -player.pos.y);
translate(-333, gridLevelY-320/2, 333);
fill(0, 0, 255);
box(120, 320, 120);
popMatrix();
}
// -----------------------------------------------------------------
int getSketchCenterX() {
return
myGLWindow.getX() + width / 2;
}
int getSketchCenterY() {
return
myGLWindow.getY() + height / 2;
}
static final com.jogamp.newt.opengl.GLWindow getFrame(final PSurface surface) {
// used only once !
return
(com.jogamp.newt.opengl.GLWindow) surface.getNative();
}
float mouseChangeX() {
return
getSketchCenterX() - (float) MouseInfo.getPointerInfo().getLocation().getX();
}
float mouseChangeY() {
return
getSketchCenterY() - (float) MouseInfo.getPointerInfo().getLocation().getY();
}
void updateRotation() {
cameraRotateX -= mouseChangeX() * cameraSpeed;
cameraRotateY += mouseChangeY() * cameraSpeed;
cameraRotateY = constrain(cameraRotateY, -HALF_PI, 0);
}
// --------------------------------------------------------------------------
void mouseClicked() {
//only used so I can keep track of coordinates in case I need to change things
player.printPos();
println("X" + mouseX);
println("Y" + mouseY);
}
void keyPressed() {
if (keyCode == SHIFT) {
accelMag = 4;
}
switch(key) {
case ' ':
player.startJump();
break;
case 'w':
wPressed = true;
pressedDir.y = -1;
break;
case 'a':
aPressed = true;
pressedDir.x = -1;
break;
case 's':
sPressed = true;
pressedDir.y = 1;
break;
case 'd':
dPressed = true;
pressedDir.x = 1;
break;
}
}
void keyReleased() {
if (keyCode == SHIFT) {
accelMag = 2;
}
switch(key) {
case 'w':
wPressed = false;
pressedDir.y = sPressed ? 1 : 0;
break;
case 'a':
aPressed = false;
pressedDir.x = dPressed ? 1 : 0;
break;
case 's':
sPressed = false;
pressedDir.y = wPressed ? -1 : 0;
break;
case 'd':
dPressed = false;
pressedDir.x = aPressed ? -1 : 0;
break;
}
}
//==================================================================
class Player {
PVector bpos = new PVector();
float bsize = 100;
// jump
float playermoveY = 0;
boolean jump=false;
int jumpcounter=0;
PVector pos, speed;
// constr
Player() {
// bpos.y = height/2+bsize/2;
pos = new PVector();
speed = new PVector();
} // constr
void display() {
pushMatrix();
//translate(bpos.x, bpos.y, bpos.z);
// translate(player.pos.x, gridLevelY, player.pos.y); // ??? qqqq
translate(player.pos.x, bpos.y, player.pos.y); // ??? qqqq
translate(bpos.x,
gridLevelY-bsize/2,
bpos.z);
stroke(255);
fill(0);
rotateY(atan2(speed.x, speed.y));
box(bsize);
popMatrix();
}
void move() {
PVector accel = getMovementDir().rotate(cameraRotateX).mult(accelMag);
speed.add(accel);
pos.add(speed);
speed.mult(0.9);
}
PVector getMovementDir() {
return
pressedDir.copy().normalize();
}
void startJump() {
// jump
// if he's already jumping, no jump is allowed
if (jump)
return; // leave
// otherwise jump
jumpcounter=0;
playermoveY=-21;
jump=true;
}
void jumpManagement() {
if (jump) {
bpos.y +=
playermoveY;
}
// stop the jump
if (bpos.y>=0) { // gridLevelY-bsize/2
bpos.y=0;
if (jumpcounter==0) {
// bounce
playermoveY=-10;
jumpcounter++;
} else if (jumpcounter==1) {
// bounce
playermoveY=-7;
jumpcounter++;
} else {
// stop jump
jump=false;
playermoveY=0;
}
} //if
else {
playermoveY++;
}
}//func
void printPos() {
println("bpos.x " + bpos.x);
println("bpos.y " + bpos.y);
println("bpos.z " + bpos.z);
}
//
}
//
//