// // playChess.js // examples // // Created by Clement Brisset on 11/08/2014 // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html (function() { this.NUM_TILES = 10; ChessGame = { KING: 0, QUEEN: 1, BISHOP: 2, KNIGHT: 3, ROOK: 4, PAWN: 5 } this.entityID = null; this.boardID = null; this.sound = null; this.boardProperties = null; this.pieceProperties = null; this.startingTile; this.grabs = 0; // Loads the drop sound this.loadSound = function() { this.sound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/clement/production/chess/ChessPieceSound.wav"); } // Play drop sound this.playSound = function() { if (this.sound && this.sound.downloaded) { Audio.playSound(this.sound, { position: this.pieceProperties.position, volume: 1.0 }); } } this.pullProperties = function() { this.pieceProperties = Entities.getEntityProperties(this.entityID); this.boardProperties = Entities.getEntityProperties(this.boardID); } // Returns whether pos is inside the grid or not this.isOutsideGrid = function(pos) { return !(pos.i > -5 && pos.j > -5 && pos.i < 4 && pos.j < 4); } // Returns the tile coordinate this.getIndexPosition = function(position) { var relative = Vec3.subtract(position, this.boardProperties.position); relative = Vec3.multiplyQbyV(Quat.inverse(this.boardProperties.rotation), relative); var tileSize = this.boardProperties.dimensions.x / this.NUM_TILES; var pos = { i: Math.floor(relative.x / tileSize), j: Math.floor(relative.z / tileSize) }; var yStart = this.boardProperties.dimensions.y / 2.0 - tileSize / 2.0; var yEnd = this.boardProperties.dimensions.y / 2.0 + tileSize; if (relative.y < yStart || relative.y > yEnd || this.isOutsideGrid(pos)) { // Simulate out of board position var isWhite = (this.pieceProperties.textures === ""); if (isWhite) { return { i: 5, j: -1 }; } else { return { i: -6, j: 0 }; } } return pos; } // Returns the world position this.getAbsolutePosition = function(pos) { var position = this.tilePosition(pos.i, pos.j); return Vec3.sum(this.boardProperties.position, Vec3.multiplyQbyV(this.boardProperties.rotation, position)); } this.tilePosition = function(i, j) { var CENTER_OFFSET = 0.5; var tileSize = this.boardProperties.dimensions.x / this.NUM_TILES; var relativePosition = { x: (i + CENTER_OFFSET) * tileSize, y: this.boardProperties.dimensions.y / 2.0, z: (j + CENTER_OFFSET) * tileSize }; return relativePosition; } // Snap piece to the center of the tile it is on this.snapToGrid = function() { var pos = this.getIndexPosition(this.pieceProperties.position); var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos); var finalRot = this.boardProperties.rotation; if (this.pieceProperties.textures === "") { finalRot = Quat.multiply(finalRot, Quat.fromPitchYawRollDegrees(0, 180, 0)); } Entities.editEntity(this.entityID, { position: finalPos, rotation: finalRot }); } this.moveDeadPiece = function() { var tileSize = this.boardProperties.dimensions.x / this.NUM_TILES; var myPos = this.getIndexPosition(this.pieceProperties.position); var others = Entities.findEntities(this.pieceProperties.position, tileSize); for (var i = 0; i < others.length; i++) { var pieceID = others[i]; if (pieceID != this.entityID) { var properties = Entities.getEntityProperties(pieceID); if (properties.type !== "Model" || properties.parentID !== this.boardID || properties.script !== this.pieceProperties.script) { continue; } var type = (properties.modelURL.search("chess/King.fbx") !== -1) ? 4 : (properties.modelURL.search("chess/Queen.fbx") !== -1) ? 3 : (properties.modelURL.search("chess/Rook.fbx") !== -1) ? 2 : (properties.modelURL.search("chess/Knight.fbx") !== -1) ? 1 : (properties.modelURL.search("chess/Bishop.fbx") !== -1) ? 0 : (properties.modelURL.search("chess/Pawn.fbx") !== -1) ? -1 : -2; if (type == -2) { continue; } var isWhite = (properties.textures === ""); var piecePos = this.getIndexPosition(properties.position); if (myPos.i === piecePos.i && myPos.j === piecePos.j && type !== -2) { var position = this.getAbsolutePosition(isWhite ? { i: 4, j: 3 - type } : { i: -5, j: type - 4 }); Entities.editEntity(pieceID, { position: position }); break; } } } } this.requestParentID = function() { var that = this; Script.setTimeout(function() { that.getParentID(); }, 10); } this.getParentID = function() { this.boardID = Entities.getEntityProperties(this.entityID, ["parentID"]).parentID; try { var url = Entities.getEntityProperties(this.boardID, ["modelURL"]).modelURL; if (url.search("chess/Board.fbx") === -1) { throw "Error"; } } catch(e) { this.requestParentID(); } } this.preload = function(entityID) { // Piece ID this.entityID = entityID; this.loadSound(); this.requestParentID(); } this.startGrab = function() { if (++this.grabs !== 1) { return; } this.pullProperties(); this.startingTile = this.getIndexPosition(this.pieceProperties.position); } this.startNearGrab = this.startGrab; this.startDistanceGrab = this.startGrab; this.releaseGrab = function() { if (--this.grabs !== 0) { return; } this.pullProperties(); this.snapToGrid(); this.moveDeadPiece(); this.playSound(); }; })