pbInfo.ro
Probleme
Probleme - clasa a IX-a
Probleme - clasa a X-a
Probleme - clasa a XI-a
Probleme din concursuri
Căutare problemă
Exerciții
Programează cu Blockly
Desenează cu Processing
Exersează SQL
Soluţii
Resurse
Resurse pentru clasa a IX-a
Resurse pentru clasa a X-a
Resurse pentru clasa a XI-a
Subiecte bacalaureat
Ajutor
Autentificare
Înregistrare
Autentificare
Utilizator sau email
Parola
Acest site foloseşte cookies. Navigând în continuare, vă exprimaţi acordul asupra folosirii cookie-urilor.
Îti place pbInfo? Atunci acceptă-l cu totul! Dezactivează modulul de blocare a reclamelor!
Lista scripturi
Script Nou
Ajutor
"Game of life 3D" - Processing
ID
Autor
Duplicat din
Ultima modificare
#6221
6B - Dumitrache Nicolae (Nicky_Dumitrache)
-
Vineri, 20 sep 2024, 18:12
// Dimensions of the working area (setting height to -1 will automatically detect the ratio let layerWidth = 64 let layerHeight = -1; //36 const layerCountMax = 20 // Timing constants const initialDelay = 1000 const generationDelay = 200 const transitionDelay = 500 // Example pattern const examplePattern = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ] // Current mode const Modes = { DRAW: 0, RUN: 1 } let mode = Modes.DRAW let modeTransition = 0 // Will be used as text display let textGraphics // Array containing all layers let layers // Moves all cubes to smooth out the layer adding animation let zOffset // Cube size provides a global scaling factor let cubeSize let fullCubeSize // Rotation and mouse flags let rotX, rotY, mouseDX, mouseDY // Drawing flags let colFlag // Time flag for delta calculation and // time of the last generation to keep the generation interval consistent let lastGenerationTime, timeFlag function setup() { // Make a canvas as big as the containing window using WEBGL for 3D createCanvas(this.windowWidth, this.windowHeight, WEBGL) textGraphics = createGraphics(width, 24) textGraphics.fill(255) textGraphics.textSize(24) textGraphics.textAlign(CENTER) textGraphics.text('Press SPACE to start in 3D view', width / 2, 18) // I hate these stroke lines, they're really ugly noStroke() // Set the layer height if (layerHeight === -1) layerHeight = parseInt(layerWidth / width * height) // Initialize the z offset, scale, rotation and time zOffset = 0 cubeSize = 22 rotX = -PI / 16 rotY = 0 lastGenerationTime = millis() + initialDelay - generationDelay timeFlag = millis() colFlag = 0 // Calculate the full cube size. This is the maximum cube scale to fill the entire window calcFullCubeSize() // Initialize an empty layer layers = [ [] ] for (let y = 0; y < layerHeight; y++) { let row = [] for (let x = 0; x < layerWidth; x++) { let patX = parseInt(x - layerWidth / 2 + examplePattern[0].length / 2) let patY = parseInt(y - layerHeight / 2 + examplePattern.length / 2) let val = 0 if (patX >= 0 && patX < examplePattern[0].length && patY >= 0 && patY < examplePattern.length) { val = examplePattern[patY][patX] } row.push(val) } layers[0].push(row) } } function draw() { // Delta time difference timeNow = millis() delta = timeNow - timeFlag timeFlag = timeNow // Update the mode transition if (modeTransition < 1) modeTransition += delta / transitionDelay if (modeTransition > 1) modeTransition = 1 // Calculate the perspective: 0 = 2D drawing view, 1 = 3D animation view // Values in beetween will result in a transitioning state let persp = mode === Modes.DRAW ? 1 - modeTransition : modeTransition // Calculate a new generation every generationDelay millis if (mode === Modes.RUN && millis() > lastGenerationTime + generationDelay) { doGeneration() zOffset = 1 lastGenerationTime = millis() } // Update the z offset for a smooth animation if (mode === Modes.RUN) { if (zOffset > 0) zOffset -= delta / generationDelay if (zOffset < 0) zOffset = 0 } else { zOffset = 0 } // Some auto-rotation if (mode == Modes.RUN) rotY += delta * 0.0001 // Background and lighting background('#190b28') ambientLight(200) pointLight(255, 255, 255, 500, 0, 200); // Rotate, scale and translate the camera push() rotateX((-PI / 2) * (1 - persp)) rotateX(rotX * persp) rotateY(rotY % TWO_PI * persp) scale(pow(fullCubeSize, 1 - persp)) scale(pow(cubeSize, persp)); translate((-layerWidth / 2) * (1 - persp) + 0.5, (1 - layers.length) * (1 - persp), (-layerHeight / 2) * (1 - persp) + 0.5) translate((-layerWidth / 2) * persp, (layerCountMax / 2 - layers.length) * persp, (-layerHeight / 2) * persp) // Pink 'p5.js' material for all the cubes ambientMaterial('#ed225d') // Iterate through each layer to draw all cubes push() translate(0, zOffset, 0) for (let z = 0; z < layers.length; z++) { let layer = layers[z] for (let y = 0; y < layerHeight; y++) { for (let x = 0; x < layerWidth; x++) { // Don't draw anything if the cube is not alive if (!layer[y][x]) continue // Translate to the cube position push() translate(x, z, y) // Bottom cube scale if (z === layers.length - 1) scale(1 - zOffset) // Top cube scale if (z === 0 && layers.length == layerCountMax) scale(zOffset) // Draw the box if the cell is alive if (layer[y][x]) { if (persp !== 1) box(1, persp * 0.999 + 0.001, 1) else box(1) } pop() // Cell } } } pop() // Z Offset pop() // Camera // Text if (mode === Modes.DRAW) { texture(textGraphics) translate(0, -height / 2 + 22, 1) plane(width, 24) } } function doGeneration() { // Store the current population and create the next one let currLayer = layers[layers.length - 1] let nextLayer = [] // Iterate through each cell for (let y = 0; y < layerHeight; y++) { let row = [] for (let x = 0; x < layerWidth; x++) { // Get the number of living neighbour cells let nb = countNeighbours(currLayer, x, y) // Apply the game of life rules to the current new cell let alive = 0 if (nb === 2) alive = currLayer[y][x] if (nb === 3) alive = 1 // Add the cell row.push(alive) } nextLayer.push(row) } // Add our new layer and remove the top one, if the array is too big layers.push(nextLayer) if (layers.length > layerCountMax) layers.splice(0, 1) } function countNeighbours(layer, x, y) { // Initialize the number of living neighbours let nb = 0 // Iterate through each neighbour cell for (let j = -1; j <= 1; j++) { for (let i = -1; i <= 1; i++) { // Don't count ourselfes if (i === 0 && j === 0) continue; // Calculate the neighbours actual x and y position let px = x + i let py = y + j // If the neighbour is not in bounds, don't count it if (px < 0 || px >= layerWidth || py < 0 || py >= layerHeight) continue // If the neighbour is alive, increment the counter if (layer[py][px]) nb++ } } // Return the number of living neighbours return nb } function calcFullCubeSize() { fullCubeSize = min(width / layerWidth, height / layerHeight) } function enterMode(nextMode) { // Don't enter the mode if we already changed it if (nextMode === mode) return // Prepare for drawing if (nextMode === Modes.DRAW) { layers.splice(0, layers.length - 1) } // Prepare to run the animation if (nextMode === Modes.RUN) { lastGenerationTime = millis() + initialDelay - generationDelay } // Set the current mode and reset the transition state mode = nextMode modeTransition = 0 } function mousePressed() { // Draw a pixel if (mode === Modes.DRAW) { // Calculate the cube position let px = parseInt((mouseX - width / 2) / fullCubeSize + layerWidth / 2) let py = parseInt((mouseY - height / 2) / fullCubeSize + layerHeight / 2) // Inverse cube if in bounds if (px >= 0 && px < layerWidth && py >= 0 && py < layerHeight) { colFlag = !layers[layers.length - 1][py][px] layers[layers.length - 1][py][px] = colFlag } } // Set the mouse flags mouseDX = mouseX mouseDY = mouseY } function mouseDragged() { // Draw a pixel if (mode === Modes.DRAW) { // Calculate the cube position let px = parseInt((mouseX - width / 2) / fullCubeSize + layerWidth / 2) let py = parseInt((mouseY - height / 2) / fullCubeSize + layerHeight / 2) // Inverse cube if in bounds if (px >= 0 && px < layerWidth && py >= 0 && py < layerHeight) { layers[layers.length - 1][py][px] = colFlag } } // Rotate the scene when the mouse is dragged if (mode === Modes.RUN) { rotX -= (mouseY - mouseDY) * 0.003 rotY += (mouseX - mouseDX) * 0.003 } // Set the mouse flags mouseDX = mouseX mouseDY = mouseY } function mouseWheel(event) { // Zoom in or out (e. g. change the global scale) if (mode === Modes.RUN) { cubeSize *= pow(0.999, event.delta) } } function keyPressed() { // Toggle the current mode if (key === ' ') { if (mode === Modes.DRAW) enterMode(Modes.RUN) else if (mode === Modes.RUN) enterMode(Modes.DRAW) } // Clear everything if (key === 'c') { for (let row of layers[layers.length - 1]) { for (var x = 0; x < row.length; x++) row[x] = 0 } } } function windowResized() { // Resize the canvas whenever the surrounding window size changes resizeCanvas(this.windowWidth, this.windowHeight) // Recalculate the full cube size. This is the maximum cube scale to fill the entire window calcFullCubeSize() }
Duplicare
Executare
Cod
Cod HTML
<iframe sandbox="allow-scripts" src="/p5js/index.php?id=6221" style="width:408px; height:408px;border:solid 1px gray; overflow: scroll;"></iframe>
Duplicare script
Denumirea noului script
Du-te sus!