Skip to content

Instantly share code, notes, and snippets.

@ViniciusFXavier
Last active June 8, 2023 05:59
Show Gist options
  • Save ViniciusFXavier/110fddfcd4a0f5e71a0a908ad7ed6ed4 to your computer and use it in GitHub Desktop.
Save ViniciusFXavier/110fddfcd4a0f5e71a0a908ad7ed6ed4 to your computer and use it in GitHub Desktop.
Gas Spread Simulation
<!DOCTYPE html>
<html>
<head>
<title>Flow Field Simulation</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="gridCanvas" width="800" height="600"></canvas>
<div id="info" style="position: absolute; top: 10px; left: 10px;"></div>
<script>
const canvas = document.getElementById('gridCanvas');
const ctx = canvas.getContext('2d');
const gridWidth = 10;
const gridHeight = 10;
const flowField = [];
for (let x = 0; x < gridWidth; x++) {
flowField[x] = [];
for (let y = 0; y < gridHeight; y++) {
flowField[x][y] = {
dx: 0,
dy: 0,
gases: {
oxygen: 0,
carbonDioxide: 0
}
};
}
}
const gasSources = [{ x: 2, y: 2 }];
const gasSinks = [{ x: 1, y: 8 }, { x: 8, y: 8 }];
canvas.addEventListener('mousemove', handleMouseMove);
function handleMouseMove(event) {
const rect = canvas.getBoundingClientRect();
const tileSize = Math.min(canvas.width / gridWidth, canvas.height / gridHeight);
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
const tileX = Math.floor(mouseX / tileSize);
const tileY = Math.floor(mouseY / tileSize);
const gases = flowField[tileX][tileY].gases;
const infoDiv = document.getElementById('info');
infoDiv.innerText = `Tile Position: [${tileX}, ${tileY}]\nOxygen: ${gases.oxygen}\nCarbon Dioxide: ${gases.carbonDioxide}`;
}
function updateFlowField() {
for (let x = 0; x < gridWidth; x++) {
for (let y = 0; y < gridHeight; y++) {
if (!isGasSource(x, y)) {
let totalFlowX = 0;
let totalFlowY = 0;
gasSources.forEach(source => {
const distanceX = x - source.x;
const distanceY = y - source.y;
const distanceSquared = distanceX * distanceX + distanceY * distanceY;
const flowX = distanceX / distanceSquared;
const flowY = distanceY / distanceSquared;
totalFlowX += flowX;
totalFlowY += flowY;
});
flowField[x][y].dx = totalFlowX;
flowField[x][y].dy = totalFlowY;
}
}
}
}
function renderFlowField() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const tileSize = Math.min(canvas.width / gridWidth, canvas.height / gridHeight);
for (let x = 0; x < gridWidth; x++) {
for (let y = 0; y < gridHeight; y++) {
const cellCenterX = (x + 0.5) * tileSize;
const cellCenterY = (y + 0.5) * tileSize;
const arrowLength = tileSize * 0.3;
const flowX = flowField[x][y].dx;
const flowY = flowField[x][y].dy;
ctx.save();
ctx.translate(cellCenterX, cellCenterY);
if (isGasSource(x, y)) {
// Desenhar um quadrado nas fontes de gás (entradas)
ctx.fillStyle = 'blue';
ctx.fillRect(-tileSize * 0.25, -tileSize * 0.25, tileSize * 0.5, tileSize * 0.5);
} else if (gasSinks.some(sink => sink.x === x && sink.y === y)) {
// Desenhar um círculo nos sumidouros de gás (saídas)
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(0, 0, tileSize * 0.25, 0, Math.PI * 2);
ctx.fill();
}
// Desenhar a seta indicando o fluxo do campo de fluxo
ctx.fillStyle = 'black';
ctx.rotate(Math.atan2(flowY, flowX));
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(arrowLength, arrowLength * 0.5);
ctx.lineTo(arrowLength, -arrowLength * 0.5);
ctx.closePath();
ctx.fill();
ctx.restore();
}
}
}
function isGasSource(x, y) {
return gasSources.some(source => source.x === x && source.y === y);
}
function animate() {
updateFlowField();
renderFlowField();
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Gas Spread Simulation</title>
<style>
canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="gridCanvas" width="800" height="600"></canvas>
<script>
const canvas = document.getElementById('gridCanvas');
const ctx = canvas.getContext('2d');
const gridWidth = 10;
const gridHeight = 10;
const gasLevels = [];
for (let x = 0; x < gridWidth; x++) {
gasLevels[x] = [];
for (let y = 0; y < gridHeight; y++) {
gasLevels[x][y] = {
oxygen: 0,
carbonDioxide: 0,
nitrogen: 0
};
}
}
function updateGasSpread() {
for (let x = 0; x < gridWidth; x++) {
for (let y = 0; y < gridHeight; y++) {
const currentTileGasLevels = gasLevels[x][y];
const neighbors = getNeighbors(x, y);
const totalNeighbors = neighbors.length;
const oxygenToSpread = currentTileGasLevels.oxygen / totalNeighbors;
const carbonDioxideToSpread = currentTileGasLevels.carbonDioxide / totalNeighbors;
const nitrogenToSpread = currentTileGasLevels.nitrogen / totalNeighbors;
neighbors.forEach(neighbor => {
if (neighbor.x >= 0 && neighbor.y >= 0 && gasLevels[neighbor.x] && gasLevels[neighbor.x][neighbor.y]) {
gasLevels[neighbor.x][neighbor.y].oxygen += oxygenToSpread;
gasLevels[neighbor.x][neighbor.y].carbonDioxide += carbonDioxideToSpread;
gasLevels[neighbor.x][neighbor.y].nitrogen += nitrogenToSpread;
}
});
currentTileGasLevels.oxygen -= oxygenToSpread * totalNeighbors;
currentTileGasLevels.carbonDioxide -= carbonDioxideToSpread * totalNeighbors;
currentTileGasLevels.nitrogen -= nitrogenToSpread * totalNeighbors;
}
}
}
function renderGrid() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const tileSize = Math.min(canvas.width / gridWidth, canvas.height / gridHeight);
for (let x = 0; x < gridWidth; x++) {
for (let y = 0; y < gridHeight; y++) {
const tileGasLevels = gasLevels[x][y];
const tileColor = calculateTileColor(tileGasLevels);
ctx.fillStyle = tileColor;
ctx.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
}
}
}
function animate() {
updateGasSpread();
renderGrid();
// gasLevels[0][0].oxygen = 1
// gasLevels[5][5].carbonDioxide = 0.5
// gasLevels[9][9].nitrogen = 0.5
requestAnimationFrame(animate);
}
function calculateTileColor(gasLevels) {
const oxygenLevel = gasLevels.oxygen;
const carbonDioxideLevel = gasLevels.carbonDioxide;
const nitrogenLevel = gasLevels.nitrogen;
const totalGas = oxygenLevel + carbonDioxideLevel;
const oxygenPercentage = oxygenLevel / totalGas;
const carbonDioxidePercentage = carbonDioxideLevel / totalGas;
const nitrogenPercentage = nitrogenLevel / totalGas;
const red = Math.round(oxygenPercentage * 255);
const green = Math.round(carbonDioxidePercentage * 255);
const blue = Math.round(nitrogenPercentage * 255);
return `rgb(${red}, ${green}, ${blue})`;
}
function getNeighbors(x, y) {
// Implement your logic to get the neighboring tiles of (x, y)
// Return an array of neighbor objects with x and y coordinates
return [{ x: x - 1, y }, { x: x + 1, y }, { x, y: y - 1 }, { x, y: y + 1 }];
}
canvas.addEventListener('click', function (event) {
const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
const clickX = (event.clientX - rect.left) * scaleX;
const clickY = (event.clientY - rect.top) * scaleY;
const tileSize = Math.min(canvas.width / gridWidth, canvas.height / gridHeight);
const clickedTileX = Math.floor(clickX / tileSize);
const clickedTileY = Math.floor(clickY / tileSize);
gasLevels[clickedTileX][clickedTileY].oxygen = 1; // Adiciona 1 de oxigênio ao tile clicado
console.log(gasLevels[2][2])
});
animate();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Árvore de Habilidades</title>
<style>
#skill-tree {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="skill-tree" width="500" height="400"></canvas>
<script>
// Configurações do canvas
const canvas = document.getElementById('skill-tree');
const ctx = canvas.getContext('2d');
const nodeSize = 40;
const nodeSpacing = 60;
// Função para desenhar um nó na tela
function drawNode(x, y, label) {
ctx.beginPath();
ctx.arc(x, y, nodeSize, 0, 2 * Math.PI);
ctx.stroke();
ctx.fillText(label, x, y);
}
// Função para desenhar uma conexão entre dois nós
function drawConnection(x1, y1, x2, y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
// Exemplo de dados para a árvore de habilidades
const skillTree = [
{ label: 'Habilidade A', x: 200, y: 100, connections: [1, 2] },
{ label: 'Habilidade B', x: 100, y: 200, connections: [2] },
{ label: 'Habilidade C', x: 300, y: 200, connections: [3] },
{ label: 'Habilidade D', x: 200, y: 300, connections: [] }
];
// Função para desenhar a árvore de habilidades
function drawSkillTree() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < skillTree.length; i++) {
const node = skillTree[i];
const x1 = node.x;
const y1 = node.y;
drawNode(x1, y1, node.label);
for (let j = 0; j < node.connections.length; j++) {
const connectedNode = skillTree[node.connections[j]];
const x2 = connectedNode.x;
const y2 = connectedNode.y;
drawConnection(x1, y1, x2, y2);
}
}
}
// Chamada inicial para desenhar a árvore de habilidades
drawSkillTree();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment