Monday, July 16, 2018

Helix Jump development tutorial using THREE.JS (Part 4)

Welcome to the 4th part of the Helix Jump development tutorial using THREE.JS
I hope you are doing well and learned much from the previous sections.

In the previous tutorial ( Part 3 ) you learned the basic concept of adding colliders to platforms, how to rotate helix cylinder and how to add keyboard listener.

The previous part was pretty short, I did not include the Physics part of the tutorial because I wanted to keep it separate to make you understand better.

Finally, the day has come to do some heavy lifting. Lets start !


Physics

Game physics is the most interesting part of the game. Once its implemented, gives such a great feeling of being a game programmer.

But some of you may think
game physics

Don't worry guys i will try to explain in the easiest way i can.

Velocity

Earth always pulls objects to the ground, no matter where you are, you are going up or down. So gravity is constant.

In this game, we have three requirements for the ball.

1- Increase the velocity of ball till it reach the max ( we will set our max velocity )
2- Bounce the ball with the same velocity it hits the platform.
3- Ball must gain the same height every time it hits the same level as the platform.

1- Increase the velocity

When the ball is falling down then its initial velocity is zero but due to gravity, its velocity increases till it attains the max velocity and finally hits the platform.
So we will increase its velocity with the constant gravity.

Ex- Assume value of gravity is 2 ( gy = 2 ). Initially ball velocity is 0 ( vy = 0 ), but due to gravity velocity will increase ( vy = vy + gravity )  and it hits the platform at velocity 100 ( vy = 100 )

2- Bounce the ball

When the ball hits the platform its velocity was 100 ( vy = 100 )
Now ball must bounce with the same velocity ( vy = 100 ), so we will reverse the value of velocity to negative i.e ( vy = -100 )
Now ball will move in the reverse direction because its velocity is reversed.
And because we know gravity always pulls down so constant gravity will act on the negative velocity also.

3- Gain same height

We know ball velocity was reversed to negative velocity ( vy = -100 ) and constant gravity is applying on it also so ball velocity will starts to increase to a positive value ( vy = -100 + gy )
At any time ball velocity will become 0 ( vy = 0 ) till that time ball will gain the same height and will continue its journey down again.

I hope its clear how we will add gravity to the ball If its not clear leave a comment below i will try another way to explain.

Its time to begin with code.

Game.init = function() {
    
    // add this line on top of everything in this function
    this.resetGravity();
    
    ............
    ............
    ............

}

Game.resetGravity = function  () {
    this.cy = 0;   //currrent y position
    this.dt = 0.1; //delta time to make smooth movement
    this.vy = 0;   //velocity
    this.mvy = 1;  //max velocity
    this.gravity = 0.05;
    this.collision = false;
}

function update() {
    requestAnimationFrame(update);
    Game.updateKeyboard();
    Game.renderer.render(Game.scene, Game.camera);

    if (Game.GAME_STARTED) {
        if (!Game.gameOver) {
            if (Game.collision) { // ball is on surface
                Game.vy = -Game.vy;
                Game.collision = false;
            }
            Game.cy -= Game.vy * Game.dt;
            Game.ball.position.y = Game.cy;

            if (Game.vy <= Game.mvy)
                Game.vy += Game.gravity;

            Game.sphere.position.set(Game.ball.position.x, 
                Game.ball.position.y, Game.ball.position.z);
        }
    }
}

You will notice ball is falling down and after some time it will disappear. So we need to update the camera position also.


Update Camera Position

Camera must follow ball so that when the ball falls down it do not go out of viewing area.
But we must set camera position to the lowest position of ball otherwise camera will also move up and down.

Game.updateCamera = function() {

    if (this.cameraY > this.ball.position.y)
        this.cameraY = this.ball.position.y;

    this.camera.position.set(0, this.cameraY + this.player.height, -6);
    this.camera.lookAt(new THREE.Vector3(0, this.cameraY - this.player.height, 0));
    this.light.position.set(-3, this.cameraY + this.player.height + 4, -3);
}

Now the ball is falling freely and the camera is following it too.


3D Axis and Rotation

Its very important to understand how axis in 3D space works then only you will be able to put correct values to find the collision.

This will help you understand better.
3d rotation axis


The presentation of the axis above is applicable for all 3D engines and for this game also.
If you rotate any object in any axis, just keep in mind it will rotate along its axis only.

Note - If you have to rotate the vertical plane to make it look horizontal you have to rotate it along the x axis and axis of rotation for the object will always be same.

To understand it better think of you are standing with eyes closed on a 3D plane in space, and you are said to rotate the plane along its x axis. You know what is yours x axis so you will rotate along it, now you are said to rotate along your z axis, this time also you will rotate along you own z axis not along the axis of person commanding you.

I hope now you understand rotation axis of 3D space better.


Collision Detection

When we were adding colliders i said i am using 3D AABB collision detection using closest clamp method, but it did not worked for me.
I found if i am adding the colliders directly to scene, i was able detect collision successfully but when i added it in a group then collision not detected using closest clamp method. So i figured out other way to do it.

I used matrix world position to detect collision.

To find collision you need to focus on x,y and z position of the colliders and anchor points of it.
Just look at this.

three js plane position in 3d space


In the above image find the position of edges of collider if its anchor point is in between of it and position is x = 0, y = 0, and z = 0
According to it we have to adjust our collider parameter to -5 to +5 for x axis and similarly for z axis also.
You may think why z axis ? Its because i have rotated the collider to z axis ( z axis is depth )
For y axis we have to set at what distance above the platform ball must collide.

Jump to code for collision detection.

var ind, _cubeBox;
var boxVector;
var spherePos;
var xPoint;
var yPoint;
var zPoint;
var clearInd = 0;

Game.findCollision = function() {

    ind = Math.abs(Math.round(this.cy));

    if (this.colliderArr[ind]) {
        boxVector = new THREE.Vector3();
        for (var i = 0; i < this.colliderArr[ind].length; i++) {
            _cubeBox = this.colliderArr[ind][i];
            boxVector.setFromMatrixPosition(_cubeBox.matrixWorld);
            spherePos = this.sphere.position.clone();

            xPoint = boxVector.x;
            yPoint = boxVector.y - spherePos.y;
            zPoint = boxVector.z;

            if (xPoint < 0.6 && xPoint > -0.55 && yPoint <= 2 
                && yPoint >= -0.2 && zPoint < -1.8 && zPoint > -2.4) {
                return true;
            }
        }
    }
    return false;
}


function update() {
    requestAnimationFrame(update);
    Game.updateKeyboard();
    Game.renderer.render(Game.scene, Game.camera);

    if (Game.GAME_STARTED) {
        if (!Game.gameOver) {
            if (Game.collision) { // ball is on surface
                Game.vy = -Game.vy;
                Game.collision = false;
            }
            Game.cy -= Game.vy * Game.dt;
            Game.ball.position.y = Game.cy;

            if (Game.vy <= Game.mvy)
                Game.vy += Game.gravity;

            Game.sphere.position.set(Game.ball.position.x, 
                Game.ball.position.y, Game.ball.position.z);
            Game.updateCamera();
            Game.collision = Game.findCollision();
        }
    }
}

If you run you game then you will find ball is bouncing and colliding with platforms.

Till now we have implemented all the essential features of this game. In the next part of this tutorial series we will add some more features to our game.

So this is the end of this part of tutorial series.

Where to go from here? ( Part 5 of this tutorial )




No comments:

Post a Comment

Note: Only a member of this blog may post a comment.