We are about to switch to a new forum software. Until then we have removed the registration on this forum.
hello all,
I am working on a camera class that also should follow the Ball. Remember good old Mario? The camera follows him. What I have trouble with is when he's turning. Instead of Mario I have a green ball. The camera follows it a bit higher behind it. But when the ball gets reflected inside a huge invisible cube (when it turns around), the ball shoots through the camera. That doesn't look good.
I want it so like in the Mario Game that the ball in a way pushes away the camera and the camera steps aside and let's the ball through. As if there is a stick between ball and camera that avoids getting the camera too close to the ball.
But I don't have the math for it.
Can anyone improve the method "follow" in the class?
Big Thanks, Greetings, Chrisir ;-)
// see also peasycam.
// see also forum.processing.org/two/discussion/comment/16112#Comment_16112
final int stateKeyboard = 0;
final int stateRotateAroundScene = 1;
final int stateCameraRotatesAroundItself = 2;
final int stateCameraBall = 3;
final int stateCameraBall2 = 4;
final int stateCameraBall3 = 5;
int state = stateCameraBall3;
// cubes
float angleCubes=45; // angle for the cubes in the scene
CameraClass cam;
PVector ballPos = new PVector (300, 300, -100);
PVector ballVel = new PVector (1, -1, -1);
// -------------------------------------------------------
void setup() {
size (600, 600, P3D);
cam = new CameraClass ();
}
void draw() {
switch (state) {
case stateCameraBall3:
background(111);
lights();
// folow
cam.follow(ballPos);
// set the values of the class to the real camera
cam.set();
//
ballPos.add(ballVel);
fill(0, 255, 0);
noStroke();
mySphere(ballPos.x, ballPos.y, ballPos.z, 10);
contain(ballPos, ballVel);
// make the scene with the boxes
scene();
// upper left corner
cam.HUD_text("The ball mode 3. ");
break;
default:
println ("Fatal error, unknow state, 035 with state-value "
+state+".");
exit();
break;
} // switch
} // func
// ---------------------------------------------------
void scene () {
//fill ( 200, 23, 23);
stroke(2);
//noStroke();
// rect (400, 300, 20, 20);
// line(22, 22, 33, 33);
float z ;
// one wall of boxes
for (int x = 10; x < 600; x+= 100)
{
fill(x/3, 2, 2);
for (int y = 10; y < 600; y+= 100)
{
z = -600;
myBox(x, y, z, 24);
// println ( "Box: " + x + ", "+y+ " "+z);
}
fill(0, 0, 254);
z=-800;
myBox(x, 10, z, 24);
}
//
// a few additional boxes
fill(0, 0, 254);
z=-400;
myBox(220, 10, z, 24);
myBox(600, 10, z, 24);
z=-400;
myBox(220, 510, z, 24);
myBox(600, 510, z, 24);
z=399;
myBox(220, 510, z, 24);
myBox(600, 510, z, 24);
z=900;
myBox(220, 510, z, 24);
myBox(600, 510, z, 24);
angleCubes++;
// save("test.jpg");
}
void myBox(float x, float y, float z,
float size1) {
// one nice wrapper for build in box-command
pushMatrix();
translate(x, y, z);
rotateY(radians(angleCubes));
rotateX(radians(45));
box(size1);
popMatrix();
}
void mySphere(float x, float y, float z,
float size1) {
// one nice wrapper for build in box-command
pushMatrix();
translate(x, y, z);
rotateY(radians(angleCubes));
rotateX(radians(45));
sphere(size1);
popMatrix();
}
void contain(PVector ballPos, PVector ballVel) {
//
fill(255, 2, 2);
mySphere(500, 500, 500, 20);
mySphere(100, 100, 100, 20);
//
if (ballPos.x>500)
ballVel.x=abs(ballVel.x)*-1;
if (ballPos.y>500)
ballVel.y=abs(ballVel.y)*-1;
if (ballPos.z>500)
ballVel.z=abs(ballVel.z)*-1;
if (ballPos.x<100)
ballVel.x=abs(ballVel.x);
if (ballPos.y<100)
ballVel.y=abs(ballVel.y);
if (ballPos.z<100)
ballVel.z=abs(ballVel.z);
}
//
// ====================================================================
class CameraClass {
// capsules the normal camera() command and its vectors
PVector camPos; // its vectors
PVector camLookAt;
PVector camUp;
PVector camPosInitial; // its vectors - the default (unchanged)
PVector camLookAtInitial;
PVector camUpInitial;
// for follow
PVector camWhereItShouldBe = new PVector(0, 0, 0);
PVector camAdd = new PVector(0, -60, 0);
float easing = .019; // .07; // how fast it changes
float camCurrentAngle=-90; // for cam rotation around itself (around Y-axis)
float camRadius; // same situation
// constructor without parameters
CameraClass() {
// constr
// set vectors
camPos = new PVector(width/2.0, height/2.0, 0);
camLookAt = new PVector(width/2.0, height/2.0, -600);
camUp = new PVector( 0, 1, 0 );
// save the initial values
camPosInitial = camPos.get();
camLookAtInitial = camLookAt.get();
camUpInitial = camUp.get();
} // constr
void set() {
// apply vectors to actual camera
camera (camPos.x, camPos.y, camPos.z,
camLookAt.x, camLookAt.y, camLookAt.z,
camUp.x, camUp.y, camUp.z);
}
// -------------------------------------------------
void setLookAt (float x1, float y1, float z1) {
camLookAt = new PVector(x1, y1, z1);
}
// -------------------------------------------------
void printData() {
println ( "Cam at " + camPos
+ " looking at " + camLookAt
+ " (angle = "
+camCurrentAngle
+").");
}
// --------
void lookAtPVector (PVector followMe) {
// follows a player (e.g.)
camLookAt = followMe.get();
}
void follow (PVector followMe) {
// follows a player or ball (e.g.)
camLookAt = followMe.get();
// behind ball but with easing
camWhereItShouldBe.set(followMe.x+camAdd.x, followMe.y+camAdd.y, followMe.z+camAdd.z);
camPos.x+= ( camWhereItShouldBe.x - camPos.x ) * easing;
camPos.y+= ( camWhereItShouldBe.y - camPos.y ) * easing;
camPos.z+= ( camWhereItShouldBe.z - camPos.z ) * easing;
}
// ---------------------------------
void HUD_text (String a1) {
// HUD text upper left corner
// this must be called at the very end of draw()
// this is a 2D HUD
camera();
hint(DISABLE_DEPTH_TEST);
noLights();
// ------------------
textSize(16);
text (a1, 20, 20);
// ------------------
// reset all parameters to defaults
textAlign(LEFT, BASELINE);
rectMode(CORNER);
textSize(32);
hint(ENABLE_DEPTH_TEST); // no HUD anymore
lights();
} // method
//
} // class
// ========================================================