From 49a12b1b9211790f1741d388bcaff5c310343378 Mon Sep 17 00:00:00 2001 From: Marcin Czerniak Date: Mon, 10 May 2021 18:39:21 +0200 Subject: [PATCH] feat: Time management --- src/configuration.js | 4 +-- src/index.html | 29 +++++++++++++++++ src/logic/agent.js | 15 ++++++--- src/logic/pathfinding.js | 13 ++++---- src/logic/time.js | 64 +++++++++++++++++++++++++++++++++++++ src/main.js | 3 +- src/styles.css | 43 +++++++++++++++++++++++++ src/view/agentController.js | 52 +++++++++++++++++++++++------- src/view/timeController.js | 19 +++++++++++ 9 files changed, 217 insertions(+), 25 deletions(-) create mode 100644 src/logic/time.js create mode 100644 src/view/timeController.js diff --git a/src/configuration.js b/src/configuration.js index fbec95d..e98437a 100644 --- a/src/configuration.js +++ b/src/configuration.js @@ -6,6 +6,6 @@ const StorageCenterLocation = { x: 7, y: 8, w: UnitsInGroupCount, h: 1 } const UnitsCount = ((ColumnsOfGroupsCount * RowsOfGroupsCount) * UnitsInGroupCount - StorageCenterLocation.w * StorageCenterLocation.h) -const AgentMoveSpeed = 20 /* 1 - slowest, 89 - fastest */ -const AgentRotationSpeed = 20 /* 1 - slowest, 89 - fastest */ +const AgentMoveSpeed = 40 /* 1 - slowest, 89 - fastest */ +const AgentRotationSpeed = 40 /* 1 - slowest, 89 - fastest */ const AgentWaitTime = 500 /* in miliseconds */ diff --git a/src/index.html b/src/index.html index 6913b2e..31798be 100644 --- a/src/index.html +++ b/src/index.html @@ -18,10 +18,12 @@ + + @@ -43,7 +45,34 @@
+
logo +
+
+ Time management + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ Day: + + +
+ +
+
diff --git a/src/logic/agent.js b/src/logic/agent.js index 5db31e0..260d520 100644 --- a/src/logic/agent.js +++ b/src/logic/agent.js @@ -1,21 +1,27 @@ class Agent extends AgentController { + + static instance; + constructor(canvas) { super(canvas); + Agent.instance = this; + const cycle = async () => { const jobRequest = Products.instance.getJobRequest(); if (jobRequest) { const requiredAmount = 50 - jobRequest.amount; await this.takeFromStore(jobRequest.product, requiredAmount); await this.deliver(jobRequest.x, jobRequest.y); + } else { + await waitFor(1000); } - await waitFor(AgentWaitTime); + await waitFor(this.waitTime); cycle(); }; setTimeout(() => cycle(), 2000); - } /** @@ -34,8 +40,9 @@ class Agent extends AgentController { */ async deliver(x, y) { await this.moveTo(x, y); - await waitFor(AgentWaitTime); + await waitFor(this.waitTime); Products.instance.exchange(x, y, this.ownedProduct, 50); + this.ownedProductAmount = 0; this.ownedProduct = Product.REGISTRY.empty; } @@ -46,7 +53,7 @@ class Agent extends AgentController { */ async takeFromStore(product, amount) { await this.moveTo(9, 8); - await waitFor(AgentWaitTime); + await waitFor(this.waitTime); this.ownedProductAmount = amount; this.ownedProduct = product; } diff --git a/src/logic/pathfinding.js b/src/logic/pathfinding.js index 83143c2..817df29 100644 --- a/src/logic/pathfinding.js +++ b/src/logic/pathfinding.js @@ -34,10 +34,12 @@ class Pathfinding { for (const successor of this.successor(elem)) { if (!Pathfinding.isNodeInArr(successor, explored) && !Pathfinding.isNodeInArr(successor, fringe)) { - Pathfinding.insertWithPriority(successor, fringe, expectedNode); + Pathfinding.insertWithPriority(successor, fringe); } else if (Pathfinding.isNodeInArr(successor, fringe)) { - const index = Pathfinding.findIndefOf(successor, fringe); - fringe.splice(index, 1, successor); + const index = Pathfinding.findIndexOf(successor, fringe); + if (successor.totalCost < fringe[index].totalCost) { + fringe.splice(index, 1, successor); + } } } } @@ -47,11 +49,11 @@ class Pathfinding { return !arr.every(n => !Pathfinding.reached(n.state, node.state)) } - static findIndefOf(node, arr) { + static findIndexOf(node, arr) { return arr.findIndex(n => Pathfinding.reached(n.state, node.state)); } - static insertWithPriority(node, arr, destination) { + static insertWithPriority(node, arr) { for (const [i, n] of arr.entries()) { if (node.totalCost < n.totalCost) { arr.splice(i, 0, node); @@ -108,7 +110,6 @@ class Pathfinding { currentElement = currentElement.parent; } - console.log(result); return result; } diff --git a/src/logic/time.js b/src/logic/time.js new file mode 100644 index 0000000..0cd06f1 --- /dev/null +++ b/src/logic/time.js @@ -0,0 +1,64 @@ +class Time { + + isPaused = false; + timeMultiplier = 1; + day = 0; + + static instance; + + constructor() { + Time.instance = this; + } + + /** + * Pause app + */ + pause() { + this.isPaused = true; + } + + + /** + * Resume from pause state + */ + resume() { + this.setMultiplier(1); + } + + /** + * Get animation frame base on pase state + */ + requestAnimationFrame(func) { + if (!this.isPaused) { + return window.requestAnimationFrame(func); + } else { + return window.requestAnimationFrame(() => { + Time.instance.requestAnimationFrame(func); + }) + } + } + + /** + * multiply agent action speed + */ + setMultiplier(multiplier) { + this.isPaused = false; + this.timeMultiplier = multiplier; + } + + /** + * Set day + */ + setDay(day) { + this.day = Number(day); + TimeController.instance.bindTime(); + } + + /** + * Add days + */ + addDays(days) { + this.setDay(this.day += Number(days)); + } + +} \ No newline at end of file diff --git a/src/main.js b/src/main.js index f497528..30a1b6e 100644 --- a/src/main.js +++ b/src/main.js @@ -6,13 +6,14 @@ window.addEventListener('DOMContentLoaded', () => document.fonts.load('900 14px const costCanvas = document.getElementById('canvas-costmap'); const costMap = new CostMap(); + const time = new Time(); + const timeController = new TimeController(); const costMapVisualisation = new CostMapVisualisation(costCanvas); const floor = new Floor(floorCanvas); const grid = new Grid(gridCanvas); const agent = new Agent(agentCanvas); const products = new Products(productsCanvas); - const fpsElement = document.getElementById('fps'); if (window.location.hash == '#debug') { displayFPS(fpsElement); diff --git a/src/styles.css b/src/styles.css index 15ccfb9..ce2822b 100644 --- a/src/styles.css +++ b/src/styles.css @@ -41,6 +41,49 @@ main { align-items: flex-end; } +.header-line { + flex-grow: 1; + display: flex; + padding: 32px; + flex: 1; +} + +.header-line fieldset { + display: flex; + gap: 5px; + justify-content: center; + border-radius: 10px; + border-color: #E9F116; +} + +.header-line div { + padding: 0 20px 0 0; +} + +.header-line .button { + cursor: pointer; + padding: 5px; + border-radius: 50%; + width: 20px; + height: 20px; + display: flex; + justify-content: center; + align-items: center; +} + +.header-line .button:hover { + background-color: #0A0A0A; +} + +.header-line input { + background-color: transparent; + border: 0; + border-bottom: 1px solid yellow; + width: 50px; + color: yellow; + outline: 0; +} + .logs-label { margin: 0 20px 30px 10px; } diff --git a/src/view/agentController.js b/src/view/agentController.js index 5a132b8..dc6e81e 100644 --- a/src/view/agentController.js +++ b/src/view/agentController.js @@ -15,14 +15,24 @@ class AgentController { } this.currentAction = this.actions.STATIONARY; - // Pozycja i poruszanie siÄ™ + // Pozycja i rotacja this.position = { x: 6, y: 0 }; this.rotation = { z: 0 }; - this.speed = 90 - AgentMoveSpeed; - this.rotationSpeed = 90 / ( 90 - AgentRotationSpeed); this.update(); } + get speed() { + return 90 - clamp(AgentMoveSpeed * Time.instance.timeMultiplier, 0, 89); + } + + get rotationSpeed() { + return 90 / ( 90 - clamp(AgentRotationSpeed * Time.instance.timeMultiplier, 0, 88)); + } + + get waitTime() { + return AgentWaitTime / (Time.instance.timeMultiplier * 2); + } + setCanvasSize (canvas) { canvas.width = 2000; canvas.height = 900; @@ -35,7 +45,7 @@ class AgentController { } this.drawAgent(); - requestAnimationFrame(this.update.bind(this)); + Time.instance.requestAnimationFrame(this.update.bind(this)); } updateAgentPosition() { @@ -78,6 +88,11 @@ class AgentController { * @param {{ x: number, y: number }} position */ moveInLine(position, actionCost) { + const vector = { + x: Math.sign(position.x - this.position.x), + y: Math.sign(position.y - this.position.y) + } + return new Promise((resolve, reject) => { const cycle = () => { let { speed } = this; @@ -89,14 +104,20 @@ class AgentController { y: this.position.y + (Math.sign(position.y - this.position.y)/speed) } - if (Math.abs(position.x - this.position.x) < 0.001 && Math.abs(position.y - this.position.y) < 0.001) { + if ( + (vector.x > 0 && this.position.x > position.x) || + (vector.x < 0 && this.position.x < position.x) || + (vector.y > 0 && this.position.y > position.y) || + (vector.y < 0 && this.position.y < position.y) || + (Math.sign(position.y - this.position.y) == 0 && Math.sign(position.x - this.position.x) == 0) + ) { this.position = { - x: Math.round(this.position.x), - y: Math.round(this.position.y) + x: Math.round(position.x), + y: Math.round(position.y) } resolve(); } else { - requestAnimationFrame(() => cycle()); + Time.instance.requestAnimationFrame(() => cycle()); } } @@ -146,6 +167,8 @@ class AgentController { const sign = (() => { if (((this.rotation.z > rotation.z) || (this.rotation.z == 0 && rotation.z == 270)) && !(this.rotation.z == 270 && rotation.z == 0)) { return -1; + } else if (this.rotation.z == rotation.z) { + return 0; } return 1; })(); @@ -154,7 +177,6 @@ class AgentController { this.currentAction = this.actions.IN_ROTATION; const oldZRotation = this.rotation.z; - const newZRotation = rotation.z; const clampRotation = (rot) => (rot + 360) % 360; let { rotationSpeed } = this; @@ -162,11 +184,17 @@ class AgentController { this.rotation = { z: clampRotation(oldZRotation + (rotationSpeed * sign)) }; - if (Math.abs(oldZRotation - newZRotation) < 5) { + if ( + (sign > 0 && rotation.z != 0 && this.rotation.z > rotation.z) || + (sign > 0 && rotation.z == 0 && this.rotation.z < 90) || + (sign < 0 && this.rotation.z < rotation.z) || + (sign < 0 && rotation.z == 0 && this.rotation.z > 270) || + sign == 0 + ) { resolve(); - this.rotation = { z: clampRotation(newZRotation) } + this.rotation = { z: clampRotation(rotation.z) } } else { - requestAnimationFrame(() => cycle()); + Time.instance.requestAnimationFrame(() => cycle()); } } diff --git a/src/view/timeController.js b/src/view/timeController.js new file mode 100644 index 0000000..e9655bb --- /dev/null +++ b/src/view/timeController.js @@ -0,0 +1,19 @@ +class TimeController { + + static instance; + + constructor() { + TimeController.instance = this; + this.bindTime(); + } + + bindTime() { + for(const elem of document.getElementsByClassName('bind-day')) { + elem.innerHTML = Time.instance.day; + } + } + + readFromDayInput() { + Time.instance.addDays(document.getElementById('dayInput').value); + } +} \ No newline at end of file