Skip to content

Commit

Permalink
Web-Based Version
Browse files Browse the repository at this point in the history
  • Loading branch information
KhamessiTaha committed Jul 31, 2024
1 parent 7324dd4 commit 5f8ec1e
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 1 deletion.
175 changes: 175 additions & 0 deletions Web-Based Version/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
const particles = [];
const grid = Array.from({ length: height }, () => Array(width).fill(null));


const particleTypes = {
sand: { color: 'yellow', density: 2 },
water: { color: 'blue', density: 1 },
fire: { color: 'red', density: 0 },
oil: { color: 'brown', density: 1 },
wall: { color: 'gray', density: Infinity },
acid: { color: 'green', density: 1 },
gas: { color: 'lightgray', density: 0 }
};

class Particle {
constructor(x, y, type) {
this.x = x;
this.y = y;
this.type = type;
this.color = particleTypes[type].color;
this.density = particleTypes[type].density;
}

update() {
if (this.type === 'sand' || this.type === 'water' || this.type === 'oil' || this.type === 'acid') {
this.fall();
} else if (this.type === 'fire') {
this.spread();
this.burn();
} else if (this.type === 'gas') {
this.rise();
}
}

fall() {
if (this.y < height - 1 && (!grid[this.y + 1][this.x] || grid[this.y + 1][this.x].density < this.density)) {
grid[this.y][this.x] = null;
this.y += 1;
grid[this.y][this.x] = this;
}
}

rise() {
if (this.y > 0 && (!grid[this.y - 1][this.x] || grid[this.y - 1][this.x].density > this.density)) {
grid[this.y][this.x] = null;
this.y -= 1;
grid[this.y][this.x] = this;
}
}

spread() {
const spreadDirections = [
{ dx: 0, dy: -1 }, // up
{ dx: 1, dy: 0 }, // right
{ dx: 0, dy: 1 }, // down
{ dx: -1, dy: 0 } // left
];

for (let dir of spreadDirections) {
const newX = this.x + dir.dx;
const newY = this.y + dir.dy;
if (newX >= 0 && newX < width && newY >= 0 && newY < height) {
const neighbor = grid[newY][newX];
if (neighbor && neighbor.type === 'oil') {
grid[newY][newX] = new Particle(newX, newY, 'fire');
particles.push(grid[newY][newX]);
}
}
}
}

burn() {
if (this.y < height - 1 && grid[this.y + 1][this.x] && grid[this.y + 1][this.x].type === 'oil') {
grid[this.y + 1][this.x] = new Particle(this.x, this.y + 1, 'fire');
particles.push(grid[this.y + 1][this.x]);
}
}

draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, 1, 1);
}
}

function addParticle(x, y, type) {
if (x >= 0 && x < width && y >= 0 && y < height && !grid[y][x]) {
const particle = new Particle(x, y, type);
particles.push(particle);
grid[y][x] = particle;
}
}

function addParticleCluster(x, y, type, size = 5) {
for (let dx = -size; dx <= size; dx++) {
for (let dy = -size; dy <= size; dy++) {
if (Math.sqrt(dx * dx + dy * dy) <= size) {
addParticle(x + dx, y + dy, type);
}
}
}
}

let isMouseDown = false;

canvas.addEventListener('mousedown', (e) => {
isMouseDown = true;
const rect = canvas.getBoundingClientRect();
const x = Math.floor(e.clientX - rect.left);
const y = Math.floor(e.clientY - rect.top);
addParticleCluster(x, y, selectedType);
});

canvas.addEventListener('mouseup', () => {
isMouseDown = false;
});

canvas.addEventListener('mousemove', (e) => {
if (isMouseDown) {
const rect = canvas.getBoundingClientRect();
const x = Math.floor(e.clientX - rect.left);
const y = Math.floor(e.clientY - rect.top);
addParticleCluster(x, y, selectedType);
}
});

let selectedType = 'sand';

function selectType(type) {
selectedType = type;
document.getElementById('colorIndicator').style.backgroundColor = particleTypes[type].color;
}


document.getElementById('colorIndicator').style.backgroundColor = particleTypes[selectedType].color;

let simulationRunning = true;

function startSimulation() {
simulationRunning = true;
}

function pauseSimulation() {
simulationRunning = false;
}

function resetSimulation() {
particles.length = 0;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
grid[y][x] = null;
}
}
}

function clearSimulation() {
resetSimulation();
ctx.clearRect(0, 0, width, height);
}

function gameLoop() {
if (simulationRunning) {
ctx.clearRect(0, 0, width, height);
particles.forEach(particle => {
particle.update();
particle.draw();
});
}
requestAnimationFrame(gameLoop);
}

gameLoop();
Empty file.
27 changes: 27 additions & 0 deletions Web-Based Version/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ParticleSimulator by Taha</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="toolbar">
<button onclick="selectType('sand')">Sand</button>
<button onclick="selectType('water')">Water</button>
<button onclick="selectType('fire')">Fire</button>
<button onclick="selectType('oil')">Oil</button>
<button onclick="selectType('wall')">Wall</button>
<button onclick="selectType('acid')">Acid</button>
<button onclick="selectType('gas')">Gas</button>
<button onclick="startSimulation()">Start</button>
<button onclick="pauseSimulation()">Pause</button>
<button onclick="resetSimulation()">Reset</button>
<button onclick="clearSimulation()">Clear</button>
<div id="colorIndicator"></div>
</div>
<canvas id="gameCanvas" width="800" height="600"></canvas>
<script src="app.js"></script>
</body>
</html>
23 changes: 23 additions & 0 deletions Web-Based Version/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
body {
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
margin: 0;
background-color: #575757;
}

#toolbar {
margin-bottom: 10px;
}

canvas {
border: 1px solid black;
}
#colorIndicator {
width: 20px;
height: 20px;
display: inline-block;
margin-left: 10px;
border: 1px solid #000;
}
2 changes: 1 addition & 1 deletion src/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
pygame.init()

WIDTH, HEIGHT = 800, 600
CELL_SIZE = 2 # Smaller cell size for smaller particles
CELL_SIZE = 2
GRID_WIDTH = WIDTH // CELL_SIZE
GRID_HEIGHT = HEIGHT // CELL_SIZE
screen = pygame.display.set_mode((WIDTH, HEIGHT))
Expand Down

0 comments on commit 5f8ec1e

Please sign in to comment.