feat: Agent rotation, fix: Product icons
This commit is contained in:
parent
cee48874c5
commit
ef225fc850
@ -7,14 +7,16 @@
|
||||
|
||||
<!-- Styles -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;400&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;400&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css">
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
<link rel="stylesheet" href="fontawesome/css/all.min.css">
|
||||
<!-- <link rel="stylesheet" href="fontawesome/css/all.min.css"> -->
|
||||
|
||||
|
||||
<!-- Modules -->
|
||||
<script src="modules/configuration.js"></script>
|
||||
<script src="modules/utilities.js"></script>
|
||||
<script src="modules/product.js"></script>
|
||||
|
||||
<script src="modules/floor.js"></script>
|
||||
<script src="modules/grid.js"></script>
|
||||
|
@ -1,4 +1,4 @@
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
window.addEventListener('DOMContentLoaded', () => document.fonts.ready.then(() => {
|
||||
const floorCanvas = document.getElementById('canvas-floor');
|
||||
const gridCanvas = document.getElementById('canvas-grid');
|
||||
const agentCanvas = document.getElementById('canvas-agent');
|
||||
@ -8,4 +8,4 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
const grid = new Grid(gridCanvas);
|
||||
const agent = new Agent(agentCanvas);
|
||||
const products = new Products(productsCanvas);
|
||||
});
|
||||
}));
|
@ -2,12 +2,47 @@ class Agent extends AgentController {
|
||||
constructor(canvas) {
|
||||
super(canvas);
|
||||
|
||||
let { x, y } = Grid.instance.randomPlace();
|
||||
this.moveTo(x, y);
|
||||
const cycle = async () => {
|
||||
|
||||
this.onDestinationReached(() => {
|
||||
let { x, y } = Grid.instance.randomPlace();
|
||||
this.moveTo(x, y);
|
||||
})
|
||||
await this.takeFromStore(Product.RANDOM_FROM_REGISTRY(), Math.floor(Math.random() * 40) + 10);
|
||||
const randomPlace = Grid.instance.randomPlace();
|
||||
await this.deliver(randomPlace.x, randomPlace.y);
|
||||
|
||||
await waitFor(2000);
|
||||
cycle();
|
||||
};
|
||||
|
||||
cycle();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nakaż agentowi przejść na wybraną pozycję
|
||||
* @param {number} x Współrzędna x
|
||||
* @param {number} y Współrzędna y
|
||||
*/
|
||||
moveTo(x, y) {
|
||||
return super.moveTo(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nakaż agentowi dostarczyć produkt, który aktualnie niesie na wybraną pozycję
|
||||
* @param {number} x Współrzędna x
|
||||
* @param {number} y Współrzędna y
|
||||
*/
|
||||
async deliver(x, y) {
|
||||
await this.moveTo(x, y);
|
||||
this.ownedProductAmount = 0;
|
||||
this.ownedProduct = Product.REGISTRY.empty;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} product
|
||||
*/
|
||||
async takeFromStore(product, amount) {
|
||||
await this.moveTo(6, 8);
|
||||
this.ownedProductAmount = amount;
|
||||
this.ownedProduct = product;
|
||||
}
|
||||
}
|
@ -1,14 +1,25 @@
|
||||
class AgentController {
|
||||
constructor(canvas) {
|
||||
// Inicjalizacja
|
||||
this.ctx = canvas.getContext('2d');
|
||||
this.events = {
|
||||
'ON_DESTINATION_REACHED': [],
|
||||
};
|
||||
|
||||
this.setCanvasSize(canvas);
|
||||
|
||||
this.position = { x: 6, y: 0 };
|
||||
this.ownedProduct = Product.REGISTRY.empty;
|
||||
this.ownedProductAmount = 0;
|
||||
|
||||
// Akcje
|
||||
this.actions = {
|
||||
'STATIONARY': 0,
|
||||
'IN_MOVE': 1,
|
||||
'IN_ROTATION': 2,
|
||||
}
|
||||
this.currentAction = this.actions.STATIONARY;
|
||||
|
||||
// Pozycja i poruszanie się
|
||||
this.position = { x: 6, y: 0 };
|
||||
this.rotation = { z: 0 };
|
||||
this.speed = 30;
|
||||
this.rotationSpeed = 2;
|
||||
this.update();
|
||||
}
|
||||
|
||||
@ -21,7 +32,6 @@ class AgentController {
|
||||
this.clearCanvas();
|
||||
if (this.currentPath) {
|
||||
this.drawPath(this.currentPath);
|
||||
this.updateAgentPosition();
|
||||
}
|
||||
this.drawAgent();
|
||||
|
||||
@ -29,35 +39,141 @@ class AgentController {
|
||||
}
|
||||
|
||||
updateAgentPosition() {
|
||||
const speed = 30;
|
||||
if (!this.currentPathIndex) {
|
||||
this.currentPathIndex = 0;
|
||||
}
|
||||
|
||||
let nearestPoint = this.currentPath[this.currentPathIndex];
|
||||
|
||||
if (nearestPoint) {
|
||||
this.position = {
|
||||
x: this.position.x + (Math.sign(nearestPoint.x - this.position.x)/speed),
|
||||
y: this.position.y + (Math.sign(nearestPoint.y - this.position.y)/speed)
|
||||
return new Promise((resolve, reject) => {
|
||||
const cycle = async () => {
|
||||
if (!this.currentPathIndex) {
|
||||
this.currentPathIndex = 0;
|
||||
}
|
||||
|
||||
let nearestPoint = this.currentPath[this.currentPathIndex];
|
||||
|
||||
if (nearestPoint) {
|
||||
const requiredRotation = this.findRequiredRotation(nearestPoint);
|
||||
await this.rotate({ z: requiredRotation });
|
||||
if (!nearestPoint.options || !nearestPoint.options.isShelf) {
|
||||
await this.moveInLine(nearestPoint);
|
||||
}
|
||||
|
||||
nearestPoint = this.currentPath[++this.currentPathIndex];
|
||||
if (!nearestPoint) {
|
||||
this.currentPath = [];
|
||||
this.currentPathIndex = 0;
|
||||
this.currentAction = this.actions.STATIONARY;
|
||||
resolve();
|
||||
} else {
|
||||
cycle();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Math.abs(nearestPoint.x - this.position.x) < 0.001 && Math.abs(nearestPoint.y - this.position.y) < 0.001) {
|
||||
nearestPoint = this.currentPath[++this.currentPathIndex];
|
||||
if (!nearestPoint) {
|
||||
|
||||
cycle();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {{ x: number, y: number }} position
|
||||
*/
|
||||
moveInLine(position) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const cycle = () => {
|
||||
const { speed } = this;
|
||||
this.currentAction = this.actions.IN_MOVE;
|
||||
this.position = {
|
||||
x: this.position.x + (Math.sign(position.x - this.position.x)/speed),
|
||||
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) {
|
||||
this.position = {
|
||||
x: Math.round(this.position.x),
|
||||
y: Math.round(this.position.y)
|
||||
}
|
||||
this.currentPath = [];
|
||||
this.currentPathIndex = 0;
|
||||
this.events.ON_DESTINATION_REACHED.forEach(func => func());
|
||||
resolve();
|
||||
} else {
|
||||
requestAnimationFrame(() => cycle());
|
||||
}
|
||||
}
|
||||
|
||||
cycle();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {{ x: number, y: number }} position
|
||||
*/
|
||||
findRequiredRotation(position) {
|
||||
if (position.x == this.position.x && position.y == this.position.y) {
|
||||
return this.rotation.z;
|
||||
}
|
||||
|
||||
const compare = (a, b) => {
|
||||
return Math.abs(a - b) < 1;
|
||||
}
|
||||
|
||||
if (compare(this.position.x, position.x)) {
|
||||
if (this.position.y < position.y) {
|
||||
return 180;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (this.position.x < position.x) {
|
||||
return 90;
|
||||
} else {
|
||||
return 270;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {{ z: number}} rotation
|
||||
* @returns
|
||||
*/
|
||||
rotate(rotation) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// console.log(this.rotation); // 270
|
||||
// console.log(rotation); // 0
|
||||
|
||||
if (this.rotation.z == rotation.z) {
|
||||
resolve();
|
||||
}
|
||||
|
||||
const sign = (() => {
|
||||
if (((this.rotation.z > rotation.z) || (this.rotation.z == 0 && rotation.z == 270)) && !(this.rotation.z == 270 && rotation.z == 0)) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
})();
|
||||
|
||||
const cycle = () => {
|
||||
this.currentAction = this.actions.IN_ROTATION;
|
||||
|
||||
const oldZRotation = this.rotation.z;
|
||||
const newZRotation = rotation.z;
|
||||
|
||||
const clampRotation = (rot) => (rot + 360) % 360;
|
||||
|
||||
this.rotation = { z: clampRotation(oldZRotation + (this.rotationSpeed * sign)) };
|
||||
|
||||
if (Math.abs(oldZRotation - newZRotation) < 1) {
|
||||
resolve();
|
||||
this.rotation = { z: clampRotation(newZRotation) }
|
||||
} else {
|
||||
requestAnimationFrame(() => cycle());
|
||||
}
|
||||
}
|
||||
|
||||
cycle();
|
||||
});
|
||||
}
|
||||
|
||||
moveTo(x, y) {
|
||||
this.currentPath = this.findPathTo(x, y, this.position.x, this.position.y);
|
||||
console.log(this.currentPath);
|
||||
return this.updateAgentPosition();
|
||||
}
|
||||
|
||||
drawPath(path) {
|
||||
@ -74,8 +190,43 @@ class AgentController {
|
||||
drawAgent() {
|
||||
const {x, y} = this.position;
|
||||
const offset = 5;
|
||||
this.ctx.clearRect((x * 100) + (offset), (y * 100) + (offset), 100 - (offset * 2), 100 - (offset * 2));
|
||||
this.roundRect((x * 100) + (offset), (y * 100) + (offset), 100 - (offset * 2), 100 - (offset * 2));
|
||||
const rotation = this.rotation.z;
|
||||
|
||||
const newX = (x * 100) + (offset);
|
||||
const newY = (y * 100) + (offset);
|
||||
const w = 100 - (offset * 2);
|
||||
const h = 100 - (offset * 2);
|
||||
|
||||
this.ctx.translate(newX + (w / 2), newY + (h / 2));
|
||||
this.ctx.rotate(rotation * Math.PI / 180);
|
||||
|
||||
// Base shape
|
||||
this.ctx.clearRect(-(w / 2), -(h / 2), w, h);
|
||||
this.roundRect(-(w / 2), -(h / 2), w, h);
|
||||
|
||||
// Eyes
|
||||
// this.roundRect(10 - (w / 2), 10 - (h / 2), w / 4, h / 4);
|
||||
// this.roundRect(80 - (3 * w / 4), 10 - (h / 2), w / 4, h / 4);
|
||||
this.ctx.fillStyle = 'red';
|
||||
this.ctx.fillRect(-(w/2) + 20, (-h/2) - 10, w - 40, 10);
|
||||
|
||||
this.ctx.rotate(-rotation * Math.PI / 180);
|
||||
|
||||
// Product
|
||||
this.ctx.font = '900 40px "Font Awesome 5 Free"';
|
||||
this.ctx.textAlign = 'center';
|
||||
this.ctx.fillStyle = 'white';
|
||||
this.ctx.fillText(this.ownedProduct.icon, 0, 15);
|
||||
|
||||
// Amount
|
||||
if (this.ownedProductAmount) {
|
||||
this.ctx.font = '20px Montserrat';
|
||||
this.ctx.textAlign = 'left';
|
||||
this.ctx.fillStyle = 'white';
|
||||
this.ctx.fillText(this.ownedProductAmount, 10, 35);
|
||||
}
|
||||
|
||||
this.ctx.translate(-(newX + (w / 2)), -(newY + (h / 2)));
|
||||
}
|
||||
|
||||
findPathTo(dx, dy, sx, sy) {
|
||||
@ -119,10 +270,6 @@ class AgentController {
|
||||
}
|
||||
}
|
||||
|
||||
onDestinationReached(func) {
|
||||
this.events.ON_DESTINATION_REACHED.push(func);
|
||||
}
|
||||
|
||||
clearCanvas() {
|
||||
this.ctx.clearRect(0, 0, 2000, 900);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class Grid {
|
||||
const x = Math.floor(Math.random() * this.grid.length);
|
||||
const y = Math.floor(Math.random() * this.grid[0].length);
|
||||
const rand = this.grid[x][y];
|
||||
if (rand === GRID_FIELD_TYPE.SHELF || rand === GRID_FIELD_TYPE.PATH) {
|
||||
if (rand === GRID_FIELD_TYPE.SHELF) {
|
||||
return { x, y };
|
||||
}
|
||||
return this.randomPlace();
|
||||
|
29
src/modules/product.js
Normal file
29
src/modules/product.js
Normal file
@ -0,0 +1,29 @@
|
||||
class Product {
|
||||
/**
|
||||
* Stwórz produkt o określonej nazwie i ikonie
|
||||
* @param {string} name
|
||||
* @param {string} icon
|
||||
* @example const product = new Product('apple', 'fa-apple')
|
||||
*/
|
||||
constructor(name, icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
static get REGISTRY() {
|
||||
return {
|
||||
empty: new Product('', ''),
|
||||
apple: new Product('apple', '\uf5d1'),
|
||||
bacon: new Product('bacon', '\uf7e5'),
|
||||
bone: new Product('bone', '\uf5d7'),
|
||||
bread: new Product('bread', '\uf7ec'),
|
||||
candyCane: new Product('candy cane', '\uf786'),
|
||||
carrot: new Product('carrot', '\uf787'),
|
||||
cheese: new Product('cheese', '\uf7ef')
|
||||
};
|
||||
}
|
||||
|
||||
static RANDOM_FROM_REGISTRY() {
|
||||
return Product.REGISTRY[Object.keys(Product.REGISTRY).filter(p => p !== 'empty')[Math.floor(Math.random() * (Object.keys(Product.REGISTRY).length - 1))]];
|
||||
}
|
||||
}
|
@ -2,27 +2,27 @@ class Products {
|
||||
|
||||
constructor(canvas) {
|
||||
this.gridProducts = [
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i'],
|
||||
['a','', 'c', 'd', '', 'f', 'g', '', 'i']
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
['','', '', '', '', '', '', '', ''],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
['','', '', '', '', '', '', '', ''],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()],
|
||||
[Product.RANDOM_FROM_REGISTRY(),'', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY(), Product.RANDOM_FROM_REGISTRY(), '', Product.RANDOM_FROM_REGISTRY()]
|
||||
];
|
||||
|
||||
this.gridProductsAmount = []
|
||||
@ -76,7 +76,7 @@ class Products {
|
||||
|
||||
product(x, y, v, productsKey, productsValue) {
|
||||
let fontSize = 40;
|
||||
this.ctx.font = `${fontSize}px Montserrat`;
|
||||
this.ctx.font = `900 ${fontSize}px "Font Awesome 5 Free"`;
|
||||
this.ctx.textAlign = "center";
|
||||
if (v <= 10){
|
||||
this.ctx.fillStyle = '#ff0000';
|
||||
@ -89,7 +89,7 @@ class Products {
|
||||
}
|
||||
let productsColumn = this.gridProducts[productsKey];
|
||||
let prdct = productsColumn[productsValue];
|
||||
this.ctx.fillText(prdct, x+50, y+60);
|
||||
this.ctx.fillText(prdct.icon, x+50, y+60);
|
||||
}
|
||||
|
||||
clearCanvas() {
|
||||
@ -102,4 +102,8 @@ class Products {
|
||||
count: this.gridProductsAmount[x][y]
|
||||
}
|
||||
}
|
||||
|
||||
setProductAt(product, count, x, y) {
|
||||
// TODO: Implement this function
|
||||
}
|
||||
}
|
@ -21,3 +21,14 @@ function fromTable(header, ...rows) {
|
||||
function clamp(v, lo, hi) {
|
||||
return v <= lo ? lo : v >= hi ? hi : v
|
||||
}
|
||||
|
||||
/**
|
||||
* Async timeout function
|
||||
* @param {number} miliseconds Number of miliseconds to wait
|
||||
* @returns
|
||||
*/
|
||||
function waitFor(miliseconds) {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => resolve(), miliseconds);
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user