// Cloned by Musthaq Ahmed on 22 Sep 2022 from World "Final Pool" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 1 Mar 2019 from World "v0.98 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 28 Feb 2019 from World "v0.97 Pool Predictor Prototype" by lillisl2
// Please leave this clone trail here.
// Cloned by lillisl2 on 27 Feb 2019 from World "v0.95 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 25 Feb 2019 from World "v0.94 Pool Predictor Prototype" by lillisl2
// Please leave this clone trail here.
// Cloned by lillisl2 on 25 Feb 2019 from World "v0.94 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 25 Feb 2019 from World "v0.92 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 20 Feb 2019 from World "v0.91 Pool Predictor Prototype" by lillisl2
// Please leave this clone trail here.
// Cloned by lillisl2 on 20 Feb 2019 from World "v0.9 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 20 Feb 2019 from World "v0.8 Pool Predictor Prototype" by lillisl2
// Please leave this clone trail here.
// Cloned by lillisl2 on 19 Feb 2019 from World "v0.7 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 18 Feb 2019 from World "v0.6 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 16 Feb 2019 from World "v0.5 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 14 Feb 2019 from World "v0.44 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 12 Feb 2019 from World "v0.43 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 5 Feb 2019 from World "v0.3 Pool Predictor Prototype" by lillisl2
// Please leave this clone trail here.
// Cloned by lillisl2 on 4 Feb 2019 from World "v0.2 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 1 Feb 2019 from World "lillisl2 0.2 Pool Predictor Prototype" by lillisl2
// Please leave this clone trail here.
// Cloned by lillisl2 on 1 Feb 2019 from World "0.1 Pool Predictor Prototype" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 30 Jan 2019 from World "Pool Predictor Prototype" by lillisl2
// Please leave this clone trail here.
// Cloned by lillisl2 on 28 Jan 2019 from World "Cloned Bouncy Balls" by Ian Gilligan
// Please leave this clone trail here.
// Cloned by Ian Gilligan on 28 Jan 2019 from World "Bouncy Balls" by Starter user
// Please leave this clone trail here.
// ==== Starter World ===============================================================================================
// (c) Ancient Brain Ltd. All rights reserved.
// This code is only for use on the Ancient Brain site.
// This code may be freely copied and edited by anyone on the Ancient Brain site.
// This code may not be copied, re-published or used on any other website.
// To include a run of this code on another website, see the "Embed code" links provided on the Ancient Brain site.
// ==================================================================================================================
// Physijs based World
// Bouncy balls
// ===================================================================================================================
// === Start of tweaker's box ========================================================================================
// ===================================================================================================================
// The easiest things to modify are in this box.
// You should be able to change things in this box without being a JavaScript programmer.
// Go ahead and change some of these. What's the worst that could happen?
AB.maxSteps = 100000;
AB.screenshotStep = 50;
AB.clockTick = 50;
// Take screenshot on this step. (All resources should have finished loading.) Default 50.
// ===================================================================================================================
// === Variables & Constants =========================================================================================
// ===================================================================================================================
const OBJPATH = "/uploads/gilligi2/"; // path of OBJ and MTL
const OBJNAME = "pooltable.obj";
const MTLNAME = "pooltable.mtl";
const SOUND_COLLISION = "/uploads/gilligi2/pool_sound.mp3";
const SOUND_GOOD = "/uploads/gilligi2/good_shot_sound.mp3";
const SOUND_BAD = "/uploads/gilligi2/bad_shot_sound.mp3";
const SOUND_CLICK = "/uploads/gilligi2/button_click_sound.mp3";
const MODELLENGTH = 11054;
const MODELWIDTH = 6279;
const SCALE = 0.009;
const BALLSIZE = 2; // size of each ball
const BALLPOS = BALLSIZE * 100; // x,z start position of balls is random in this interval
const BALLHEIGHT = BALLSIZE * 2; // y start position of balls
const HEAVYIMPACT = 1; // heavy impacts have y velocity greater than this
const GROUNDSIZE = 150; // size of table
const startRadius = MODELWIDTH * 0.02; // camera start distance
const maxRadius = MODELLENGTH * 0.03; // camera max distance
const SKYCOLOR = 0xccddff; //colour of sky / background (white)
// friction and restitution between 0 and 1:
const GROUND_FRICTION = 1; // friction of ground
const GROUND_RESTITUTION = 0.40; // restitution of ground
const WALL_FRICTION = 0.7; // friction of wall
const WALL_RESTITUTION = 0.9; // restitution of wall
const BALL_FRICTION = 1; // friction of ball
const BALL_RESTITUTION = 1; // restitution of ball
var LIMIT = [7,7,1,1]; // limit values of each type of balls [yellow, red, black, white]
var BALL_CHOICE = 0; // the ball that the user has currently selected
const BALL_TYPE = [ // what each value of ball choice (0-3) represent
"Yellow",
"Red",
"Black",
"White"];
// define gravity along x,y,z dimensions:
const gravity = new THREE.Vector3 (0, -150, 0);
const BALL_MASS = 1; // mass of ball
const BASE_POWER = 500;
var CURRENT_POWER = 0;
var MIN_POWER = 1;
var MAX_POWER = 5;
var SAVED_POWER = 0;
var YOURCOLOR = "None";
var CALCULATED = false;
var CALCULATING = false;
// == Balls Placed ==
var BALL_COUNT = 0;
var BALLS = [];
var WHITE = -1;
// == Ball Colors ==
const BALL_COLORS = {
0 : "Yellow",
1 : "Red",
2 : "Black",
3 : "White"};
const BALL_COLORS_R = {
"Yellow" : 0,
"Red" : 1,
"Black" : 2,
"White" : 3};
// == Ball Movement ==
var OBSTRUCTION = false;
var isSpace = true;
var movFin = false;
var MOVING = false;
var last_velocity = 0;
const SLOWFACTOR = 0.1;
// == Score Calculation ==
var POCKETED = false;
var WHITE_POT = false;
var BLACK_POT = false;
var firstHit = true;
var YOURSCORE = 0;
var OTHERSCORE = 0;
var FOUL = false;
var setUpScene;
var SCORE = 50;
var ANGLE;
// == Shot Choice ==
var BALLS_TO_POT = 0;
var BALLS_ATTEMPTED = 0;
var SHOT_PICKED = 0;
// == Shot Angle ==
var ANGLE_COUNT = 0;
var ANGLES = [
[-0.04, -0.04],
[-0.04, 0.04],
[0.04, -0.04],
[0.04, 0.04]];
// == Camera ==
ABWorld.drawCameraControls = false;
var CAMERA = "On";
var cameraPocketCounter = 0;
var CONTROLLER = false;
// == UI ==
var PAGE_SELECT = 1;
var CURRENT_PAGE = 0;
const line4_1 = ("<p align=\"center\"><button id='yellowButton'>__</button><button id='redButton'>__</button> <button id='blackButton'>__</button> <button id='whiteButton'>__</button></p>");
const line4_3 = ("<p align=\"center\"><button id='gameButton'> Game Controls</button> <button id='cameraButton'>Camera Controls</button></p>");
const line6_1 = ("<p align=\"center\"><button id='yourNButton'>__</button> <button id='yourYButton'>__</button> <button id='yourRButton'>__</button></p>");
const line6_2 = ("<p align=\"center\"><button id='decreasePowerMinButton'>- Min</button> <button id='increasePowerMinButton'>+ Min</button> <button id='decreasePowerMaxButton'>- Max</button> <button id='increasePowerMaxButton'>+ Max</button></p> ");
const line6_3 = ("<p align=\"center\"><button id='cameraFlatButton'>Flat Down View</button> <button id='cameraCornerButton'>Pocket View</button></p> ");
// == Save ==
BALL_LAYOUT = [];
BEST_SCORES = [];
var toggleBasic = false;
var toggledBasic = false;
// ===================================================================================================================
// === End of tweaker's box ==========================================================================================
// ===================================================================================================================
// You will need to be some sort of JavaScript programmer to change things below the tweaker's box.
// ===================================================================================================================
// === Inits & Loads =================================================================================================
// ===================================================================================================================
var resourcesLoaded = false;
var splashClicked = false;
function World()
{
var ground_texture;
var self = this;
var GROUND;
var table;
var p_height = 25;
// --- Cue -----------------------------------------------------------------------
var cue_material = Physijs.createMaterial(new THREE.MeshStandardMaterial({color : "#c96120"}));
var cue = new THREE.Mesh(new THREE.CylinderGeometry(0.5,1.5,100, 100), cue_material , 0);
cue.position.x = -51;
cue.position.y = 4;
cue.rotation.z = (Math.PI / 2) * 3 - 0.05;
var pivot = new THREE.Mesh(new THREE.SphereGeometry(0.001, 10, 10), cue_material, 0);
pivot.add(cue);
// --- Ball ----------------------------------------------------------------------
var ball_material_0 = Physijs.createMaterial(new THREE.MeshLambertMaterial({color : "yellow"}), BALL_FRICTION, BALL_RESTITUTION);
var ball_material_1 = Physijs.createMaterial(new THREE.MeshLambertMaterial({color : "red"}), BALL_FRICTION, BALL_RESTITUTION);
var ball_material_2 = Physijs.createMaterial(new THREE.MeshLambertMaterial({color : "black"}), BALL_FRICTION, BALL_RESTITUTION);
var ball_material_3 = Physijs.createMaterial(new THREE.MeshLambertMaterial({color : "white"}), BALL_FRICTION, BALL_RESTITUTION);
var ball_geometry = new THREE.SphereGeometry(BALLSIZE, 100, 100);
// --- Space ---------------------------------------------------------------------
var space_material = Physijs.createMaterial(new THREE.MeshStandardMaterial({color : "#c96120"}));
function loadResources() // asynchronous file loads - call initScene() when all finished
{
var m = new THREE.MTLLoader();
m.setTexturePath (OBJPATH);
m.setPath (OBJPATH);
m.load ( MTLNAME, function ( materials )
{
materials.preload();
var o = new THREE.OBJLoader();
o.setMaterials ( materials );
o.setPath ( OBJPATH );
o.load ( OBJNAME, function ( object )
{
table = object;
if ( asynchFinished() ) initScene();
});
});}
function asynchFinished() // all file loads returned
{
if (! table){
return false;}
return true;}
function initScene() // all file loads have returned
{
// --- Light ------------------------------------------------------------------
var light = new THREE.DirectionalLight(0xFFFFFF, 0.4);
// close to origin, high up, works best for shadows
light.position.set(0, 40, 0);
light.target.position.copy(ABWorld.scene.position);
light.castShadow = true;
// how far away to draw shadows:
light.shadow.camera.left = -20;
light.shadow.camera.right = 20;
light.shadow.camera.bottom = -20;
light.shadow.camera.top = 20;
// higher quality shadows at expense of computation time:
light.shadow.mapSize.width = 2048;
light.shadow.mapSize.height = 2048;
light.shadow.bias = -0.1;
ABWorld.scene.add(light);
var light1 = new THREE.DirectionalLight(0xFFFFFF, 0.4);
var light2 = new THREE.DirectionalLight(0xFFFFFF, 0.4);
var light3 = new THREE.DirectionalLight(0xFFFFFF, 0.4);
var light4 = new THREE.DirectionalLight(0xFFFFFF, 0.4);
light1.position.set(100, 30, 0);
light2.position.set(-100, 30, 0);
light3.position.set(0, 30, 100);
light4.position.set(0, 30, -100);
ABWorld.scene.add(light1);
ABWorld.scene.add(light2);
ABWorld.scene.add(light3);
ABWorld.scene.add(light4);
// --- Table -------------------------------------------------------------------
table.position.y = 0;
table.position.x = -15;
table.position.z = 0;
ABWorld.scene.add(table);
// --- Ground ------------------------------------------------------------------
var ground_material = Physijs.createMaterial(new THREE.MeshStandardMaterial({wireframe : true, color : "#444444"}), GROUND_FRICTION, GROUND_RESTITUTION);
// ground as plane allows bounces but seems to be infinite plane
var ground = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.93, 1, MODELWIDTH * SCALE * 0.68), ground_material, 0);
ground.position.y = p_height;
ground.collisions = 0;
ground.receiveShadow = true;
GROUND = ground;
// --- Floor -------------------------------------------------------------------
var floor_material = Physijs.createMaterial(new THREE.MeshStandardMaterial({color: "#a0192b"}), 0.1, 0.1);
var floor = new Physijs.PlaneMesh(new THREE.PlaneGeometry(1000, 1000), floor_material);
floor.rotation.x = (Math.PI / 2) * 3;
floor.receiveShadow = true;
floor.addEventListener('collision', function(other_object, relative_velocity, relative_rotation, contact_normal)
{
POCKETED = false;
FOUL = true;
removeBall(other_object);
});
ABWorld.scene.add(floor);
// --- Wall --------------------------------------------------------------------
var wall_material = Physijs.createMaterial(new THREE.MeshStandardMaterial({wireframe : true}), WALL_FRICTION, WALL_RESTITUTION);
var wall1 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 1.03, 5.9, MODELWIDTH * SCALE * 0.055), wall_material, 0);
wall1.position.z = 27.5;
wall1.collisions = 0;
wall1.receiveShadow = true;
var wall2 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 1.03, 5.9, MODELWIDTH * SCALE * 0.055), wall_material, 0);
wall2.position.z = -27.7;
wall2.collisions = 0;
wall2.receiveShadow = true;
var wall3 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.02, 5.9, MODELWIDTH * SCALE * 0.92), wall_material, 0);
wall3.position.x = 52.2;
wall3.collisions = 0;
wall3.receiveShadow = true;
var wall4 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.02, 5.9, MODELWIDTH * SCALE * 0.92), wall_material, 0);
wall4.position.x = -52.2;
wall4.collisions = 0;
wall4.receiveShadow = true;
wall1.visible = false;
wall2.visible = false;
wall3.visible = false;
wall4.visible = false;
// --- Bumper --------------------------------------------------------------------
var bumper1 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.33, 5.9, MODELWIDTH * SCALE * 0.075 * 1.65), wall_material, 0);
bumper1.position.z = 23.5;
bumper1.position.x = 23.5;
bumper1.position.y = -0.1;
bumper1.collisions = 0;
bumper1.receiveShadow = true;
var bumper2 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.33, 5.9, MODELWIDTH * SCALE * 0.075 * 1.65), wall_material, 0);
bumper2.position.z = 23.5;
bumper2.position.x = -23;
bumper2.collisions = 0;
bumper2.receiveShadow = true;
var bumper3 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.33, 5.9, MODELWIDTH * SCALE * 0.075 * 1.58), wall_material, 0);
bumper3.position.z = -23.5;
bumper3.position.x = 23.5;
bumper3.position.y = -0.1;
bumper3.collisions = 0;
bumper3.receiveShadow = true;
var bumper4 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.33, 5.9, MODELWIDTH * SCALE * 0.075 * 1.58), wall_material, 0);
bumper4.position.z = -23.5;
bumper4.position.x = -23;
bumper4.collisions = 0;
bumper4.receiveShadow = true;
var bumper5 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.047, 5.9, MODELWIDTH * SCALE * 0.56), wall_material, 0);
bumper5.position.z = 0;
bumper5.position.x = 49;
bumper5.receiveShadow = true;
var bumper6 = new Physijs.BoxMesh(new THREE.BoxGeometry(MODELLENGTH * SCALE * 0.047, 5.9, MODELWIDTH * SCALE * 0.56), wall_material, 0);
bumper6.position.z = 0;
bumper6.position.x = -49;
bumper6.receiveShadow = true;
bumper1.visible = false;
bumper2.visible = false;
bumper3.visible = false;
bumper4.visible = false;
bumper5.visible = false;
bumper6.visible = false;
ground.add(wall1);
ground.add(wall2);
ground.add(wall3);
ground.add(wall4);
ground.add(bumper1);
ground.add(bumper2);
ground.add(bumper3);
ground.add(bumper4);
ground.add(bumper5);
ground.add(bumper6);
// --- Bumper Edge ---------------------------------------------------------------
var bumperedge1 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge1.position.z = 23;
bumperedge1.position.x = 7.8;
bumperedge1.receiveShadow = true;
var bumperedge2 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge2.position.z = 23;
bumperedge2.position.x = -7.5;
bumperedge2.receiveShadow = true;
var bumperedge3 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge3.position.z = -23.1;
bumperedge3.position.x = 7.8;
bumperedge3.receiveShadow = true;
var bumperedge4 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge4.position.z = -23.1;
bumperedge4.position.x = -7.5;
bumperedge4.receiveShadow = true;
var bumperedge5 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge5.position.z = 23;
bumperedge5.position.x = 39.1;
bumperedge5.receiveShadow = true;
var bumperedge6 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge6.position.z = 23;
bumperedge6.position.x = -39;
bumperedge6.receiveShadow = true;
var bumperedge7 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge7.position.z = -23.1;
bumperedge7.position.x = 39.1;
bumperedge7.receiveShadow = true;
var bumperedge8 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge8.position.z = -23.1;
bumperedge8.position.x = -39;
bumperedge8.receiveShadow = true;
var bumperedge9 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge9.position.z = 14.2;
bumperedge9.position.x = 49.6;
bumperedge9.receiveShadow = true;
var bumperedge10 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge10.position.z = 14.2;
bumperedge10.position.x = -49.6;
bumperedge10.receiveShadow = true;
var bumperedge11 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge11.position.z = -14.2;
bumperedge11.position.x = 49.6;
bumperedge11.receiveShadow = true;
var bumperedge12 = new Physijs.CylinderMesh( new THREE.CylinderGeometry( 3, 2.9, 5.7, 100 ), wall_material );
bumperedge12.position.z = -14.2;
bumperedge12.position.x = -49.6;
bumperedge12.receiveShadow = true;
bumperedge1.visible = false;
bumperedge2.visible = false;
bumperedge3.visible = false;
bumperedge4.visible = false;
bumperedge5.visible = false;
bumperedge6.visible = false;
bumperedge7.visible = false;
bumperedge8.visible = false;
bumperedge9.visible = false;
bumperedge10.visible = false;
bumperedge11.visible = false;
bumperedge12.visible = false;
ground.add(bumperedge1);
ground.add(bumperedge2);
ground.add(bumperedge3);
ground.add(bumperedge4);
ground.add(bumperedge5);
ground.add(bumperedge6);
ground.add(bumperedge7);
ground.add(bumperedge8);
ground.add(bumperedge9);
ground.add(bumperedge10);
ground.add(bumperedge11);
ground.add(bumperedge12);
ABWorld.scene.add(ground);
// --- Pocket --------------------------------------------------------------------
var pocket_material = Physijs.createMaterial(new THREE.MeshStandardMaterial());
var pocket = new Physijs.SphereMesh(new THREE.SphereGeometry(1), pocket_material, 0);
pocket.position.y = -4;
var pocket1 = new Physijs.SphereMesh(new THREE.SphereGeometry(4, 15, 15), pocket_material, 0);
pocket1.position.y = p_height;
pocket1.position.z = 21.5;
pocket1.position.x = 47;
var pocket2 = new Physijs.SphereMesh(new THREE.SphereGeometry(4, 15, 15), pocket_material, 0);
pocket2.position.y = p_height;
pocket2.position.z = -21.5;
pocket2.position.x = 47;
var pocket3 = new Physijs.SphereMesh(new THREE.SphereGeometry(4, 15, 15), pocket_material, 0);
pocket3.position.y = p_height;
pocket3.position.z = 24;
var pocket4 = new Physijs.SphereMesh(new THREE.SphereGeometry(4, 15, 15), pocket_material, 0);
pocket4.position.y = p_height;
pocket4.position.z = 21.5;
pocket4.position.x = -47;
var pocket5 = new Physijs.SphereMesh(new THREE.SphereGeometry(4, 15, 15), pocket_material, 0);
pocket5.position.y = p_height;
pocket5.position.z = -21.5;
pocket5.position.x = -47;
var pocket6 = new Physijs.SphereMesh(new THREE.SphereGeometry(4, 15, 15), pocket_material, 0);
pocket6.position.y = p_height;
pocket6.position.z = -24;
pocket.add(pocket1);
pocket.add(pocket2);
pocket.add(pocket3);
pocket.add(pocket4);
pocket.add(pocket5);
pocket.add(pocket6);
pocket.addEventListener('collision', function(other_object, relative_velocity, relative_rotation, contact_normal)
{
POCKETED = true;
removeBall(other_object);
});
pocket.visible = false;
ABWorld.scene.add(pocket);
ABWorld.render();
console.log("Resources loaded.");
resourcesLoaded = true;}
// ===================================================================================================================
// === Button Functions ==============================================================================================
// ===================================================================================================================
function decreasePowerMin(){
if (MIN_POWER > 1) {MIN_POWER -= 1;}
}
function increasePowerMin(){
if (MIN_POWER < MAX_POWER) {MIN_POWER += 1;}
}
function decreasePowerMax(){
if (MIN_POWER < MAX_POWER) {MAX_POWER -= 1;}
}
function increasePowerMax(){
if (MAX_POWER < 5) {MAX_POWER += 1;}
}
function selectBall(x)
{
BALL_CHOICE = x;
}
function setColor(x){
YOURCOLOR = x;
}
function pageChange(x){
PAGE_SELECT = x;
}
function cameraFlatDown(){
ABWorld.camera.position.set(0,100,0);
}
function cameraSomeCornerPocket(){
if (cameraPocketCounter % 4 === 0){
ABWorld.camera.position.set(50,50,30);
}
else if (cameraPocketCounter % 4 == 1){
ABWorld.camera.position.set(50,50,-30);
}
else if(cameraPocketCounter % 4 == 2){
ABWorld.camera.position.set(-50,50,-30);
}
else if(cameraPocketCounter % 4 == 3){
ABWorld.camera.position.set(-50,50, 30);
}
cameraPocketCounter = cameraPocketCounter + 1;
}
// ===================================================================================================================
// === Shot Calculations =============================================================================================
// ===================================================================================================================
function calculateShot()
{
if(validSetUp() === true){
CALCULATING = true;
initOptions();
prepareHit();
}
}
function prepareHit()
{
if (YOURCOLOR == "None"){
BALLS_TO_POT = 14;
}
else if (YOURCOLOR != "None"){
BALLS_TO_POT = colorCount(YOURCOLOR);
if (BALLS_TO_POT === 0){
BALLS_TO_POT = 1;
}
}
BALLS_ATTEMPTED = 0;
CURRENT_POWER = MIN_POWER;
if (toggledBasic === false){
for (var i in BALLS){
var x = BALLS[i].position.x;
var z = BALLS[i].position.z;
var name = BALLS[i].name;
BALL_LAYOUT.push([x, p_height + 0.5, z, BALL_COLORS_R[name]]);
}
}
hitBall();
}
function hitBall()
{
movFin = false;
MOVING = true;
ABWorld.scene.addEventListener("update", function(){
if (movementFinished()){
if (CALCULATED === false){
SCORE = calculateScore(YOURSCORE, OTHERSCORE, WHITE_POT, BLACK_POT);
//console.log("Score for this turn: " + SCORE + ".");
}
clearTable();
}
});
firstHit = true;
if (CALCULATED === false){
ANGLE = ballChoice();
}
cue = makeCue(ANGLE);
WHITE.applyCentralImpulse(ANGLE);
removeCue(cue);
}
function clearTable()
{
while (BALLS.length !== 0){
LIMIT[BALL_COLORS_R[BALLS[0].name]] += 1;
BALLS[0].name = "None";
BALLS[0].geometry.dispose();
BALLS[0].material.dispose();
ABWorld.scene.remove(BALLS[0]);
BALLS.splice(0, 1);
}
reset();
}
function reset()
{
BALL_COUNT = 0;
WHITE_POT = false;
BLACK_POT = false;
YOURSCORE = 0;
OTHERSCORE = 0;
FOUL = false;
if (toggledBasic === true){
YOURCOLOR = "None";
basicSetUp();
}
else{
for (var i in BALL_LAYOUT){
createBall(BALL_LAYOUT[i][0], BALL_LAYOUT[i][1], BALL_LAYOUT[i][2], BALL_LAYOUT[i][3]);
}
MOVING = false;
$("#simulate").css({"background-color" : "red" , "color" : "white", "padding" : "15px", "font-size" : "25px", "border-radius" : "10px", "font-weight" : "bold"});
if (CALCULATING === true && BALLS_TO_POT > BALLS_ATTEMPTED){
hitBall();
}
else if (CALCULATING === true && BALLS_TO_POT == BALLS_ATTEMPTED){
CALCULATING = false;
CALCULATED = true;
//console.log("Finished Calculations");
//console.log("Best Scores: ", BEST_SCORES);
initPostOptions();
}
}
}
function calculateScore(x, y, w, b)
{
var score = 50;
if ((FOUL === true || w === true) && y === 0){
score += (-8) + (x * 7);
}
else{
score += (-9 * y) + (x * 7);
}
if (b === true && (w === true || YOURCOLOR == "None" || LIMIT[BALL_COLORS_R[YOURCOLOR]] != 7)){
score = -1;
}
else if (b === true){
score = 100;
}
if (BEST_SCORES.length < 3){
BEST_SCORES.push([score, ANGLE, SAVED_POWER]);
}
else{
chooseBest(score, ANGLE, SAVED_POWER);
}
return(score);
}
function chooseBest(s, a, p)
{
var min = 0;
for (var i in BEST_SCORES){
if (BEST_SCORES[i][0] < BEST_SCORES[min][0]){
min = i;
}
}
if (BEST_SCORES[min][0] < s){
BEST_SCORES[min] = [s, a, p];
soundGood();
}
else{soundBad()}
}
function validSetUp()
{
if (LIMIT[2] + LIMIT[3] > 0){
errorSplash("Invalid Set Up! Black or white ball missing.");
return(false);
}
else if (YOURCOLOR == "None" && LIMIT[0] + LIMIT[1] + LIMIT[2] + LIMIT[3] > 0){
errorSplash("Invalid Set Up! Incorrect setting of your color, should be Yellow or Red.");
return(false);
}
else if ((YOURCOLOR == "Red" || YOURCOLOR == "Yellow") && LIMIT[0] + LIMIT[1] === 0){
errorSplash("Invalid Set Up! Incorrect setting of your color, should be None.");
return(false);
}
else{
return(true);
}
}
function colorCount(color)
{
var x = 0;
for (var i in BALLS){
if (BALLS[i].name == color){
x += 1;
}
}
return(x);
}
function makeCue(angle)
{
firstHit = true;
if (WHITE != -1){
pivot.position.x = WHITE.position.x;
pivot.position.y = WHITE.position.y;
pivot.position.z = WHITE.position.z;
var rotate = -(Math.atan((angle.z - WHITE.position.z)/(angle.x - WHITE.position.x)));
if((angle.x - WHITE.position.x) < 0){
if ((angle.z - WHITE.position.z) < 0){
rotate -= Math.PI;
}
else if ((angle.z - WHITE.position.z) > 0){
rotate += Math.PI;
}
else {rotate = Math.PI}
}
pivot.rotation.y = rotate;
ABWorld.scene.add(pivot);
return pivot;
}
}
function waiting(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function removeCue(object){
await waiting(2000);
object.geometry.dispose();
object.material.dispose();
ABWorld.scene.remove(object);
}
function isValid(ball){
if (YOURCOLOR == "None"){
if (ball.name == "Yellow" || ball.name == "Red"){
//console.log("Valid Selection");
return(true);
}
}
else if (ball.name == YOURCOLOR){
//console.log("Valid Selection");
return(true);
}
else if (ball.name == "Black" && LIMIT[BALL_COLORS_R[YOURCOLOR]] == 7){
return(true);
}
return(false);
}
function errorSplash(msg){
AB.newSplash ("<p align=\"center\">Error!</p><p align=\"center\"> "+ msg +"</p>");
$("#splashbutton").click (function()
{
AB.removeSplash(); // remove splash screen
soundClick();
splashClicked = true;
});
}
function ballChoice()
{
// choose a valid ball to calculate angle
var valid_balls = 0;
for (var i in BALLS){
if (isValid(BALLS[i])){
if (valid_balls == BALLS_ATTEMPTED){
var angle = pickAngle(BALLS[i]);
if (ANGLE_COUNT < 3){
ANGLE_COUNT += 1;
}
else if (ANGLE_COUNT == 3){
CURRENT_POWER += 1;
ANGLE_COUNT = 0;
}
if (CURRENT_POWER > MAX_POWER){
BALLS_ATTEMPTED += 1;
CURRENT_POWER = MIN_POWER;
}
return(angle);
}
valid_balls += 1;
}
}
}
function pickAngle(ball)
{
// calculate angle to hit ball
var length = (Math.sqrt(Math.pow((WHITE.position.x - ball.position.x), 2) + Math.pow((WHITE.position.z - ball.position.z), 2)));
SAVED_POWER = CURRENT_POWER;
angle = (new THREE.Vector3 ((BASE_POWER * CURRENT_POWER * (((ball.position.x - WHITE.position.x) / length) + ANGLES[ANGLE_COUNT][0])), 0, (BASE_POWER * CURRENT_POWER * (((ball.position.z - WHITE.position.z) / length) + ANGLES[ANGLE_COUNT][1]))));
return(angle);
}
function movementFinished()
{
if (firstHit === false && movFin === false){
var vel = 0;
for (var x in BALLS){
vel += BALLS[x].getAngularVelocity().length();
}
if (vel < 0.2){
//console.log("Movement Finished!");
movFin = true;
return(true);
}
return(false);
}
}
function simulateShot()
{
if (MOVING === false){
ANGLE = BEST_SCORES[SHOT_PICKED][1];
hitBall();
}
else {errorSplash("Wait for current simulation to end.");}
}
// ===================================================================================================================
// === Ball Creation =================================================================================================
// ===================================================================================================================
function basicSetUp()
{
if (BALL_COUNT === 0){
createBall(-30, p_height + 0.5, 0, 3); //white
createBall(30, p_height + 0.5, 0, 2); //black
createBall(23, p_height + 0.5, 0, 1); //red
createBall(26.5, p_height + 0.5, -2, 1); //red
createBall(30, p_height + 0.5, 4, 1); //red
createBall(33.5, p_height + 0.5, 2, 1); //red
createBall(33.5, p_height + 0.5, -6, 1); // red
createBall(37, p_height + 0.5, -4, 1); //red
createBall(37, p_height + 0.5, 8, 1); //red
createBall(26.5, p_height + 0.5, 2, 0); //yellow
createBall(30, p_height + 0.5, -4, 0); //yellow
createBall(33.5, p_height + 0.5, -2, 0); //yellow
createBall(33.5, p_height + 0.5, 6, 0); //yellow
createBall(37, p_height + 0.5, 0, 0); //yellow
createBall(37, p_height + 0.5, 4, 0); //yellow
createBall(37, p_height + 0.5, -8, 0); //yellow
MOVING = false;
}
if (CALCULATING === true && BALLS_TO_POT > BALLS_ATTEMPTED){
hitBall();
}
else if (CALCULATING === true && BALLS_TO_POT == BALLS_ATTEMPTED){
CALCULATING = false;
CALCULATED = true;
console.log("Finished Calculations");
console.log("Best Scores: ", BEST_SCORES);
initPostOptions();
}
}
function createBall(x, y, z, CURRENT_COLOR)
{
if ( resourcesLoaded && LIMIT[CURRENT_COLOR] !== 0 && splashClicked)
{
var ball;
// choose ball color
if (CURRENT_COLOR === 0){
ball = new Physijs.SphereMesh(ball_geometry, ball_material_0, BALL_MASS);
}
else if (CURRENT_COLOR == 1){
ball = new Physijs.SphereMesh(ball_geometry, ball_material_1, BALL_MASS);
}
else if (CURRENT_COLOR == 2){
ball = new Physijs.SphereMesh(ball_geometry, ball_material_2, BALL_MASS);
}
else{
ball = new Physijs.SphereMesh(ball_geometry, ball_material_3, BALL_MASS);
}
ball.name = BALL_COLORS[CURRENT_COLOR];
ball.collisions = 0;
ball.castShadow = true;
//ball.position.set(1, 40, 1);
ball.position.set(x, y + 2, z);
ball.addEventListener('collision', function(other_object, relative_velocity, relative_rotation, contact_normal)
{
if (other_object != GROUND){
var mainImpact = relative_velocity.y; // impact in direction of gravity
if (Math.abs(mainImpact) > HEAVYIMPACT) // main impact, not lesser ones as it settles
{
soundCollision();
}
}
if (ball == WHITE && other_object != GROUND){
if (firstHit === true){
if(other_object.name == YOURCOLOR || YOURCOLOR == "None"){
//console.log("Valid Hit");
}
else if (LIMIT[BALL_COLORS_R[YOURCOLOR]] == 7 && other_object.name == "Black"){
//console.log("Valid Hit");
}
else{
console.log("Invalid Hit");
FOUL = true;
}
firstHit = false;
}
}
});
BALLS.push(ball);
if (CURRENT_COLOR == 3){
WHITE = ball;
}
BALL_COUNT += 1;
ABWorld.scene.add(ball);
ball.setDamping(0.5, 0.5);
LIMIT[CURRENT_COLOR] -= 1;
}
}
function removeBall(ball)
{
var index = BALLS.indexOf(ball);
if (index > -1) {
BALLS.splice(index, 1);
}
if (POCKETED === true){
if (ball.name == YOURCOLOR){
console.log("Good Shot!");
YOURSCORE += 1;
}
else if (YOURCOLOR == "None" && (ball.name !== "Black" && ball.name !== "White")){
console.log("You are now " + ball.name + "s.");
YOURCOLOR = ball.name;
YOURSCORE += 1;
}
else if (ball.name == "Black"){
BLACK_POT = true;
}
else if (ball.name == "White"){
WHITE_POT = true;
console.log("Foul Shot.");
}
else{
console.log("Bad Shot :(");
OTHERSCORE += 1;
}
}
LIMIT[BALL_COLORS_R[ball.name]] += 1;
ball.name = "None";
ball.geometry.dispose();
ball.material.dispose();
ABWorld.scene.remove(ball);
}
// ===================================================================================================================
// === Keyboard & Mouse Control ======================================================================================
// ===================================================================================================================
var OURKEYS = [49, 50, 51, 52];
function ourKeys(event) {return(OURKEYS.includes(event.keyCode));}
function keyHandler(event)
{
if (! ABRun.runReady) {return true;} // not ready yet
// if not handling this key, send it to default:
if (! ourKeys(event)) {return true;}
// else handle it and prevent default:
if ( event.keyCode == 49 ) {selectBall(0);}
else if ( event.keyCode == 50 ) {selectBall(1);}
else if ( event.keyCode == 51 ) {selectBall(2);}
else if ( event.keyCode == 52 ) {selectBall(3);}
event.stopPropagation(); event.preventDefault(); return false;
}
var startX, startY;
var dragevents; // number of events in the current drag
function click(x, y)
{
var object = (ABWorld.hitsObjectPoint(x, y, GROUND)); // returns null if no hit
if (object !== null){
createBall(object.x, object.y, object.z, BALL_CHOICE);}
}
//for future drag functionality
function initTouch(x, y)
{
var object = (ABWorld.hitsObjectPoint(x, y, GROUND)); // returns null if no hit
if (object !== null){
createBall(object.x, object.y, object.z, BALL_CHOICE);}
}
function dummy(){
}
// ===================================================================================================================
// === User Interface ================================================================================================
// ===================================================================================================================
function initPreOptions()
{
$("#user_span1").html("<p align=\"center\">Page: <b>"+ PAGE_SELECT + "</b></p>");
$("#user_span2").html("<p align=\"center\"><button id='page1'>Page 1</button> <button id='page2'>Page 2</button></p>");
$("#user_span4").html(line4_1);
$("#user_span6").html(line6_1);
$("#user_span7").html("<p align=\"center\">The Camera Settings :</p>");
$("#user_span8").html(line6_3);
$("#user_span10").html("<p align=\"center\"><button id='calculateShot'>GO!</button></p>");
$(document).ready(function(){
//Button Functionality
$("#page1").click(function(){pageChange(1), soundClick();});
$("#page2").click(function(){pageChange(2), soundClick();});
$("#calculateShot").click(function(){calculateShot(),ABHandler.defaultTouch(), ABHandler.defaultMouse(), soundClick();});
$("#cameraFlatButton").click(function(){cameraFlatDown(), soundClick();});
$("#cameraCornerButton").click(function(){cameraSomeCornerPocket(), soundClick();});
//Button CSS
$("#page1").css({"background-color" : "#99ff33" , "border-radius" : "10px" , "padding" : "5px"});
$("#page2").css({"background-color" : "#99ff33" , "border-radius" : "10px" , "padding" : "5px"});
$("#calculateShot").css({"background-color" : "red" , "color" : "white", "padding" : "15px", "font-size" : "25px", "border-radius" : "10px", "font-weight" : "bold"});
$("#cameraFlatButton").css({"background-color" : "white" , "color" : "black" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#cameraCornerButton").css({"background-color" : "white" , "color" : "black" , "border-radius" : "10px" , "padding" : "10px 10px"});
});
}
function initOptions()
{
$("#user_span1").html("<p align=\"center\"><b>Calculating Table ...</b></p>");
$("#user_span4").html("<p align=\"center\">Camera</p>");
$("#user_span5").html(line6_3);
$("#user_span7").html("<p></p>");
$("#user_span8").html("<p></p>");
$("#user_span10").html("<p></p>");
$(document).ready(function(){
//Button Functionality
$("#cameraFlatButton").click(function(){cameraFlatDown(), soundClick();});
$("#cameraCornerButton").click(function(){cameraSomeCornerPocket(), soundClick();});
//Button CSS
$("#cameraFlatButton").css({"background-color" : "white" , "color" : "black" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#cameraCornerButton").css({"background-color" : "white" , "color" : "black" , "border-radius" : "10px" , "padding" : "10px 10px"});
});
}
function initPostOptions()
{
$("#user_span1").html("<p align=\"center\"><b>Finished Calculation</b></p>");
$("#user_span5").html("<p align=\"center\"><button id='show1'>1</button> <button id='show2'>2</button> <button id='show3'>3</button></p>");
$("#user_span6").html("<p align=\"center\"><button id='simulate'>Simulate Shot</button></p>");
$("#user_span7").html("<p align=\"center\">Camera</p>");
$("#user_span8").html(line6_3);
$("#user_span9").html("<p></p>");
$("#user_span10").html("<p></p>");
$(document).ready(function(){
//Button Functionality
$("#show1").click(function(){SHOT_PICKED = 0, soundClick();});
$("#show2").click(function(){SHOT_PICKED = 1, soundClick();});
$("#show3").click(function(){SHOT_PICKED = 2, soundClick();});
$("#simulate").click(function(){simulateShot(), soundClick(), $("#simulate").css({"background-color" : "#333333" , "color" : "#aaaaaa", "padding" : "15px", "font-size" : "25px", "border-radius" : "10px", "font-weight" : "bold"});});
$("#cameraFlatButton").click(function(){cameraFlatDown(), soundClick();});
$("#cameraCornerButton").click(function(){cameraSomeCornerPocket(), soundClick();});
//Button CSS
$("#show1").css({"background-color" : "black" , "color" : "white" , "padding" : "10px 20px", "font-size" : "16px", "border-radius" : "5px"});
$("#show2").css({"background-color" : "black" , "color" : "white" , "padding" : "10px 20px", "font-size" : "16px", "border-radius" : "5px"});
$("#show3").css({"background-color" : "black" , "color" : "white" , "padding" : "10px 20px", "font-size" : "16px", "border-radius" : "5px"});
$("#simulate").css({"background-color" : "red" , "color" : "white", "padding" : "15px", "font-size" : "25px", "border-radius" : "10px", "font-weight" : "bold"});
$("#cameraFlatButton").css({"background-color" : "white" , "color" : "black" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#cameraCornerButton").css({"background-color" : "white" , "color" : "black" , "border-radius" : "10px" , "padding" : "10px 10px"});
});
}
function updatePreHUD()
{
$("#user_span1").html("<p align=\"center\">Page: <b>"+ PAGE_SELECT + "</b></p>");
if (PAGE_SELECT == 1){
$("#user_span3").html("<p align=\"center\">Ball Selected: <b>"+ BALL_TYPE[BALL_CHOICE] + "</b></p>");
$("#user_span5").html("<p align=\"center\">The Colour you are playing as is set to: <b>" + YOURCOLOR + "</b></p>");
if (CURRENT_PAGE !== PAGE_SELECT){
$("#user_span4").html(line4_1);
$("#user_span6").html(line6_1);
$(document).ready(function(){
//Button Functionality
$("#yellowButton").click(function(){selectBall(0), soundClick();});
$("#redButton").click(function(){selectBall(1), soundClick();});
$("#blackButton").click(function(){selectBall(2), soundClick();});
$("#whiteButton").click(function(){selectBall(3), soundClick();});
$("#yourNButton").click(function(){setColor("None"), soundClick();});
$("#yourYButton").click(function(){setColor("Yellow"), soundClick();});
$("#yourRButton").click(function(){setColor("Red"), soundClick();});
//Button CSS
$("#yellowButton").css({"background-color" : "yellow" , "color" : "yellow" , "border-radius" : "30px" , "padding" : "10px 10px"});
$("#redButton").css({"background-color" : "red" , "color" : "red" , "border-radius" : "30px" , "padding" : "10px 10px"});
$("#blackButton").css({"background-color" : "black" , "color" : "black" , "border-radius" : "30px" , "padding" : "10px 10px"});
$("#whiteButton").css({"background-color" : "white" , "color" : "white" , "border-radius" : "30px" , "padding" : "10px 10px"});
$("#yourNButton").css({"background-color" : "#dddddd" , "color" : "#dddddd" , "border-radius" : "30px" , "padding" : "10px 10px"});
$("#yourYButton").css({"background-color" : "yellow" , "color" : "yellow" , "border-radius" : "30px" , "padding" : "10px 10px"});
$("#yourRButton").css({"background-color" : "red" , "color" : "red" , "border-radius" : "30px" , "padding" : "10px 10px"});
});
}
}
else if (PAGE_SELECT == 2){
$("#user_span3").html("<p align=\"center\">Toggle controls: <b>Camera " + CAMERA + "</b></p>");
$("#user_span5").html("<p align=\"center\">Power: <b>" + MIN_POWER + " to " + MAX_POWER + "</b></p>");
if (CURRENT_PAGE !== PAGE_SELECT){
$("#user_span4").html(line4_3);
$("#user_span6").html(line6_2);
$(document).ready(function(){
//Button Functionality
$("#gameButton").click(function(){myControls(), soundClick(), CAMERA = "Off";});
$("#cameraButton").click(function(){ABHandler.defaultTouch(), ABHandler.defaultMouse(), soundClick(), CAMERA = "On";});
$("#decreasePowerMinButton").click(function(){decreasePowerMin(), soundClick();});
$("#increasePowerMinButton").click(function(){increasePowerMin(), soundClick();});
$("#decreasePowerMaxButton").click(function(){decreasePowerMax(), soundClick();});
$("#increasePowerMaxButton").click(function(){increasePowerMax(), soundClick();});
//Button CSS
$("#gameButton").css({"background-color" : "black" , "color" : "white" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#cameraButton").css({"background-color" : "black" , "color" : "white" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#decreasePowerMinButton").css({"background-color" : "black" , "color" : "white" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#increasePowerMinButton").css({"background-color" : "black" , "color" : "white" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#decreasePowerMaxButton").css({"background-color" : "black" , "color" : "white" , "border-radius" : "10px" , "padding" : "10px 10px"});
$("#increasePowerMaxButton").css({"background-color" : "black" , "color" : "white" , "border-radius" : "10px" , "padding" : "10px 10px"});
});
}
}
CURRENT_PAGE = PAGE_SELECT;
}
function updateHUD(){
$("#user_span2").html("<p align=\"center\">The Colour you are playing as is set to: <b>" + YOURCOLOR + "</b>.</p>");
$("#user_span3").html("<p align=\"center\"></p>");
$("#user_span6").html("<p align=\"center\">Balls on Table: <b>" + BALLS.length + "</b>.</p>");
$("#user_span7").html("<p align=\"center\">Balls Calculated: <b>" + BALLS_ATTEMPTED + "</b> of <b>" + BALLS_TO_POT + "</b>.</p>");
}
function updatePostHUD(){
$("#user_span2").html("<p align=\"center\">Current Shot: <b>" + ((SHOT_PICKED) + 1) + "</b>.</p>");
$("#user_span3").html("<p align=\"center\">Shot Score: <b>" + BEST_SCORES[SHOT_PICKED][0] + "</b>.</p>");
$("#user_span4").html("<p align=\"center\">Shot Power: <b>" + BEST_SCORES[SHOT_PICKED][2] + "</b>.</p>");
}
// ===================================================================================================================
// === Ancient Brain Functions =======================================================================================
// ===================================================================================================================
this.newRun = function()
{
ABWorld.init3d(startRadius, maxRadius, SKYCOLOR); // sets up renderer, scene, camera
initPreOptions();
// can adjust renderer:
ABWorld.renderer.shadowMap.enabled = true;
// scene is Physijs.Scene, not THREE.Scene
// can adjust scene - change gravity from default:
ABWorld.scene.setGravity ( gravity );
loadResources(); // asynchronous file loads
// calls initScene() when all done
ABWorld.lookat.copy ( ABWorld.scene.position );
ABWorld.scene.simulate(); // Physics simulate - runs on independent timer to AB nextStep
// user actions
document.onkeydown = keyHandler;
};
function myControls()
{
ABHandler.initTouchDrag = initTouch;
ABHandler.touchDrag = dummy;
ABHandler.initMouseDrag = click;
ABHandler.mouseDrag = dummy;
}
this.nextStep = function() // not used
{
if (splashClicked === true && CONTROLLER === true){
CONTROLLER = true;
myControls();
}
if (splashClicked === true && toggleBasic === true){
basicSetUp();
toggleBasic = false;
toggledBasic = true;
}
if (CALCULATED === false && CALCULATING === false){
updatePreHUD();}
else if (CALCULATING === true){
updateHUD();
}
else{
updatePostHUD();
}
};
}
// ===================================================================================================================
// === Audio =========================================================================================================
// ===================================================================================================================
var colaudio1 = new Audio( SOUND_COLLISION );
var colaudio2 = new Audio( SOUND_COLLISION );
var colaudio3 = new Audio( SOUND_COLLISION );
var colaudio4 = new Audio( SOUND_COLLISION );
var colaudio5 = new Audio( SOUND_COLLISION );
var goodaudio1 = new Audio( SOUND_GOOD );
var goodaudio2 = new Audio( SOUND_GOOD );
var goodaudio3 = new Audio( SOUND_GOOD );
var goodaudio4 = new Audio( SOUND_GOOD );
var goodaudio5 = new Audio( SOUND_GOOD );
var badaudio1 = new Audio( SOUND_BAD );
var badaudio2 = new Audio( SOUND_BAD );
var badaudio3 = new Audio( SOUND_BAD );
var badaudio4 = new Audio( SOUND_BAD );
var badaudio5 = new Audio( SOUND_BAD );
var clkaudio1 = new Audio( SOUND_CLICK );
var clkaudio2 = new Audio( SOUND_CLICK );
var clkaudio3 = new Audio( SOUND_CLICK );
var clkaudio4 = new Audio( SOUND_CLICK );
var clkaudio5 = new Audio( SOUND_CLICK );
function soundCollision() // triggered by JS, not by user interaction
{
if ( ! AB.audioIsPlaying ( colaudio1 ) ) { colaudio1.play(); return; }
if ( ! AB.audioIsPlaying ( colaudio2 ) ) { colaudio2.play(); return; }
if ( ! AB.audioIsPlaying ( colaudio3 ) ) { colaudio3.play(); return; }
if ( ! AB.audioIsPlaying ( colaudio4 ) ) { colaudio4.play(); return; }
if ( ! AB.audioIsPlaying ( colaudio5 ) ) { colaudio5.play(); return; }
// else try to make a new one, local variable, without user interaction
// but this will not play on some browsers:
var a = new Audio( SOUND_COLLISION );
a.play();
}
function soundGood() // triggered by JS, not by user interaction
{
if ( ! AB.audioIsPlaying ( goodaudio1 ) ) { goodaudio1.play(); return; }
if ( ! AB.audioIsPlaying ( goodaudio2 ) ) { goodaudio2.play(); return; }
if ( ! AB.audioIsPlaying ( goodaudio3 ) ) { goodaudio3.play(); return; }
if ( ! AB.audioIsPlaying ( goodaudio4 ) ) { goodaudio4.play(); return; }
if ( ! AB.audioIsPlaying ( goodaudio5 ) ) { goodaudio5.play(); return; }
// else try to make a new one, local variable, without user interaction
// but this will not play on some browsers:
var a = new Audio( SOUND_GOOD );
a.play();
}
function soundBad() // triggered by JS, not by user interaction
{
if ( ! AB.audioIsPlaying ( badaudio1 ) ) { badaudio1.play(); return; }
if ( ! AB.audioIsPlaying ( badaudio2 ) ) { badaudio2.play(); return; }
if ( ! AB.audioIsPlaying ( badaudio3 ) ) { badaudio3.play(); return; }
if ( ! AB.audioIsPlaying ( badaudio4 ) ) { badaudio4.play(); return; }
if ( ! AB.audioIsPlaying ( badaudio5 ) ) { badaudio5.play(); return; }
// else try to make a new one, local variable, without user interaction
// but this will not play on some browsers:
var a = new Audio( SOUND_BAD );
a.play();
}
function soundClick() // triggered by JS, not by user interaction
{
if ( ! AB.audioIsPlaying ( clkaudio1 ) ) { clkaudio1.play(); return; }
if ( ! AB.audioIsPlaying ( clkaudio2 ) ) { clkaudio2.play(); return; }
if ( ! AB.audioIsPlaying ( clkaudio3 ) ) { clkaudio3.play(); return; }
if ( ! AB.audioIsPlaying ( clkaudio4 ) ) { clkaudio4.play(); return; }
if ( ! AB.audioIsPlaying ( clkaudio5 ) ) { clkaudio5.play(); return; }
// else try to make a new one, local variable, without user interaction
// but this will not play on some browsers:
var a = new Audio( SOUND_CLICK );
a.play();
}
// ===================================================================================================================
// === Splash Screens ================================================================================================
// ===================================================================================================================
AB.newSplash ("<p align=\"center\">Optional Start Settings</p><p align=\"center\">Set up balls in initial break arrangement</p><p align=\"center\"><button id='basicSetUp1'>Initial Break Set Up</button></p>");
$(document).ready(function(){
//Button Functionality
$("#basicSetUp1").click(function(){toggleBasic = true, soundClick(), $("#basicSetUp1").css({"background-color" : "green" , "color" : "white" , "padding" : "15px 30px", "font-size" : "16px", "border-radius" : "5px"});});
//Button CSS
$("#basicSetUp1").css({"background-color" : "black" , "color" : "white" , "padding" : "15px 30px", "font-size" : "16px", "border-radius" : "5px"});});
// when user clicks/touches button on splash screen, audio starts and run starts:
$("#splashbutton").click (function()
{
AB.removeSplash(); // remove splash screen
soundClick();
splashClicked = true;
});