123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- (function(exports){
- var LAYER_BOUNTY = 1000;
- var LAYERHEIGHT = 1;
- var DOWNVECTOR = new THREE.Vector3(0,-1,0);
- var UPVECTOR = new THREE.Vector3(0,1,0);
- var PALLETE = [0x03B5AA, 0x0A1128, 0xF2F6D0, 0x5F464B, 0xFCD0A1 ];
- var basicMaterial = new THREE.MeshPhongMaterial({
- specular: 0x030303,
- color : 0x00ff00,
- alphaTest: 0.9,
- shininess: 50,
- side: THREE.DoubleSide
- });
- var basicGeometry = new THREE.BoxGeometry(1,1,1);
- function GameBox(sizex, sizey, sizez){
- this.size = new THREE.Vector3(sizex,sizey,sizez);
- this.layers = [];
- for(var i=0;i<sizey;i++){
- var nlayer = new Layer(sizex,sizez);
- nlayer.position.copy(new THREE.Vector3(0,i,0));
- this.layers.push(nlayer);
- }
- this.droppables = [];
- this.moveVector = new THREE.Vector3(0,-1,0);
- this.platform = new THREE.Object3D();
- this.platform.position.copy(new THREE.Vector3(-this.size.x/2,1.501,-this.size.z/2));
- this.layerNode = new THREE.Object3D();
- for(var i = 0 ; i < this.layers.length; i ++ )
- this.layerNode.add(this.layers[i]);
- this.platform.add(this.layerNode);
- this.createFloor(0xf0f0f0);
- //init
- this._init();
- }
- GameBox.prototype._init = function(){
- this.moveVec = new THREE.Vector3(0,0,0);
- this.rmoveVec = new THREE.Vector3(0,0,0);
- this._axis = DOWNVECTOR;
- this._degrees = 0;
- this._oldAxis = DOWNVECTOR;
- this._oldDegrees = 0;
- this.toBeFree = [];
- this.score = 0;
- this.paused = false;
- this.finished = false;
- };
- GameBox.prototype.createFloor = function(color){
- var geometry = new THREE.BoxGeometry( this.size.x, 1, this.size.z);
- var texture = new THREE.TextureLoader().load( "textures/checker.png" );
- texture.wrapS = THREE.RepeatWrapping;
- texture.wrapT = THREE.RepeatWrapping;
- texture.repeat.set( this.size.x/2, this.size.z/2 );
- //var material = new THREE.MeshBasicMaterial( {color: color, side: THREE.DoubleSide, shading: THREE.FlatShading} );
- var material = new THREE.MeshPhongMaterial({
- specular: 0x030303,
- color : color,
- map : texture,
- alphaTest: 0.9,
- shininess: 2,
- side: THREE.DoubleSide
- });
- var plane = new THREE.Mesh( geometry, material );
- plane.receiveShadow = true;
- plane.position.x += this.size.x/2 - 0.5;
- plane.position.z += this.size.z/2 - 0.5;
- plane.position.y -= 1.0;
- this.platform.add(plane);
- // Add top light
- var l = new THREE.DirectionalLight( 0xffffff, 0.55 );
- l.castShadow = true;
- l.shadowCameraRight = 30;
- l.shadowCameraLeft = -30;
- l.shadowCameraTop = 30;
- l.shadowCameraBottom = -30;
- l.shadow.mapSize.width = 512;
- l.shadow.mapSize.height = 512;
- l.position.copy(new THREE.Vector3( 0 , 50, 0));
- l.castShadow = true;
- this.platform.add(l);
- };
-
- GameBox.prototype.init = function(scene){
- scene.add(this.platform);
- };
- GameBox.prototype.progress = function() {
- if(this.paused || this.finished)return;
- this.score += 5;
- this.free();
- this.checkLayers();
- for(var i = this.droppables.length-1 ; i >= 0 ; i-- )
- this.droppables[i].progress(DOWNVECTOR, this._axis,this._degrees);
- for(var i = 0 ; i < this.droppables.length ; i ++ ){
- var geometry = this.droppables[i].getGeometry();
- var flag = false;
- for(var j=0; j < geometry.length; j ++)
- if(this.checkCollision(geometry[j]))flag = true;
- if(flag){
- this.droppables[i].progress(UPVECTOR, this._oldAxis,this._oldDegrees);
- geometry = this.droppables[i].getGeometry();
- this.randomDrop();
- }
- for(var j=0; j < geometry.length; j ++){
- try{
- this.occupy(this.droppables[i].color, geometry[j], !flag);
- }
- catch(e){
- this.lost();
- return true;
- }
- }
- if(flag)
- this.droppables.splice( i, 1 );
- }
- return flag;
- };
-
- GameBox.prototype.progressToNext = function(){
- while(!this.progress()){}; // drop to floor
- };
- GameBox.prototype.randomDrop = function(){
- var shape = new SHAPESARRAY[parseInt(Math.random()*SHAPESARRAY.length - 0.0000001)](PALLETE[parseInt(Math.random()*12345) % 5])
- this.drop(shape);
- };
- GameBox.prototype.checkLayers = function(){
- var flag = false;
- for(var i = this.layers.length-1; i >= 0; i --) {
- if(this.layers[i].isComplete()){
- flag = true;
- this.layers.splice(i,1);
- this.layers.push(new Layer(this.size.x,this.size.z));
- this.score += LAYER_BOUNTY;
- }
- }
- if(flag){
- this.layerNode.children.length = 0;
- for(var i = 0 ; i < this.layers.length && flag; i ++){
- this.layers[i].position.copy(new THREE.Vector3(0,i,0));
- this.layerNode.add(this.layers[i]);
- }
- }
- };
- GameBox.prototype.occupy = function(color, vec, temp){
- try{
- this.getQuanto(vec.x,vec.y,vec.z).occupy(color, temp);
- }
- catch(e){}
- if(temp){
- this.toBeFree.push(vec);
- }
- };
- GameBox.prototype.drop = function(shape) {
- var rpos = new THREE.Vector3( parseInt(Math.random()*(this.size.x-4))+2 ,(this.layers.length-2) * LAYERHEIGHT , parseInt(Math.random()*(this.size.z-4))+2);
- shape.position.copy(rpos);
- var geometry = shape.getGeometry();
- for(var j=0; j < geometry.length; j ++)
- if(this.checkCollision(geometry[j]))this.lost();
- this.droppables.push(shape);
- };
- GameBox.prototype.move = function(x,z, axis, degrees) {
- this.moveVec.set(x,0,z);
- this.rmoveVec.set(-x,0,-z);
- this._oldAxis = this._axis;
- this._oldDegrees = this._degrees;
- this._axis = axis;
- this._degrees = degrees;
- this.free();
- for(var i = this.droppables.length-1 ; i >= 0 ; i-- )
- this.droppables[i].progress(this.moveVec , axis, degrees);
- for(var i = 0 ; i < this.droppables.length ; i ++ ){
- var geometry = this.droppables[i].getGeometry();
- var flag = false;
- for(var j=0; j < geometry.length; j ++)
- if(this.checkCollision(geometry[j]))flag = true;
- if(flag){
- this.droppables[i].progress(this.rmoveVec , this._oldAxis, this._oldDegrees);
- this._axis = this._oldAxis;
- this._degrees = this._oldDegrees;
- geometry = this.droppables[i].getGeometry();
- }
- for(var j=0; j < geometry.length; j ++)
- this.occupy(this.droppables[i].color, geometry[j], true);
- }
- };
- GameBox.prototype.free = function(){
- // free old
- for(var i = 0 ; i < this.toBeFree.length; i ++)
- this.getQuanto(this.toBeFree[i]).free();
- this.toBeFree = [];
- };
- GameBox.prototype.checkCollision = function(x,y,z){
- if(typeof x == "object"){z = x.z;y=x.y;x=x.x;}
- if(x<0 || y < 0 || z < 0)return true;
- if(x >= this.size.x || z >= this.size.z)
- return true;
- if(y >= this.size.y)
- return this.lost();
- return this.getQuanto(x,y,z).occupied;
- };
- GameBox.prototype.getSpeed = function(){
- return 0.55 - 0.02 * parseInt(this.score / 10000);
- };
- GameBox.prototype.lost = function(){
- this.paused = true;
- this.finished = true;
- return -1;
- };
- GameBox.prototype.restart = function(){
- this.paused = false;
- this.finished = false;
- for(var x = 0; x < this.size.x; x++)
- for(var y = 0; y < this.size.y; y++)
- for(var z = 0; z < this.size.z; z++)
- this.getQuanto(x,y,z).free();
- this.droppables = [];
- this._init();
- this.drop(new window.Shapes.Box(0x00ff20));
- return;
- };
- GameBox.prototype.getQuanto = function(x,y,z){
- if(typeof x == "object"){z = x.z;y=x.y;x=x.x;}
- if(x<0 || y < 0 || z < 0)return true;
- if(x >= this.size.x || y >= this.size.y || z >= this.size.z)return true;
- return this.layers[y].points[x][z];
- };
- // GameBox.prototype.occupyLayer = function(x) {
- // for(var i = 0;i<this.size.x;i++)
- // this.layers[x].points[i][4].occupy(0x00ff00);
- // this.layers[x].points[5][4].free();
- // };
- // LAYER /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////
- function Layer(x,y){
- THREE.Object3D.apply(this);
- this.points = [];
- for( var i = 0; i < x ; i ++){
- this.points[i] = [];
- for ( var j = 0; j < y ; j ++){
- this.points[i][j] = new Quanto();
- this.points[i][j].position.copy(new THREE.Vector3(i,0,j));
- this.add(this.points[i][j]);
- }
- }
- };
- Layer.prototype = Object.create(THREE.Object3D.prototype);
- Layer.prototype.constructor = Layer;
-
- Layer.prototype.isComplete = function(){
- for(var i = 0; i < this.points.length; i ++)
- for(var j = 0;j < this.points[i].length; j++)
- if(!this.points[i][j].occupied)return false;
- return true;
- }
- // Quanto /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////
- function Quanto(){
- THREE.Object3D.apply(this);
- this.occupied = false;
- };
- Quanto.prototype = Object.create(THREE.Object3D.prototype);
- Quanto.prototype.constructor = Quanto;
- Quanto.prototype.occupy = function(color , temp){
- if(this.occupied)
- throw new Error("Quanto is already occupied!!!");
- if(!this.cube){
- var geometry = basicGeometry.clone();
- //var material = new THREE.MeshBasicMaterial( {color: color} );
- var material = basicMaterial.clone();
- this.cube = new THREE.Mesh( geometry, material );
- this.cube.castShadow = true;
- this.cube.receiveShadow = true;
- }
- this.cube.material.color.set(color);
- this.add( this.cube );
- this.occupied = true;
- if(temp)this.occupied = false;
- };
- Quanto.prototype.free = function(){
- this.children.length = 0;
- this.occupied = false;
- }
- Quanto.prototype.toBoxCoords = function(Layer){
- return this.position + Layer;
- }
-
- // Shape /////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////
- function Shape(color){
- THREE.Object3D.call(this);
- this.position.copy(new THREE.Vector3(0,0,0));
- this.array = [this.position.clone()]; // Array of positions specifying the shape
- this.color = color;
- this.qrot = new THREE.Quaternion();
- this.qrot.setFromAxisAngle(UPVECTOR, 0);
- };
- Shape.prototype = Object.create(THREE.Object3D.prototype);
- Shape.prototype.constructor = Shape;
- Shape.prototype.progress = function(moveVector, axis, degrees ){
- this.position.add(moveVector);
- this.qrot.setFromAxisAngle( axis, degrees);
- };
- Shape.prototype.getGeometry = function(){
- var narr = [];
- for(var i=0;i<this.array.length;i++){
- narr[i] = this.array[i].clone().applyQuaternion(this.qrot);
- narr[i].add(this.position);
- narr[i].x = parseInt(narr[i].x + sign(narr[i].x)*0.5);
- narr[i].y = parseInt(narr[i].y + sign(narr[i].y)*0.5);
- narr[i].z = parseInt(narr[i].z + sign(narr[i].z)*0.5);
- }
- return narr;
- };
- window.sign = function(x) { return x ? x < 0 ? -1 : 1 : 0; };
- ////////////////////////////////////////////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////// SHAPES //////////////////////////////////////////
- function Cross(color){
- Shape.call(this);
- this.position = new THREE.Vector3(0,0,0);
- this.array = [new THREE.Vector3(0,0,0),
- new THREE.Vector3(1,0,0),
- new THREE.Vector3(0,1,0),
- new THREE.Vector3(0,0,1),
- new THREE.Vector3(-1,0,0),
- new THREE.Vector3(0,-1,0)
- ]; // Array of positions specifying the shape
- this.color = color;
- };
- Cross.prototype = Object.create(Shape.prototype);
- Cross.prototype.constructor = Cross;
- function Line(color){
- Shape.call(this);
- this.position = new THREE.Vector3(0,0,0);
- this.array = [new THREE.Vector3(0,0,0),
- new THREE.Vector3(0,0,1),
- new THREE.Vector3(0,0,-1)
- ]; // Array of positions specifying the shape
- this.color = color;
- };
- Line.prototype = Object.create(Shape.prototype);
- Line.prototype.constructor = Line;
- function Light(color){
- Shape.call(this);
- this.position = new THREE.Vector3(0,0,0);
- this.array = [new THREE.Vector3(0,0,0),
- new THREE.Vector3(0,0,1)
- ]; // Array of positions specifying the shape
- this.color = color;
- };
- Light.prototype = Object.create(Shape.prototype);
- Light.prototype.constructor = Light;
- function Corner(color){
- Shape.call(this);
- this.position = new THREE.Vector3(0,0,0);
- this.array = [new THREE.Vector3(0,0,0),
- new THREE.Vector3(0,0,1),
- new THREE.Vector3(1,0,0),
- new THREE.Vector3(-1,0,0)
- ]; // Array of positions specifying the shape
- this.color = color;
- };
- Corner.prototype = Object.create(Shape.prototype);
- Corner.prototype.constructor = Corner;
- function Axis(color){
- Shape.call(this);
- this.position = new THREE.Vector3(0,0,0);
- this.array = [new THREE.Vector3(0,0,0),
- new THREE.Vector3(1,0,0),
- new THREE.Vector3(0,1,0),
- new THREE.Vector3(0,0,1)
- ]; // Array of positions specifying the shape
- this.color = color;
- };
- Axis.prototype = Object.create(Shape.prototype);
- Axis.prototype.constructor = Axis;
- var SHAPESARRAY = [Line, Shape, Shape, Line, Light, Light, Axis, Corner];
- exports.Shapes = {
- Cross : Cross,
- Line : Line,
- Box : Shape,
- Axis : Axis,
- Corner: Corner,
- Light : Light
- };
- exports.GameBox = GameBox;
- })(window);
|