mirror of
https://github.com/YunoHost-Apps/Cubiks-2048_ynh.git
synced 2024-09-03 18:25:55 +02:00
499 lines
14 KiB
JavaScript
499 lines
14 KiB
JavaScript
function createcoord() {
|
|
this.x = 0;
|
|
this.y = 0;
|
|
this.z = 0;
|
|
};
|
|
|
|
function GAME(size) {
|
|
this.game_size = size;
|
|
this.cube_count = size * size * size;
|
|
this.filled_cubes = 0;
|
|
this.cube_array = {};
|
|
|
|
// Initialize the array .
|
|
|
|
for (var i = 0 ; i < this.cube_count; i++) {
|
|
this.cube_array[i] = 0;
|
|
}
|
|
|
|
this.gravity = new threeD_vector();
|
|
this.coord = new createcoord();
|
|
|
|
this.removal_queue = [];
|
|
this.premerges = [];
|
|
this.five_one_two_anims = {};
|
|
|
|
this.add_random_cube( 2 );
|
|
this.shift_cubes();
|
|
|
|
this.showing_view = false;
|
|
};
|
|
|
|
GAME.prototype.create_random_number = function (limit) {
|
|
return Math.floor(Math.random() * 100) % limit;
|
|
};
|
|
|
|
GAME.prototype.index_to_ijk = function ( rand )
|
|
{
|
|
coord = new createcoord();
|
|
coord.z = Math.floor(rand / (this.game_size * this.game_size)); // z level
|
|
rand = rand % (this.game_size * this.game_size); // remaining in level
|
|
|
|
coord.y = Math.floor(rand / this.game_size);
|
|
coord.x = rand % this.game_size;
|
|
return coord;
|
|
};
|
|
|
|
GAME.prototype.get_coord = function (rand, coord) {
|
|
var coord = this.index_to_ijk(rand);
|
|
coord.x = Math.floor(coord.x - Math.floor(this.game_size / 2));
|
|
coord.y = Math.floor(coord.y - Math.floor(this.game_size / 2));
|
|
coord.z = Math.floor(coord.z - Math.floor(this.game_size / 2));
|
|
|
|
coord.x *= (100 / this.game_size);
|
|
coord.y *= (100/ this.game_size);
|
|
coord.z *= (100 / this.game_size);
|
|
|
|
return coord;
|
|
};
|
|
|
|
GAME.prototype.coord_to_index = function( i, j, k ){
|
|
var numb = 0;
|
|
numb += this.game_size * this.game_size * k;
|
|
numb += j * this.game_size;
|
|
numb += i;
|
|
|
|
return numb;
|
|
};
|
|
|
|
GAME.prototype.add_random_cube = function ( count ) {
|
|
|
|
if (count == 0)
|
|
{
|
|
while (this.premerges.length)
|
|
this.premerges.pop();
|
|
|
|
return;
|
|
}
|
|
|
|
if( this.filled_cubes == this.cube_count )
|
|
return;
|
|
|
|
var rand = this.create_random_number(this.cube_count);
|
|
|
|
while (this.cube_array[rand] != 0 ) {
|
|
rand++;
|
|
if (rand == this.cube_count)
|
|
rand = 0;
|
|
}
|
|
|
|
this.coord = this.get_coord( rand );
|
|
|
|
var cube = create_inner_cube(33);
|
|
cube.position.set(this.coord.x, this.coord.y, this.coord.z);
|
|
cube.scale = { x: 0.0, y: 0.0, z: 0.0 };
|
|
var scaling = 1.0;
|
|
new TWEEN.Tween(cube.scale).to({ x: scaling, y: scaling, z: scaling }, 300).delay(400).start();
|
|
new TWEEN.Tween(cube.material).to({ opacity:1.0},300).delay(400).start();
|
|
cube_group.add(cube);
|
|
this.cube_array[rand] = cube;
|
|
|
|
this.filled_cubes++;
|
|
var ijk = this.index_to_ijk(rand);
|
|
this.sift_cube( ijk.x, ijk.y, ijk.z, this.gravity.direction );
|
|
this.add_random_cube(--count);
|
|
};
|
|
|
|
function get_map_id( map )
|
|
{
|
|
var underscore_idx = map.sourceFile.indexOf("_");
|
|
var dot_idx = map.sourceFile.lastIndexOf(".");
|
|
var index = map.sourceFile.substring(++underscore_idx, dot_idx);
|
|
return parseInt(index);
|
|
}
|
|
|
|
function next_map(map) {
|
|
var index = get_map_id( map );
|
|
return index + index;
|
|
};
|
|
|
|
GAME.prototype.is_in_bound = function( i2, j2 , k2 ){
|
|
if( i2 < 0 || i2 >= this.game_size)
|
|
return false;
|
|
|
|
if( j2 < 0 || j2 >= this.game_size)
|
|
return false;
|
|
|
|
if( k2 < 0 || k2 >= this.game_size)
|
|
return false;
|
|
|
|
return true;
|
|
};
|
|
|
|
GAME.prototype.get_512_and_above_count = function () {
|
|
var count = 0;
|
|
|
|
for (var i = 0; i < this.cube_count; i++) {
|
|
if( this.cube_array[i] != 0 )
|
|
if (get_map_id(this.cube_array[i].material.map) >= 512)
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
};
|
|
|
|
GAME.prototype.do_texture_events = function (index, index2, i2, j2, k2) {
|
|
var next_texture = this.cube_array[index].material.map;
|
|
|
|
// Win!
|
|
if (next_texture == textures[2048]) {
|
|
TWEEN.removeAll();
|
|
this.view_sides( true );
|
|
return true;
|
|
}
|
|
// Almost there!
|
|
else if (next_texture == textures[512]) {
|
|
|
|
var go = new TWEEN.Tween(this.cube_array[index].scale)
|
|
.to({ x: 1.2, y: 1.2, z: 1.2 }, 500)
|
|
.easing(TWEEN.Easing.Sinusoidal.In)
|
|
.start();
|
|
|
|
var back = new TWEEN.Tween(this.cube_array[index].scale)
|
|
.to({ x: 1.0, y: 1.0, z: 1.0 }, 500)
|
|
.easing(TWEEN.Easing.Sinusoidal.In);
|
|
|
|
go.chain(back);
|
|
back.chain(go);
|
|
|
|
// Record these for future..
|
|
|
|
this.five_one_two_anims[ this.cube_array[index].uuid ] = go;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
GAME.prototype.merge_cubes = function(last_index)
|
|
{
|
|
// Remove from 512 array as well
|
|
|
|
if (this.five_one_two_anims[this.cube_array[last_index].uuid ] != undefined) {
|
|
this.five_one_two_anims[this.cube_array[last_index].uuid].stop();
|
|
}
|
|
|
|
// Cube to be removed expands a little.
|
|
this.removal_queue.push(this.cube_array[last_index]);
|
|
this.cube_array[last_index].transparent = false;
|
|
this.cube_array[last_index] = 0;
|
|
this.filled_cubes--;
|
|
|
|
|
|
var length = 200;
|
|
var tween = new TWEEN.Tween(this.removal_queue[0].scale).
|
|
to({ x: 1.3, y: 1.3, z: 1.3 }, length).
|
|
easing(TWEEN.Easing.Sinusoidal.In)
|
|
.start();
|
|
|
|
var tween2 = new TWEEN.Tween(this.removal_queue[0].scale).
|
|
to({ x: 1.0, y: 1.0, z: 1.0 }, length/2).
|
|
easing(TWEEN.Easing.Sinusoidal.In)
|
|
.onComplete(function () {
|
|
|
|
// Remove from removal queue of settles..
|
|
|
|
var removal = CUBE2048.removal_queue.shift();
|
|
cube_group.remove(removal);
|
|
delete removal;
|
|
});
|
|
|
|
tween.chain(tween2);
|
|
};
|
|
|
|
GAME.prototype.is_premerged = function ( cube ) {
|
|
|
|
for (var i = 0; i < this.premerges.length ; i++) {
|
|
if (this.premerges[i] == cube)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
|
|
var counter = 0;
|
|
GAME.prototype.sift_cube = function ( i, j, k, direction ) {
|
|
|
|
var start_index = this.coord_to_index(i, j, k)
|
|
|
|
this.coord = this.get_coord( start_index );
|
|
|
|
// No cube at this location.
|
|
if (this.cube_array[start_index] == 0)
|
|
return false;
|
|
|
|
var i2 = i + direction.x;
|
|
var j2 = j + direction.y;
|
|
var k2 = k + direction.z;
|
|
var last_index = this.coord_to_index(i2, j2, k2);
|
|
|
|
while( this.is_in_bound( i2, j2, k2) && (this.cube_array[last_index] == 0) )
|
|
{
|
|
i2 += direction.x;
|
|
j2 += direction.y;
|
|
k2 += direction.z;
|
|
|
|
last_index = this.coord_to_index(i2, j2, k2);
|
|
}
|
|
|
|
// Either we are out of bound or we are filled..
|
|
|
|
if( this.is_in_bound( i2, j2, k2) )
|
|
{
|
|
// We found an existing cube. Is it the same texture?
|
|
// If this was from a previous merge.skip..
|
|
|
|
if ( !this.is_premerged(this.cube_array[last_index])
|
|
&& (this.cube_array[start_index] != 0)
|
|
&& (this.cube_array[last_index] != 0)
|
|
&& (this.cube_array[start_index].material.map == this.cube_array[last_index].material.map))
|
|
{
|
|
this.merge_cubes( last_index );
|
|
var next_text = next_map( this.cube_array[start_index].material.map );
|
|
//console.log("Merging " + start_index + " with " + last_index + " New texture : " + next_text);
|
|
|
|
this.cube_array[start_index].material.map = textures[next_text];
|
|
|
|
// Dont merge on this again.
|
|
this.premerges.push(this.cube_array[start_index]);
|
|
|
|
if ( this.do_texture_events(start_index, last_index, i2, j2, k2) )
|
|
return true;
|
|
}
|
|
else{
|
|
// Move to the next free block.
|
|
i2 -= direction.x;
|
|
j2 -= direction.y;
|
|
k2 -= direction.z;
|
|
}
|
|
}
|
|
else{
|
|
// Move to the next free block.
|
|
i2 -= direction.x;
|
|
j2 -= direction.y;
|
|
k2 -= direction.z;
|
|
}
|
|
|
|
start_index = this.coord_to_index( i, j, k );
|
|
last_index = this.coord_to_index( i2, j2, k2 );
|
|
|
|
|
|
if (start_index == last_index)
|
|
return false;
|
|
|
|
var start_coord = new createcoord();
|
|
var last_coord = new createcoord();
|
|
|
|
var start_coord = this.get_coord( start_index );
|
|
var last_coord = this.get_coord( last_index );
|
|
|
|
//console.log("Final coord : \t" + last_coord.x + "\t " + last_coord.y+ "\t " + last_coord.z);
|
|
|
|
this.settled = false;
|
|
new TWEEN.Tween(this.cube_array[start_index].position)
|
|
.to({ x: last_coord.x, y: last_coord.y, z: last_coord.z }, 600)
|
|
.easing(TWEEN.Easing.Bounce.Out)
|
|
.onComplete( function (){ CUBE2048.settled = true;} )
|
|
.start();
|
|
|
|
this.cube_array[last_index] = this.cube_array[start_index];
|
|
this.cube_array[start_index] = 0;
|
|
|
|
return true;
|
|
};
|
|
|
|
GAME.prototype.shift_cubes = function () {
|
|
var shifted = false;
|
|
if (this.gravity.direction.x != 0) {
|
|
var start = this.gravity.direction.x > 0 ? this.game_size-1 : 0;
|
|
var end = this.gravity.direction.x > 0 ? -1 : this.game_size;
|
|
|
|
start -= this.gravity.direction.x;
|
|
|
|
for (var i = start; i != end ; i -= this.gravity.direction.x) {
|
|
for (var j = 0 ; j < this.game_size; j++) {
|
|
for (var k = 0; k < this.game_size; k++) {
|
|
shifted |= this.sift_cube(i, j, k, this.gravity.direction);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
else if (this.gravity.direction.y != 0)
|
|
{
|
|
var start = this.gravity.direction.y > 0 ? this.game_size-1 : 0;
|
|
var end = this.gravity.direction.y > 0 ? -1 : this.game_size;
|
|
start -= this.gravity.direction.y;
|
|
|
|
for (var j = start; j != end ; j -= this.gravity.direction.y) {
|
|
for (var i = 0 ; i < this.game_size; i++) {
|
|
for (var k = 0; k < this.game_size; k++) {
|
|
shifted |= this.sift_cube(i, j, k, this.gravity.direction);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.gravity.direction.z != 0) {
|
|
var start = this.gravity.direction.z > 0 ? this.game_size-1 : 0;
|
|
var end = this.gravity.direction.z > 0 ? -1 : this.game_size;
|
|
start -= this.gravity.direction.z;
|
|
for (var k = start; k != end ; k -= this.gravity.direction.z) {
|
|
for (var i = 0 ; i < this.game_size; i++) {
|
|
for (var j = 0; j < this.game_size; j++) {
|
|
shifted |= this.sift_cube(i, j, k, this.gravity.direction);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return shifted;
|
|
};
|
|
|
|
GAME.prototype.translate = function (i, j, k, direction) {
|
|
var start_index = this.coord_to_index(i, j, k);
|
|
var coord = this.get_coord(start_index, coord);
|
|
if (this.cube_array[start_index] != 0) {
|
|
new TWEEN.Tween(this.cube_array[start_index].position)
|
|
.to({
|
|
x: coord.x + (121 * direction.x),
|
|
y: coord.y + (121 * direction.y),
|
|
z: coord.z + (121 * direction.z)
|
|
}, 100)
|
|
.start();
|
|
}
|
|
};
|
|
|
|
GAME.prototype.view_sides = function ( is_win ) {
|
|
|
|
if (TWEEN.getAll().length > this.get_512_and_above_count())
|
|
return;
|
|
|
|
if (this.showing_view)
|
|
return;
|
|
|
|
var right = this.gravity.right();
|
|
var left = new THREE.Vector3(0, 0, 0);
|
|
left.copy( right );
|
|
left.negate();
|
|
|
|
var dirs = [];
|
|
dirs.push( left );
|
|
dirs.push( new THREE.Vector3(0, 0, 0) );
|
|
dirs.push( right );
|
|
|
|
if (this.gravity.direction.x != 0) {
|
|
var start = this.gravity.direction.x > 0 ? this.game_size - 1 : 0;
|
|
var end = this.gravity.direction.x > 0 ? -1 : this.game_size;
|
|
|
|
for (var i = start; i != end ; i -= this.gravity.direction.x) {
|
|
for (var j = 0 ; j < this.game_size; j++) {
|
|
for (var k = 0; k < this.game_size; k++) {
|
|
this.translate(i, j, k, dirs[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
else if (this.gravity.direction.y != 0) {
|
|
var start = this.gravity.direction.y > 0 ? this.game_size - 1 : 0;
|
|
var end = this.gravity.direction.y > 0 ? -1 : this.game_size;
|
|
for (var j = start; j != end ; j -= this.gravity.direction.y) {
|
|
for (var i = 0 ; i < this.game_size; i++) {
|
|
for (var k = 0; k < this.game_size; k++) {
|
|
this.translate(i, j, k, dirs[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
else if (this.gravity.direction.z != 0) {
|
|
var start = this.gravity.direction.z > 0 ? this.game_size - 1 : 0;
|
|
var end = this.gravity.direction.z > 0 ? -1 : this.game_size;
|
|
for (var k = start; k != end ; k -= this.gravity.direction.z) {
|
|
for (var i = 0 ; i < this.game_size; i++) {
|
|
for (var j = 0; j < this.game_size; j++) {
|
|
this.translate(i, j, k, dirs[k]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_win) {
|
|
new TWEEN.Tween(camera.position)
|
|
.to({
|
|
x: camera.position.x,
|
|
y: camera.position.y + 100,
|
|
z: camera.position.z
|
|
}, 150)
|
|
.onUpdate(function () {
|
|
camera.lookAt(new THREE.Vector3(50, 50, 0));
|
|
})
|
|
.delay( 2000 )
|
|
.onComplete(function () {
|
|
renderer.render(scene, camera);
|
|
alert(" Did you just win? !!");
|
|
release('Yes you did! You won! Yay!! :) ');
|
|
})
|
|
.start();
|
|
}
|
|
else {
|
|
new TWEEN.Tween(camera.position)
|
|
.to({
|
|
x: camera.position.x,
|
|
y: camera.position.y + 100,
|
|
z: camera.position.z
|
|
}, 150)
|
|
.onUpdate(function () {
|
|
camera.lookAt(new THREE.Vector3(50, 50, 0));
|
|
})
|
|
.start();
|
|
}
|
|
|
|
|
|
this.showing_view = true;
|
|
};
|
|
|
|
GAME.prototype.reset_positions = function()
|
|
{
|
|
|
|
if (!this.showing_view)
|
|
return;
|
|
|
|
for( var i = 0 ; i < this.cube_count ; i ++ )
|
|
{
|
|
if (this.cube_array[i] != 0) {
|
|
var coord = this.get_coord( i );
|
|
new TWEEN.Tween(this.cube_array[i].position)
|
|
.to({ x: coord.x, y: coord.y, z: coord.z }, 100)
|
|
.start();
|
|
}
|
|
}
|
|
|
|
new TWEEN.Tween(camera.position)
|
|
.to({
|
|
x: 50,
|
|
y: dist/5,
|
|
z: dist/6
|
|
},100)
|
|
.onUpdate(function () {
|
|
camera.lookAt(new THREE.Vector3(50, 50, 0));
|
|
})
|
|
.start();
|
|
|
|
this.showing_view = false;
|
|
|
|
}
|
|
|