From 281e393469771f08863f95cb0b9d1bb8ed4b9b0e Mon Sep 17 00:00:00 2001 From: miniature-tiger <35037641+miniature-tiger@users.noreply.github.com> Date: Wed, 16 Jan 2019 23:05:39 +0000 Subject: [PATCH] Whirlpools - transitions * Addition of transitions to the creation and movement of whirlpools - spinning and reducing / increasing in size. * Simplification of display piece transitions for scale and rotations. piecedisplay.js * spinTransitionDown - New method for spinning transition with decrease in size. * spinTransitionUp - New method for spinning transition with increase in size. * changeScale - New method to change scale of a piece. * changeRotation - New method to change direction of a piece. * Change to method for scaling pieces - uses transform instead of svg viewport to allow transitions. move.js * Addition of transitions to whirlpool moves whirlpool.js, gamemanagement.js * Implementation of window scrolling before whirlpool changes * Use of async / await for sequential transitions of whirlpools build.js, dashboard.js, contracts.js * Simplification of display piece transitions for scale and rotations. --- build.js | 2 +- contracts.js | 6 ++--- dashboard.js | 6 ++--- gamemanagement.js | 10 ++++---- index.html | 8 +++---- move.js | 19 +++++++++++---- movement.js | 25 ++++++-------------- piecedisplay.js | 59 +++++++++++++++++++++++++++++++++++++++++++++-- surround.css | 4 ++-- svgdisplay.js | 7 +++--- whirlpool.js | 11 +++++---- 11 files changed, 107 insertions(+), 50 deletions(-) diff --git a/build.js b/build.js index 217db7c..7a73b5e 100644 --- a/build.js +++ b/build.js @@ -53,7 +53,7 @@ let buildItem = { let buildNo = buildItem.buildRecipe.findIndex(y => y.type == build); // Add icon of ship clicked on - let buildIcon = buildItem.building.appendChild(new PieceSVG(build, 'Unclaimed', 'buildPiece', 10, (game.mapWidth - 2*game.surroundSize) * 0.04 - (game.gridSize + 2*game.tileBorder)/2, 1.5, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); + let buildIcon = buildItem.building.appendChild(new PieceSVG(build, 'Unclaimed', 'buildPiece', 10, (game.mapWidth - 2*game.surroundSize) * 0.04 - (game.gridSize + 2*game.tileBorder)/2, 0.7, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); // Check enough goods to build chosen ship let allowConstruction = this.enoughGoodsToBuild(buildNo, game.turn); diff --git a/contracts.js b/contracts.js index 6754879..f6ca3e1 100644 --- a/contracts.js +++ b/contracts.js @@ -555,13 +555,13 @@ let tradeContracts = { // Icon added if (this.contractsArray[i].contracts[resource.goods].struck == 'open') { - divType.appendChild(new PieceSVG(resource.type, 'Unclaimed', 'dash_' + resource.type, 2, 0, 1.5, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); + divType.appendChild(new PieceSVG(resource.type, 'Unclaimed', 'dash_' + resource.type, 2, 0, 0.7, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); divForText.innerHTML = this.contractsArray[i].contracts[resource.goods].struck; } else if (this.contractsArray[i].contracts[resource.goods].struck == 'active') { - divType.appendChild(new PieceSVG(resource.type, this.contractsArray[i].contracts[resource.goods].team, 'dash_' + resource.type, 2, 0, 1.5, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); + divType.appendChild(new PieceSVG(resource.type, this.contractsArray[i].contracts[resource.goods].team, 'dash_' + resource.type, 2, 0, 0.7, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); divForText.innerHTML = 'active'; } else if (this.contractsArray[i].contracts[resource.goods].struck == 'closed') { - divType.appendChild(new PieceSVG(resource.type, this.contractsArray[i].contracts[resource.goods].team, 'dash_' + resource.type, 2, 0, 1.5, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); + divType.appendChild(new PieceSVG(resource.type, this.contractsArray[i].contracts[resource.goods].team, 'dash_' + resource.type, 2, 0, 0.7, 0, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); divForText.innerHTML = 'closed'; } diff --git a/dashboard.js b/dashboard.js index 8f09d30..f502f7a 100644 --- a/dashboard.js +++ b/dashboard.js @@ -217,7 +217,7 @@ let stockDashboard = { // Icon setting base on piece type if (pieceData.category == 'Transport') { rotateIcon = 90; - xPosition = -8; + xPosition = 0; } else { rotateIcon = 0; xPosition = 0; @@ -244,7 +244,7 @@ let stockDashboard = { divType.setAttribute('class', 'inner_item_holder'); divCat.appendChild(divType); // Icon added - divType.appendChild(new PieceSVG(pieceType, game.turn, 'dash_' + pieceType, 2, xPosition, 1.5, rotateIcon, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); + divType.appendChild(new PieceSVG(pieceType, game.turn, 'dash_' + pieceType, 2, xPosition, 0.7, rotateIcon, 5, game.gridSize, game.tileBorder, game.boardSurround).svg); let divForText = document.createElement('div'); divForText.setAttribute('class', 'dashboard_text'); divType.appendChild(divForText); @@ -290,7 +290,7 @@ let stockDashboard = { divType.setAttribute('class', 'inner_item_holder ' + additionalClass); divCat.appendChild(divType); // Icon added - let divTypeIcon = new PieceSVG(pieceType, 'Unclaimed', 'dash_' + pieceType, 2, xPosition, 1.5, rotateIcon, 5, game.gridSize, game.tileBorder, game.boardSurround).svg; + let divTypeIcon = new PieceSVG(pieceType, 'Unclaimed', 'dash_' + pieceType, 2, xPosition, 0.7, rotateIcon, 5, game.gridSize, game.tileBorder, game.boardSurround).svg; if (pieceData.category == 'Transport') { //divTypeIcon.setAttribute('class', additionalClass); diff --git a/gamemanagement.js b/gamemanagement.js index ce49d76..b35c458 100644 --- a/gamemanagement.js +++ b/gamemanagement.js @@ -137,11 +137,11 @@ Game.prototype.nextTurn = function() { } } -Game.prototype.nextTurnTwo = function() { +Game.prototype.nextTurnTwo = async function() { // Move to next player go / next date game.nextPlayer(); game.prepareNextTurn(); - game.prePlayerEvents(); + await game.prePlayerEvents(); game.checkGameEnd(); if (game.gameEnd === true) { // End scroll pop up @@ -247,7 +247,7 @@ Game.prototype.prepareNextTurn = function() { // Pre player move events // ------------------------------------------------ -Game.prototype.prePlayerEvents = function() { +Game.prototype.prePlayerEvents = async function() { if (game.turn !== 'Pirate') { // Chance of new trade contract if(settings.workFlow === true) {console.log('Checking for new trade contracts: ' + (Date.now() - settings.launchTime)); } @@ -272,12 +272,14 @@ Game.prototype.prePlayerEvents = function() { // Create and move whirlpools //if (this.gameDate > 1 * this.phaseCount) { // start at end of first moon along with contracts if (this.gameDate > 0 * this.phaseCount ) { // testing - whirlpool.manageWhirlpools(); + await whirlpool.manageWhirlpools(); } } // Repair ships pieceMovement.harbourRepair(); + + return; } // Method to activate next turn - up to moon change diff --git a/index.html b/index.html index 2dae2a0..8918e9f 100644 --- a/index.html +++ b/index.html @@ -44,8 +44,7 @@ - + @@ -59,8 +58,7 @@ - +
@@ -169,7 +167,7 @@ - + diff --git a/move.js b/move.js index f7fe81c..0b95a15 100644 --- a/move.js +++ b/move.js @@ -34,7 +34,7 @@ Move.prototype.process = async function() { // boardArray changes this.board.addPiece([this.startMove.row, this.startMove.col], new Resources('Resources', this.discoveredResource, '0', 'Unclaimed', this.discoveredGoods, this.discoveredStock, this.discoveredProduction, 'none')); // Display changes - this.boardDisplay.addPiece(this.discoveredResource, 'Unclaimed', this.startMove.row, this.startMove.col, '0', 5); + this.boardDisplay.addPiece(this.discoveredResource, 'Unclaimed', this.startMove.row, this.startMove.col, '0', 5, 1); } else if (this.moveType === 'claim') { // boardArray changes @@ -94,14 +94,14 @@ Move.prototype.process = async function() { // boardArray changes this.board.addPiece([this.endMove.row, this.endMove.col], new Transport('Transport', 'cargoship', '0', 1, startPiece.team, 'none', 0, 0, 'none')); // Display changes - this.boardDisplay.addPiece('cargoship', startPiece.team, this.endMove.row, this.endMove.col, '0', 1); + this.boardDisplay.addPiece('cargoship', startPiece.team, this.endMove.row, this.endMove.col, '0', 1, 1); endPieceSVG = this.boardDisplay.pieces[endPieceID]; endPieceSVG.repairShip(1); } else if (this.endMove.piece.type === 'warship') { // boardArray changes this.board.addPiece([this.endMove.row, this.endMove.col], new Transport('Transport', 'warship', '0', 3, startPiece.team, 'none', 0, 0, 'none')); // Display changes - this.boardDisplay.addPiece('warship', startPiece.team, this.endMove.row, this.endMove.col, '0', 3); + this.boardDisplay.addPiece('warship', startPiece.team, this.endMove.row, this.endMove.col, '0', 3, 1); endPieceSVG = this.boardDisplay.pieces[endPieceID]; endPieceSVG.repairShip(3); } @@ -121,12 +121,21 @@ Move.prototype.process = async function() { // boardArray changes this.board.addPiece([this.startMove.row, this.startMove.col], new Hazard('Hazards', 'whirlpool', 0, 'Pirate', 'none', 0, 0, 'none', this.startMove.row, this.startMove.col)); // Display changes - this.boardDisplay.addPiece('whirlpool', 'none', this.startMove.row, this.startMove.col, '0', 5); + let whirlpool = this.boardDisplay.addPiece('whirlpool', 'none', this.startMove.row, this.startMove.col, '360', 5, 0.1); + whirlpool.svg.focus(); + // Display transition + await whirlpool.spinTransitionUp(2 * settings.gameSpeed); + + return; } else if (this.moveType === 'moveWhirlpool') { // boardArray changes let endPiece = this.board.movePiece([this.startMove.row, this.startMove.col], [this.endMove.row, this.endMove.col]); - // Display changes + // Display and transition changes + await startPieceSVG.spinTransitionDown(2 * settings.gameSpeed); this.boardDisplay.movePieceNoTransition(startPieceSVG, endPieceID, this.endMove.row, this.endMove.col); + await startPieceSVG.spinTransitionUp(2 * settings.gameSpeed); + + return; } } diff --git a/movement.js b/movement.js index 49b1f52..8cff180 100644 --- a/movement.js +++ b/movement.js @@ -500,14 +500,9 @@ let pieceMovement = { // n is number of transition in chain // Transitions to be applied (added here to allow different transitions to be applied dynamically in future) startPieceSVG.svg.style.transition = 'transform ' + (0.1 * gameSpeed) + 's 0s ease-in-out, left ' + (0.35 * gameSpeed) + 's ' + (0.1 * gameSpeed) + 's ease-in-out, top ' + (0.35 * gameSpeed) + 's ' + (0.1 * gameSpeed) + 's ease-in-out'; - // Delayed application of transformations to give board game style move effect - //setTimeout(function() { - //console.log(startPieceSVG.style.left, startPieceSVG.style.top); - startPieceSVG.svg.style.left = parseFloat(startPieceSVG.svg.style.left) + (leftDirection * (game.gridSize + game.tileBorder*2)) + 'px'; - startPieceSVG.svg.style.top = parseFloat(startPieceSVG.svg.style.top) + (topDirection * (game.gridSize + game.tileBorder*2)) + 'px'; - startPieceSVG.svg.style.transform = 'rotate(' + rotateDirection + 'deg)'; - //}, 500 * gameSpeed); + startPieceSVG.changePosition(parseFloat(startPieceSVG.svg.style.top) + (topDirection * (game.gridSize + game.tileBorder*2)), parseFloat(startPieceSVG.svg.style.left) + (leftDirection * (game.gridSize + game.tileBorder*2))); + startPieceSVG.changeRotation(rotateDirection); return n + 1; }, @@ -528,12 +523,8 @@ let pieceMovement = { if(game.boardArray[endMove.row+i][endMove.col+j].tile.terrain == 'land' && !game.boardArray[endMove.row+i][endMove.col+j].piece.populatedSquare) { // If so - picks a reource card type using resourceManagement.pickFromResourceDeck() and updates boardArray to this tile tile with unoccupied team deckCard = resourceManagement.pickFromResourceDeck(); - //randomProduction = Math.floor(Math.random() * (deckCard.maxProduction)) + 1; let randomStock = Math.floor(Math.random() * 3); new Move({row: endMove.row+i, col: endMove.col+j}, {row: endMove.row, col: endMove.col}, 'discover', {discoveredResource: deckCard.type, discoveredGoods: deckCard.goods, discoveredStock: randomStock, discoveredProduction: deckCard.production}).process(); - //game.boardArray[endMove.row+i][endMove.col+j].pieces = {populatedSquare: true, category: 'Resources', type: deckCard.type, direction: '0', used: 'unused', damageStatus: 5, team: 'Unclaimed', goods: deckCard.goods, stock: randomStock, production: deckCard.production}; - // and then creates an SVG resource tile for the land space - //game.boardDisplay.addPiece(game.boardArray[endMove.row+i][endMove.col+j].pieces.type, game.boardArray[endMove.row+i][endMove.col+j].pieces.team, endMove.row+i, endMove.col+j, game.boardArray[endMove.row+i][(endMove.col+j)].pieces.direction); } } } @@ -644,12 +635,10 @@ let pieceMovement = { if (repeat > 0) { shipPieceSVG.svg.style.transition = 'transform ' + (0.4 * settings.gameSpeed) + 's 0s ease-in-out, left ' + (0.7 * settings.gameSpeed * fireEffect) + 's ' + (0.0 * settings.gameSpeed * fireEffect) + 's ease-in-out, top ' + (0.7 * settings.gameSpeed * fireEffect) + 's ' + (0.0 * settings.gameSpeed * fireEffect) + 's ease-in-out'; piratePieceSVG.svg.style.transition = 'transform ' + (0.4 * settings.gameSpeed) + 's 0s ease-in-out, left ' + (0.7 * settings.gameSpeed * fireEffect) + 's ' + (0.0 * settings.gameSpeed * fireEffect) + 's ease-in-out, top ' + (0.7 * settings.gameSpeed * fireEffect) + 's ' + (0.0 * settings.gameSpeed * fireEffect) + 's ease-in-out'; - shipPieceSVG.svg.style.transform = 'rotate(' + conflictDirection + 'deg)'; - piratePieceSVG.svg.style.transform = 'rotate(' + conflictDirection + 'deg)'; - shipPieceSVG.svg.style.left = parseFloat(shipPieceSVG.svg.style.left) - (conflictLeftDirection * reductionDirection * (game.gridSize + game.tileBorder*2)) + 'px'; - shipPieceSVG.svg.style.top = parseFloat(shipPieceSVG.svg.style.top) - (conflictTopDirection * reductionDirection * (game.gridSize + game.tileBorder*2)) + 'px'; - piratePieceSVG.svg.style.left = parseFloat(piratePieceSVG.svg.style.left) + (conflictLeftDirection * reductionDirection * (game.gridSize + game.tileBorder*2)) + 'px'; - piratePieceSVG.svg.style.top = parseFloat(piratePieceSVG.svg.style.top) + (conflictTopDirection * reductionDirection * (game.gridSize + game.tileBorder*2)) + 'px'; + shipPieceSVG.changeRotation(conflictDirection); + piratePieceSVG.changeRotation(conflictDirection); + shipPieceSVG.changePosition(parseFloat(shipPieceSVG.svg.style.top) - (conflictTopDirection * reductionDirection * (game.gridSize + game.tileBorder*2)), parseFloat(piratePieceSVG.svg.style.left) + (conflictLeftDirection * reductionDirection * (game.gridSize + game.tileBorder*2))); + piratePieceSVG.changePosition(parseFloat(piratePieceSVG.svg.style.top) + (conflictTopDirection * reductionDirection * (game.gridSize + game.tileBorder*2)), parseFloat(shipPieceSVG.svg.style.left) - (conflictLeftDirection * reductionDirection * (game.gridSize + game.tileBorder*2))); if (reductionDirection == 0.25) { reductionDirection = -0.12; } else if (reductionDirection == 0.12) { @@ -718,7 +707,7 @@ let pieceMovement = { } } } - shipPieceSVG.svg.style.transform = 'rotate(' + repairDirection + 'deg)'; + shipPieceSVG.changeRotation(repairDirection); // Updates boardArray for new status - cargo ships take longer to repair, working through damageStatus from 1 to 5 rather than just 3 to 5 if (endPiece.type === 'cargoship') { diff --git a/piecedisplay.js b/piecedisplay.js index 64ed6ad..d70b2eb 100644 --- a/piecedisplay.js +++ b/piecedisplay.js @@ -36,10 +36,65 @@ PieceSVG.prototype.changePosition = function(top, left) { this.svg.style.left = this.left + 'px'; } +// Method to change direction of a piece +// --------------------------------------- +PieceSVG.prototype.changeRotation = function(rotation) { + this.rotation = rotation; + this.svg.style.transform = 'rotate(' + this.rotation + 'deg) scale(' + this.scale + ')'; +} + +// Method to change scale of a piece +// --------------------------------------- +PieceSVG.prototype.changeScale = function(scale) { + this.scale = scale; + this.svg.style.transform = 'rotate(' + this.rotation + 'deg) scale(' + this.scale + ')'; +} + +// Method for spinning transition with decrease in size +// ---------------------------------------------------- +PieceSVG.prototype.spinTransitionDown = async function(speed) { + const whirlpool = this.svg; + const finishedDown = () => new Promise (resolve => { + whirlpool.addEventListener('transitionend', function whirlpoolDownHandler() { + whirlpool.removeEventListener('transitionend', whirlpoolDownHandler); + resolve(); + }); + }); + + this.svg.style.transition = 'transform ' + speed + 's 0s ease-in-out'; + this.rotation = this.rotation - 180; + this.scale = 0.1; + this.svg.style.transform = 'rotate(' + this.rotation + 'deg) scale(' + this.scale + ')'; + + await finishedDown(); + return; +} + +// Method for spinning transition with increase in size +// ---------------------------------------------------- +PieceSVG.prototype.spinTransitionUp = async function(speed) { + const whirlpool = this.svg; + const finishedUp = () => new Promise (resolve => { + whirlpool.addEventListener('transitionend', function whirlpoolUpHandler() { + whirlpool.removeEventListener('transitionend', whirlpoolUpHandler); + resolve(); + }); + }); + + this.svg.style.transition = 'transform ' + speed + 's 0s ease-in-out'; + this.rotation = this.rotation - 180; + this.scale = 1; + this.svg.style.transform = 'rotate(' + this.rotation + 'deg) scale(' + this.scale + ')'; + + await finishedUp(); + return; +} + + // Method to create a single piece (for addition to board or as icon in dashboards) // -------------------------------------------------------------------------------- PieceSVG.prototype.createPiece = function() { - const viewportSize = 25 * this.scale; + const viewportSize = 25; // Create SVG tile of designated height and width this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); this.svg.setAttribute('width', this.gridSize + this.tileBorder); @@ -48,7 +103,7 @@ PieceSVG.prototype.createPiece = function() { // Position tile based on coordinates passed from boardArray this.svg.style.top = this.top + 'px'; this.svg.style.left = this.left + 'px'; - this.svg.style.transform = 'rotate(' + this.rotation + 'deg)'; + this.svg.style.transform = 'rotate(' + this.rotation + 'deg) scale(' + this.scale + ')'; // Set view size, class and id this.svg.setAttribute('viewBox', '0, 0, ' + viewportSize + ' ' + viewportSize); diff --git a/surround.css b/surround.css index b86faac..a3d0f72 100644 --- a/surround.css +++ b/surround.css @@ -72,7 +72,7 @@ html { .under_text { position: static; width: 100%; - background-color: rgb(254,252,250); + /* background-color: rgb(254,252,250); */ padding-top: 1%; } @@ -84,7 +84,7 @@ html { padding: 0%; height: 84%; top: 8%; - background-color: rgba(138, 87, 50, 0.1); + background-color: rgba(138, 87, 50, 0.1); overflow: scroll; } diff --git a/svgdisplay.js b/svgdisplay.js index b8132f8..22340f2 100644 --- a/svgdisplay.js +++ b/svgdisplay.js @@ -12,7 +12,7 @@ BoardDisplay.prototype.setupPieces = function() { if (this.boardArray[i][j].piece.populatedSquare === true) { let piece = this.boardArray[i][j].piece; // Create action tile svg and add to the board - this.addPiece(piece.type, piece.team, i, j, piece.direction, piece.damageStatus); + this.addPiece(piece.type, piece.team, i, j, piece.direction, piece.damageStatus, 1); } } } @@ -20,12 +20,13 @@ BoardDisplay.prototype.setupPieces = function() { // Method to add a single piece to the screen using SVG // --------------------------------------------------- -BoardDisplay.prototype.addPiece = function(type, team, row, col, rotation, damageStatus) { +BoardDisplay.prototype.addPiece = function(type, team, row, col, rotation, damageStatus, scale) { const top = this.boardSurround + this.tileBorder/2 + (this.gridSize + this.tileBorder * 2) * row; const left = this.boardSurround + this.tileBorder/2 + (this.gridSize + this.tileBorder * 2) * col; const pieceID = 'piece' + ('0' + row).slice(-2) + ('0' + col).slice(-2); - this.pieces[pieceID] = new PieceSVG(type, team, pieceID, top, left, 1, rotation, damageStatus, this.gridSize, this.tileBorder, this.boardSurround); + this.pieces[pieceID] = new PieceSVG(type, team, pieceID, top, left, scale, rotation, damageStatus, this.gridSize, this.tileBorder, this.boardSurround); this.node.appendChild(this.pieces[pieceID].svg); + return this.pieces[pieceID]; } // Method to move a single SVG piece on the screen diff --git a/whirlpool.js b/whirlpool.js index de7d64c..d696050 100644 --- a/whirlpool.js +++ b/whirlpool.js @@ -14,11 +14,10 @@ let whirlpool = { // Method to create / move whirlpools // ---------------------------------- - manageWhirlpools: function() { + manageWhirlpools: async function() { if (settings.workFlow === true) {console.log('Managing whirlpools: ' + (Date.now() - settings.launchTime)); } const stockTotalPosition = stockDashboard.pieceTotals.findIndex(fI => fI.team == 'total'); - // Choose whirlpool position for a quadrant let whirlpoolPosition = (rowAdd, colAdd) => { @@ -45,14 +44,18 @@ let whirlpool = { quadrant = this.positions[quadrant]; const coords = whirlpoolPosition(quadrant.addRow, quadrant.addCol); + await game.boardDisplay.scrollWindow(coords[0]); if (stockDashboard.pieceTotals[stockTotalPosition].pieces.whirlpool.quantity < 4) { - new Move({row: coords[0], col: coords[1]}, {row: coords[0], col: coords[1]}, 'addWhirlpool', {}).process(); + await new Move({row: coords[0], col: coords[1]}, {row: coords[0], col: coords[1]}, 'addWhirlpool', {}).process(); } else { - new Move({row: quadrant.row, col: quadrant.col, piece: null}, {row: coords[0], col: coords[1], piece: null}, 'moveWhirlpool', {}).process(); + await new Move({row: quadrant.row, col: quadrant.col, piece: null}, {row: coords[0], col: coords[1], piece: null}, 'moveWhirlpool', {}).process(); } [quadrant.row, quadrant.col] = coords; } + return; }, + + // LAST BRACKET OF OBJECT }