responsive bouncy 3d

by ixistudio

HTML

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script type="importmap">
            {
                "imports": {
                    "three": "https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.js",
                    "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.169.0/examples/jsm/"
                }
            }
        </script>
        <script src = "https://cdn.jsdelivr.net/npm/phaser@v3.85.2/dist/phaser.min.js"></script>
    </head>
    <body>
        
        <div id="thegame"><canvas id="game-canvas"></canvas></div>
        
    </body>
</html>

CSS

/* Apply a natural box layout model to all elements */
            *, *:before, *:after {
              -moz-box-sizing: border-box; 
              -webkit-box-sizing: border-box; 
              box-sizing: border-box; 
            }

            body{
                background: #FFFFB3;
                padding: 0px;
                margin: 0px;
            }

            #thegame {
                display: block;
                margin: 0;
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 100%;
                height: 100%;
                z-index: 10;
            }

JavaScript

import * as THREE from 'three';
//import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js';

/********************************s
 * RESPONSIVE BOUNCY 3D
 */


// Should the resize functions run once as part of update()
let is_resize = false; 

// Is the game restarting, used on the initial start as well 
let is_game_restart = true; 

// Is the game on the viewport enough to be active
let is_game_on_viewport = true; 

// Is this the first time for update()
let is_first_update = false; 

// Should game be paused, happens on update()
let is_pause = false; 

// Has the start button been clicked
let has_game_started = true; 

// Holds width and height of last screen sizes
let screen_last_size = [window.innerWidth, window.innerHeight]; 

// Compensate on y axis to change perspective on 3d platforms
let platform_landscape_ball_compensate = -9;


/********************************s
 * GAME
 */

var game;
let gameOptions = {

    // ball gravity
    ballGravity: 1200,

    // bounce velocity when the ball hits a platform
    bounceVelocity: 800,

    // ball start x position, 0 = left; 1 = right
    ballStartXPosition: 0.2,

    // amount of platforms to be created and recycled
    platformAmount: 10,

    // platform speed, in pixels per second
    platformSpeed: 650,

    // min and max distance range between platforms
    platformDistanceRange: [250, 450],

    // min and max platform height, , 0 = top of the screen; 1 = bottom of the screen
    platformHeightRange: [0.5, 0.8],

    // min and max platform length
    platformLengthRange: [40, 160],

    // local storage name where to save best scores
    localStorageName: "bestballscore3d",

    // game scale between 2D and 3D
    gameScale: 0.1 
}


class playGame extends Phaser.Scene {

	// Store mesh and then clone for efficiency
    geometry_3D_platform = false;
    material_3D_platform = false;
    mesh_3D_platform = false;

    constructor(){

        super({
            key: 'PlayGame'
    ...