diff options
author | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-12 18:29:07 +0000 |
---|---|---|
committer | luchen@google.com <luchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-12 18:29:07 +0000 |
commit | 97c7057c30c7fd7d740f22769a832193b278fa98 (patch) | |
tree | 86d02ed6cc9cad61291e4c5e9d432f7fe43a875e | |
parent | 8815b7f26086c7a8b98dfeb11efa32aa4fd483e1 (diff) | |
download | chromium_src-97c7057c30c7fd7d740f22769a832193b278fa98.zip chromium_src-97c7057c30c7fd7d740f22769a832193b278fa98.tar.gz chromium_src-97c7057c30c7fd7d740f22769a832193b278fa98.tar.bz2 |
Adding checkers demo.
Review URL: http://codereview.chromium.org/2892004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52109 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | o3d/samples/o3d-webgl-samples/checkers.html | 873 |
1 files changed, 873 insertions, 0 deletions
diff --git a/o3d/samples/o3d-webgl-samples/checkers.html b/o3d/samples/o3d-webgl-samples/checkers.html new file mode 100644 index 0000000..7548174 --- /dev/null +++ b/o3d/samples/o3d-webgl-samples/checkers.html @@ -0,0 +1,873 @@ +<!-- +Copyright 2009, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> + +<!-- +Checker Game Example + +This sample demonstates usage of primitive functions and simple 3d animation techniques. +--> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title> +3D Checkers Game +</title> +<script type="text/javascript" src="../o3d-webgl/base.js"></script> +<script type="text/javascript" src="../o3djs/base.js"></script> + +<!-- Our javascript code --> +<script type="text/javascript" id="o3dscript"> +o3djs.base.o3d = o3d; +o3djs.require('o3djs.webgl'); +o3djs.require('o3djs.util'); +o3djs.require('o3djs.rendergraph'); +o3djs.require('o3djs.material'); +o3djs.require('o3djs.primitives'); +o3djs.require('o3djs.arcball'); +o3djs.require('o3djs.picking'); +o3djs.require('o3djs.math'); +o3djs.require('o3djs.quaternions'); + +// global variables +var g_o3dElement; +var g_client; +var g_o3d; +var g_math; +var g_quaternions; +var g_pack; +var g_viewInfo; +var g_sceneRoot; +var g_eyeView; +var g_cubeShape; +var g_cylinderShape; +var g_prismShape; +var g_material; +var g_aball; +var g_thisRot; +var g_lastRot; +var g_zoomFactor; +var g_dragging = false; +var g_pickManager; // information about the transform graph. +var g_statusInfoElem; + +// Animation globals. +var g_flashTimer; +var g_moveTimer; +var g_moveDuration; +var g_oldFlashTimer; + +// Checkers globals. +var g_board; +var g_boardSize; +var g_boardSquare; +var g_boardHeight; +var g_pieceHeight; +var g_selectedPiece; +var g_selectedSquare; +var g_player; +var g_canJump; + +/** + * Creates the client area. + */ +function initClient() { + window.g_finished = false; // for selenium testing. + + // Runs the sample in V8. Comment out this line to run it in the browser + // JavaScript engine, for example if you want to debug it. + o3djs.util.setMainEngine(o3djs.util.Engine.V8); + + o3djs.webgl.makeClients(main); +} + +/** + * Initializes global variables, positions camera, draws the 3D chart. + * @param {Array} clientElements Array of o3d object elements. + */ +function main(clientElements) { + // Init global variables. + initGlobals(clientElements); + + // Set up the view and projection transformations. + initContext(); + + // Add the checkers board to the transform hierarchy. + createCheckersBoard(); + + // Register mouse events handlers + o3djs.event.addEventListener(g_o3dElement, 'mousedown', startDragging); + o3djs.event.addEventListener(g_o3dElement, 'mousemove', drag); + o3djs.event.addEventListener(g_o3dElement, 'mouseup', stopDragging); + o3djs.event.addEventListener(g_o3dElement, 'wheel', scrollMe); + + // Set the rendering callback + g_client.setRenderCallback(onrender); + + window.g_finished = true; // for selenium testing. +} + +/** + * Initializes global variables and libraries. + */ +function initGlobals(clientElements) { + // init o3d globals. + g_o3dElement = clientElements[0]; + window.g_client = g_client = g_o3dElement.client; + g_o3d = g_o3dElement.o3d; + g_math = o3djs.math; + g_quaternions = o3djs.quaternions; + + // Create an arcball. + g_aball = o3djs.arcball.create(g_client.width, g_client.height); + + // Create a pack to manage the objects created. + g_pack = g_client.createPack(); + + // Create a transform node to act as the 'root' of the scene. + // Attach it to the root of the transform graph. + g_sceneRoot = g_pack.createObject('Transform'); + g_sceneRoot.parent = g_client.root; + + // Create the render graph for the view. + var clearColor = [.98, .98, .98, 1]; + g_viewInfo = o3djs.rendergraph.createBasicView( + g_pack, + g_client.root, + g_client.renderGraphRoot, + clearColor); + + // Create a material for the objects rendered. + g_material = o3djs.material.createBasicMaterial( + g_pack, + g_viewInfo, + [1, 1, 1, 1]); + + // Initialize checkers piece and square data. + g_boardSize = 8; + g_boardSquare = 10; + g_boardHeight = g_boardSquare / 5; + g_pieceHeight = g_boardHeight * 0.75; + g_selectedPiece = null; + g_selectedSquare = null; + + // Create a cube shape for the board squares. + g_cubeShape = o3djs.primitives.createCube( + g_pack, + g_material, + 1); + + // Create a cylinder shape for the checkers pieces. + g_cylinderShape = o3djs.primitives.createCylinder( + g_pack, + g_material, + g_boardSquare / 2 - 1, // Radius. + g_pieceHeight, // Depth. + 100, // Number of subdivisions. + 1); + + // use an extruded poligon to create a 'crown' for the king piece. + var polygon = [[0, 0], [1, 0], [1.5, 1.5], [0.5, 0.5], + [0, 2], [-0.5, 0.5], [-1.5, 1.5], [-1, 0]]; + + // use the 'prism' primitive for the crown. + g_prismShape = o3djs.primitives.createPrism( + g_pack, + g_material, + polygon, // The profile polygon to be extruded. + 1); // The depth of the extrusion. + + // Get the status element. + g_statusInfoElem = o3djs.util.getElementById('statusInfo'); + + // Initialize player data. + g_player = 1; // red player starts first. + g_canJump = false; + + // Initialize various animation globals. + g_flashTimer = 0; + g_moveTimer = 0; + g_moveDuration = 1.3; + g_oldFlashTimer = 0; +} + +/** + * Initialize the original view of the scene. + */ +function initContext() { + g_eyeView = [-5, 120, 100]; + g_zoomFactor = 1.03; + g_dragging = false; + g_sceneRoot.identity(); + g_lastRot = g_math.matrix4.identity(); + g_thisRot = g_math.matrix4.identity(); + + // Set up a perspective transformation for the projection. + g_viewInfo.drawContext.projection = g_math.matrix4.perspective( + Math.PI * 40 / 180, // 30 degree frustum. + g_o3dElement.clientWidth / g_o3dElement.clientHeight, // Aspect ratio. + 1, // Near plane. + 10000); // Far plane. + + // Set up our view transformation to look towards the axes origin. + g_viewInfo.drawContext.view = g_math.matrix4.lookAt( + g_eyeView, // eye + [0, 0, 0], // target + [0, 1, 0]); // up +} + +/** + * Creates a Coord object used to hold a set of 2D coordinates. + * + * @private + * @constructor + * @param {number} x X coordinate. + * @param {number} y Y coordinate. + */ +function Coord(x, y) { + this.x = x; + this.y = y; +} + +/** + * Creates a BoardInfo object to hold board information. + * + * @private + * @constructor + * @param {number} x X coordinate on the checkers board. + * @param {number} y Y coordinate on the checkers board. + */ +function BoardInfo(x, y) { + this.x = x; + this.y = y; + this.square = null; + this.type = 0; + this.pieceParent = null; + this.piece = null; + this.king = false; +} + +/** + * Returns the initial settings for a given position on the board. + * + * @param {number} x X coordinate on the checkers board. + * @param {number} y Y coordinate on the checkers board. + * @return {number} 0 = no piece, 1 = red piece, -1 = white piece + */ +function getSquarePiece(x, y) { + // if bad coordinates, no piece. + if (x >= g_boardSize || x < 0 || y >= g_boardSize || y < 0) + return 0; + // if on rows 3 and 4 or on a white square - no piece. + if (y == 3 || y == 4 || ((x + y) % 2 == 1)) + return 0; + // if on rows 0-2 it is a red piece, otherwise white piece. + if (0 <= y && y < 3) return 1; + if (5 <= y && y < 8) return -1; + // Any not covered case. + return 0; +} + +/** + * Creates the checkers board. + */ +function createCheckersBoard() { + g_board = []; + // Create a checker board (black at 0,0). + for (var i = 0; i < g_boardSize; i += 1) { // columns. + g_board[i] = []; + for (var j = 0; j < g_boardSize; j += 1) { // rows. + // create the transform for the board squares. + var square = g_pack.createObject('Transform'); + square.parent = g_sceneRoot; + square.addShape(g_cubeShape); + // translate and scale the squares correctly relative to origin. + var offset = g_boardSquare * (1 - g_boardSize) / 2; + square.translate(offset + g_boardSquare * i , + 0, -(offset + g_boardSquare * j)); + square.scale(g_boardSquare, g_boardHeight, g_boardSquare); + // set the square color. + var isBlack = (i + j) % 2 == 0 ? true : false; + var squareColor = isBlack ? + [0.15, 0.15, 0.15, 1] : [0.85, 0.85, 0.75, 1]; + square.createParam('diffuse', 'ParamFloat4').value = squareColor; + + // add this square and its info to the board. + g_board[i][j] = new BoardInfo(i, j); + g_board[i][j].square = square; + + // create the piece for this square and update the board position. + // skip if the square has no piece. + var pieceType = getSquarePiece(i, j); + if (pieceType == 0) + continue; + + // create a parent transform for this piece. + var pieceParent = g_pack.createObject('Transform'); + pieceParent.parent = g_sceneRoot; + + // create the checkers piece. + var piece = g_pack.createObject('Transform'); + piece.parent = pieceParent; + piece.addShape(g_cylinderShape); + + // place the piece on the correct location on the board. + pieceParent.translate(0, (g_pieceHeight + g_boardHeight) / 2, 0); + pieceParent.translate(offset + g_boardSquare * i , + 0, -(offset + g_boardSquare * j)); + + // pick the piece color (red or white). + piece.createParam('diffuse', 'ParamFloat4').value = + getPieceColor(pieceType); + + // update the board info to include this piece. + g_board[i][j].piece = piece; + g_board[i][j].pieceParent = pieceParent; + g_board[i][j].type = pieceType; + } + } + + // Update our PickManager. + updatePickManager(); + + // update status. + updateStatus('Game starting... RED moves first.', true); +} + +/** + * Checks if a piece has become a 'king' piece and updates it. + * + * @param {number} x X coordinate on the checkers board. + * @param {number} y Y coordinate on the checkers board. + */ +function checkAndUpdateKing(x, y) { + // if the piece is not on the king row, nothing to do. + if ( y > 0 && y < g_boardSize - 1 ) return; + + // ignore if no piece or the piece is already king + var selSquare = g_board[x][y]; + if (!selSquare.piece || selSquare.king) return; + + // change the king piece color. + selSquare.king = true; + + // create the crown shape. + var crown = g_pack.createObject('Transform'); + crown.parent = selSquare.piece; + crown.addShape(g_prismShape); + var crownSize = g_pieceHeight; + crown.scale(crownSize, crownSize, crownSize); + crown.translate(0, g_pieceHeight / 2, 0); + crown.createParam('diffuse', 'ParamFloat4').value = [1, 1, 0, 0]; +} + + +/** + * Updates the transform tree info. + */ +function updatePickManager() { + if (!g_pickManager) { + g_pickManager = o3djs.picking.createPickManager(g_client.root); + } + g_pickManager.update(); +} + +/** + * Check if a player selection is a jump. + * + * @param {BoardInfo} piece The board info for the piece. + * @param {BoardInfo} square The board info for the landing square. + * @return {boolean} true if this is a jump. + */ +function isJump(piece, square) { + return (Math.abs(piece.x - square.x) == 2 && + Math.abs(piece.y - square.y) == 2 ); +} + +function isLegalMove(piece, square) { + var orig = new Coord(piece.x, piece.y); + var dest = new Coord(square.x, square.y); + + // it must be this player's turn to make a move. + if (piece.type != g_player) return false; + + // the destination must be un-occupied. + if (square.type != 0 ) return false; + + // must move diagonally. + var diag = new Coord(dest.x - orig.x, dest.y - orig.y); + if (Math.abs(diag.x) != Math.abs(diag.y)) return false; + + // cannot move more than 2. + if (Math.abs(diag.x) > 2) return false; + + // make sure the piece is moved in the 'forward' direction + // unless this is a 'king' piece. + if (!piece.king && g_player * diag.y < 0) return false; + + // if a jump check if valid. + if (Math.abs(diag.x) == 2) { + var jumpType = g_board[(orig.x + dest.x)/2][(orig.y + dest.y)/2].type; + if (jumpType == piece.type || jumpType == 0) + return false; + } + + return true; +} + +/** + * Update the status message. + * + * @param {string} statusMsg The message to display. + * @param {boolean} opt_hidePlayer Prefix the status with the name of the player. + */ +function updateStatus(statusMsg, opt_hidePlayer) { + var status = (g_player == 1) ? 'RED: ' : 'WHITE: '; + g_statusInfoElem.innerHTML = (opt_hidePlayer ? '' : status) + statusMsg; +} + + +/** + * Check if a valid boad coordinate. + * + * @param {number} x X coordinate on the checkers board. + * @param {number} y Y coordinate on the checkers board. + * @return {boolean} True if a valid coordinate. + */ +function isValidCoord(x, y) { + if ( x < 0 || x >= g_boardSize ) return false; + if ( y < 0 || y >= g_boardSize ) return false; + return true; +} + + +/** + * Check if a piece has a valid sliding move. + * + * @param {!BoardInfo} piece The board info for the piece. + * @return {boolean} True if the piece can slide. + */ +function pieceCanSlide(piece) { + var x = piece.x; + var y = piece.y; + + for (var i = -1; i <= 1; i += 2) { + for (var j = -1; j <= 1; j += 2) { + if (isValidCoord(x + i, y + j)) + if (isLegalMove(piece, g_board[x + i][y + j])) + return true; + } + } + return false; +} + +/** + * Check if a piece has a valid jumping move. + * + * @param {!BoardInfo} piece The board info for the piece. + * @return {boolean} True if the piece can jump. + */ +function pieceCanJump(piece) { + var x = piece.x; + var y = piece.y; + + for (var i = -2; i <= 2; i += 4) { + for (var j = -2; j <= 2; j += 4) { + if (isValidCoord(x + i, y + j)) + if (isLegalMove(piece, g_board[x + i][y + j])) + return true; + } + } + return false; +} + +/** + * Check if the current player has any moves available. + * + * @return {boolean} True if the player can move. + */ +function currentPlayerCanMove() { + var canSlide = false; + for (var x = 0; x < g_boardSize; x += 1) { + for (var y = 0; y < g_boardSize; y += 1) { + var sel = g_board[x][y]; + if (sel.piece == null) continue; + // if jump set the canJump variable and return. + g_canJump = pieceCanJump(sel); + if (g_canJump) return true; + if (pieceCanSlide(sel)) { + canSlide = true; + } + } + } + return canSlide; +} + +/** + * Check if a forced jump is required for the current player. + * + * @return {boolean} True if a jump is required. + */ +function checkForcedJump() { + for (var x = 0; x < g_boardSize; x += 1) { + for (var y = 0; y < g_boardSize; y += 1) { + var sel = g_board[x][y]; + if (sel.piece && pieceCanJump(sel)) { + g_forcedJump = true; + return true; + } + } + } + g_forcedJump = false; + return false; +} + +/** + * Check if the game is over. + * + * @return {boolean} True if the game is over. + */ +function isGameOver() { + // the game is over when a player has no pieces left + // or it cannot make a valid move. + if (!currentPlayerCanMove()) { + var statusStr = (g_player == 1) ? 'White Won!' : 'Red Won!'; + updateStatus(statusStr, true); + return true; + } + return false; +} + +/** + * Detect a mouse click an element of the checkers board. + * + * @param {event} e event. + */ +function detectSelection(e) { + var worldRay = o3djs.picking.clientPositionToWorldRay(e.x, + e.y, + g_viewInfo.drawContext, + g_client.width, + g_client.height); + + // check if we picked any objects. + var pickInfo = g_pickManager.pick(worldRay); + if (pickInfo) { + // get the parent transform of this object. + var pickTrans = pickInfo.shapeInfo.parent.transform; + var pickTransClientId = pickTrans.clientId; + + // check if a board square or a piece. + for (var x = 0; x < g_boardSize; x += 1) { + for (var y = 0; y < g_boardSize; y += 1) { + if (g_board[x][y].piece && + pickTransClientId == g_board[x][y].piece.clientId) { + // do not select another player's piece. + if (g_player != g_board[x][y].type) return; + + // if a previous piece selection, clear it. + if (g_selectedPiece) { + g_selectedPiece.piece.getParam('diffuse').value = + getPieceColor(g_selectedPiece.type); + } + + // check if a forced jump. + if (g_canJump) { + if (!pieceCanJump(g_board[x][y])) { + updateStatus('Must jump, incorrect piece!'); + return; + } + } + + SelectPiece(x, y); + return; + } else if (pickTransClientId == g_board[x][y].square.clientId) { + // selected the landing square if a piece move is pending. + if (g_selectedPiece) { + // check if a forced jump. + if (g_canJump && !isJump(g_selectedPiece, g_board[x][y])) { + updateStatus('Must jump!'); + return; + } + // check if a legal move, then move the piece. + if (isLegalMove(g_selectedPiece, g_board[x][y])) { + SelectSquare(x, y); + } else { + updateStatus('Illegal move!'); + } + } + return; + } + } + } + } +} + +/** + * Select a piece on the checkers board. + */ +function SelectPiece(x, y) { + g_selectedPiece = g_board[x][y]; + // update status message. + updateStatus('Selected piece at (' + x + ',' + y + ')'); +} + +/** + * Select a square on the checkers board. + */ +function SelectSquare(x, y) { + updateStatus('Moving piece from (' + g_selectedPiece.x + ',' + + g_selectedPiece.y + ') to (' + x + ',' + y + ')'); + g_selectedSquare = g_board[x][y]; + g_moveTimer = 0; +} + +/** + * Return the color for the given piece type. + * + * @param {number} type Type of the checkers piece. + * @return {Array} Array representing the color. + */ +function getPieceColor(type) { + return (type == 1) ? [1, 0.15, 0.15, 1] : [1, 1, 1, 1]; +} + +/** + * Called every frame. + * @param {o3d.RenderEvent} renderEvent Rendering Information. + */ +function onrender(renderEvent) { + g_flashTimer += renderEvent.elapsedTime; + g_flashTimer = g_flashTimer % 0.5; + + if (g_selectedPiece) { + var origColor = getPieceColor(g_selectedPiece.type); + // flash highlight the selected piece as long as selected. + if (g_oldFlashTimer > g_flashTimer ) { + g_selectedPiece.piece.getParam('diffuse').value = [0.6, 1, 1, 1]; + } else if (g_flashTimer >= 0.25 && g_oldFlashTimer < 0.25) { + g_selectedPiece.piece.getParam('diffuse').value = origColor; + } + + // check if we selected a square to move the piece. + if (g_selectedSquare) { + moveSelectedPiece(renderEvent.elapsedTime); + } + } + g_oldFlashTimer = g_flashTimer; +} + + +/** + * Slides or jumps the selected piece. + * This method is used to simulate the animation of the moving piece. + * @param {number} elapsedTime The elapsed time in seconds since the last call. + */ +function moveSelectedPiece(elapsedTime) { + g_moveTimer += elapsedTime; + // animate the piece one iteration at the time. + var lerp = g_moveTimer / g_moveDuration; + + // get the board coordinates of the curent and future position. + var x0 = g_selectedPiece.x; + var y0 = g_selectedPiece.y; + var x1 = g_selectedSquare.x; + var y1 = g_selectedSquare.y; + + // get the coordinates relative to axis origin. + var offset = g_boardSquare * (1 - g_boardSize) / 2; + var xc0 = offset + g_boardSquare * x0; + var zc0 = -(offset + g_boardSquare * y0); + var xc1 = offset + g_boardSquare * x1; + var zc1 = -(offset + g_boardSquare * y1); + var yc = (g_pieceHeight + g_boardHeight) / 2; + + // Our piece's position and rotation. + var px; + var pz; + var jump = 0; + var rotation = 0; + var done = false; + + if (lerp < 1) { + // check if this is a jump. + if (isJump(g_selectedPiece, g_selectedSquare)) { + // compute the jump height. + jump = Math.sin(Math.PI * lerp) * g_pieceHeight * 13; + // simulate a spinning of the jumping piece. + rotation = -lerp * 4 * Math.PI; + } + px = xc0 + (xc1 - xc0) * lerp; + pz = zc0 + (zc1 - zc0) * lerp; + } else { + // done with the move. + px = xc1; + pz = zc1; + done = true; + } + + // move the piece to the new position. + var pieceParent = g_board[x0][y0].pieceParent; + pieceParent.identity(); + pieceParent.translate(px, yc + jump, pz); + + // spin the piece + g_selectedPiece.piece.identity(); + g_selectedPiece.piece.rotateX(rotation); + + if (done) { + // stop flashing - restore the original color. + var origColor = getPieceColor(g_selectedPiece.type); + g_selectedPiece.piece.getParam('diffuse').value = origColor; + + // if a jump destroy the jumped piece. + var wasJump = isJump(g_selectedPiece, g_selectedSquare); + if (wasJump) { + var xj = (x0 + x1)/2; + var yj = (y0 + y1)/2; + g_board[xj][yj].type = 0; + g_board[xj][yj].pieceParent.parent = null; + g_board[xj][yj].pieceParent = null; + g_board[xj][yj].piece = null; + } + + // the new square has a new piece. + g_board[x1][y1].type = g_selectedPiece.type; + g_board[x1][y1].king = g_selectedPiece.king; + g_board[x1][y1].piece = g_selectedPiece.piece; + g_board[x1][y1].pieceParent = g_selectedPiece.pieceParent; + + // the original square is now empty. + g_board[x0][y0].type = 0; + g_board[x0][y0].piece = null; + g_board[x0][y0].pieceParent = null; + + // check if the moved piece became king. + checkAndUpdateKing(x1, y1); + + g_selectedPiece = null; + g_selectedSquare = null; + g_moveTimer = 0; + + // update the picking info. + updatePickManager(); + + // check if current player can jump again. + if (wasJump && pieceCanJump(g_board[x1][y1])) { + g_selectedPiece = g_board[x1][y1]; + updateStatus('Must jump again ...'); + } else { + // this player is done, switch players. + g_player = -g_player; + // check if game over; also checks if the current player must jump. + if (!isGameOver()) { + updateStatus(g_canJump ? 'Must jump...' : 'Next turn...'); + } + } + } +} + + +/** + * Zooms the scene in / out by changing the viewpoint. + * @param {number} zoom zooming factor. + */ +function ZoomInOut(zoom) { + for (i = 0; i < g_eyeView.length; i += 1) { + g_eyeView[i] = g_eyeView[i] / zoom; + } + + g_viewInfo.drawContext.view = g_math.matrix4.lookAt( + g_eyeView, // eye. + [0, 0, 0], // target. + [0, 1, 0]); // up. +} + +/** + * Start mouse dragging. + * @param {event} e event. + */ +function startDragging(e) { + detectSelection(e); + g_lastRot = g_thisRot; + + g_aball.click([e.x, e.y]); + g_dragging = true; +} + +/** + * Use the arcball to rotate the scene. + * Computes the rotation matrix. + * @param {event} e event. + */ +function drag(e) { + if (g_dragging) { + var rotationQuat = g_aball.drag([e.x, e.y]); + var rot_mat = g_quaternions.quaternionToRotation(rotationQuat); + + g_thisRot = g_math.matrix4.mul(g_lastRot, rot_mat); + var m = g_sceneRoot.localMatrix; + g_math.matrix4.setUpper3x3(m, g_thisRot); + g_sceneRoot.localMatrix = m; + } +} + +/** + * Stop dragging. + * @param {event} e event. + */ +function stopDragging(e) { + g_dragging = false; +} + +/** + * Using the mouse wheel zoom in and out of the scene. + * @param {event} e event. + */ +function scrollMe(e) { + var zoom = (e.deltaY < 0) ? 1 / g_zoomFactor : g_zoomFactor; + ZoomInOut(zoom); + g_client.render(); +} + +</script> +</head> + +<body onload="initClient()"> +<h2>3D Checkers Game</h2> +<div style="font-size:10;"><span id="statusInfo"></span></div> +<!-- Start of O3D plugin --> +<div id="o3d" style="width: 600px; height: 600px;"></div> +<!-- End of O3D plugin --> + +</body> +</html> |