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
Articole recomandate
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!
Script Nou - Processing
Lista scripturi
Script Nou
Ajutor
ID
Autor
Duplicat din
Ultima modificare
#7237
7B-Necsulescu Stefan Matei (Stefan_Matei_Necsulescu)
-
Duminica, 17 mai 2026, 12:09
// ========================================== // CONFIGURAȚIE BLOCURI ȘI INVENTAR // ========================================== const AIR = 0, GRASS = 1, STONE = 2, WOOD = 3, LEAVES = 4, BRICK = 5, GLASS = 6, PLANKS = 7, SWORD = 8, COAL = 9, PICKAXE = 10, STICK = 11, TORCH = 12; const blockNames = { [AIR]:"Aer", [GRASS]:"Iarba", [STONE]:"Piatra", [WOOD]:"Lemn", [LEAVES]:"Frunze", [BRICK]:"Camida", [GLASS]:"Sticla", [PLANKS]:"Scanduri", [SWORD]:"Sabie", [COAL]:"Carbune", [PICKAXE]:"Tarnacop", [STICK]:"Bat", [TORCH]:"Torta" }; const blockColors = { [GRASS]: '#5a9e32', [STONE]: '#7a7a7a', [WOOD]: '#5c3a21', [LEAVES]: '#1e641e', [BRICK]: '#9c2a2a', [GLASS]: 'rgba(187,221,255,0.5)', [PLANKS]: '#ad723e', [COAL]: '#222222', [TORCH]: '#ffaa00' }; let world = new Map(); let loadedChunks = new Set(); const CHUNK_SIZE = 6; const RENDER_DIST = 2; // Optimizat strans pentru PbInfo const BLOCK_SIZE = 40; let hotbar = [PICKAXE, SWORD, GRASS, STONE, WOOD, PLANKS, TORCH, AIR, AIR]; let selectedSlot = 0; let inventory = [ { id: PICKAXE, count: 1 }, { id: SWORD, count: 1 }, { id: STONE, count: 20 }, { id: WOOD, count: 10 }, { id: COAL, count: 5 }, { id: BRICK, count: 5 } ]; // Umplem restul inventarului pana la 27 de sloturi (3 randuri de 9) for(let i = inventory.length; i < 27; i++) inventory.push({ id: AIR, count: 0 }); // Stări joc let showInventory = false; let notificationText = "Apasati E pentru Inventar / Crafting"; let notificationTimer = 180; // Poziție și orientare let pX = 0, pY = 400, pZ = 0; let rotY = 0, rotX = 0; // Animații procedurale mână let swingProgress = 0; let isSwinging = false; let placeActionProgress = 0; // Fuziune fizică let velocityY = 0, isGrounded = false; // ========================================== // SETUP & DRAW MAIN LOOP // ========================================== function setup() { createCanvas(windowWidth, windowHeight, WEBGL); // Generare strat inițial pe înălțime pY = (getNoiseHeight(0, 0) + 3) * BLOCK_SIZE; } function draw() { background('#78a7ff'); // Gestionare mișcare cameră din taste (pentru medii fără mouse pointer lock securizat) if (!showInventory) { if (keyIsDown(LEFT_ARROW)) rotY += 0.04; if (keyIsDown(RIGHT_ARROW)) rotY -= 0.04; if (keyIsDown(UP_ARROW)) rotX = constrain(rotX + 0.03, -HALF_PI + 0.05, HALF_PI - 0.05); if (keyIsDown(DOWN_ARROW)) rotX = constrain(rotX - 0.03, -HALF_PI + 0.05, HALF_PI - 0.05); } handlePhysics(); // Configurare Cameră First Person let headY = -pY - 45; let lookX = pX + sin(rotY) * cos(rotX); let lookY = headY + sin(rotX); let lookZ = pZ + cos(rotY); camera(pX, headY, pZ, lookX, lookY, lookZ, 0, 1, 0); // Lumini dinamice joc ambientLight(140); directionalLight(140, 140, 140, 0.5, 1, -0.3); // Randare mediu blocks updateInfiniteWorld(); // Randare interfață și mână (izolate în spațiu 2D/HUD) push(); resetMatrix(); // Translatăm în planul frontal de vizualizare HUD translate(0, 0, -300); renderHandModel(); renderInGameHUD(); pop(); } // ========================================== // MOTOR GENERARE LUMI (CHUNKS) // ========================================== function setBlock(x, y, z, type) { if (type === AIR) world.delete(`${x},${y},${z}`); else world.set(`${x},${y},${z}`, type); } function getBlock(x, y, z) { return world.get(`${x},${y},${z}`) || AIR; } function getNoiseHeight(x, z) { let n = sin(x * 0.1) * cos(z * 0.1) * 3; return floor(n + 6); } function generateChunk(cx, cz) { let chunkKey = `${cx},${cz}`; if (loadedChunks.has(chunkKey)) return; loadedChunks.add(chunkKey); let startX = cx * CHUNK_SIZE; let startZ = cz * CHUNK_SIZE; for (let x = 0; x < CHUNK_SIZE; x++) { for (let z = 0; z < CHUNK_SIZE; z++) { let wx = startX + x; let wz = startZ + z; let h = getNoiseHeight(wx, wz); for (let y = 0; y < h; y++) { if (y === h - 1) setBlock(wx, y, wz, GRASS); else if (y > h - 4) setBlock(wx, y, wz, STONE); else setBlock(wx, y, wz, random() < 0.08 ? COAL : STONE); } // Copaci rari procedurali if (abs(wx) % 9 === 0 && abs(wz) % 9 === 0 && random() < 0.2) { for (let th = 0; th < 3; th++) setBlock(wx, h + th, wz, WOOD); setBlock(wx, h + 3, wz, LEAVES); setBlock(wx + 1, h + 2, wz, LEAVES); setBlock(wx - 1, h + 2, wz, LEAVES); } } } } function updateInfiniteWorld() { let playerChunkX = floor((pX / BLOCK_SIZE) / CHUNK_SIZE); let playerChunkZ = floor((pZ / BLOCK_SIZE) / CHUNK_SIZE); for (let x = -RENDER_DIST; x <= RENDER_DIST; x++) { for (let z = -RENDER_DIST; z <= RENDER_DIST; z++) { generateChunk(playerChunkX + x, playerChunkZ + z); } } let pBlockX = round(pX / BLOCK_SIZE); let pBlockY = floor(pY / BLOCK_SIZE); let pBlockZ = round(pZ / BLOCK_SIZE); for (let [key, type] of world.entries()) { let [x, y, z] = key.split(',').map(Number); if (abs(x - pBlockX) > RENDER_DIST * CHUNK_SIZE || abs(z - pBlockZ) > RENDER_DIST * CHUNK_SIZE) continue; let isVisible = getBlock(x+1,y,z)===AIR || getBlock(x-1,y,z)===AIR || getBlock(x,y+1,z)===AIR || getBlock(x,y-1,z)===AIR || getBlock(x,y,z+1)===AIR || getBlock(x,y,z-1)===AIR; if (isVisible) { push(); translate(x * BLOCK_SIZE, -y * BLOCK_SIZE, z * BLOCK_SIZE); fill(blockColors[type] || '#ffffff'); stroke(0, 40); if (type === TORCH) { translate(0, BLOCK_SIZE/4, 0); box(BLOCK_SIZE * 0.2, BLOCK_SIZE * 0.6, BLOCK_SIZE * 0.2); } else { box(BLOCK_SIZE); } pop(); } } } // ========================================== // FIZICĂ ȘI CONTROALE DE DEPLASARE // ========================================== function checkCollision(x, y, z) { let bx = round(x / BLOCK_SIZE); let by = floor(y / BLOCK_SIZE); let bz = round(z / BLOCK_SIZE); return (getBlock(bx, by, bz) !== AIR || getBlock(bx, by + 1, bz) !== AIR); } function handlePhysics() { if (showInventory) return; let speed = 3.5; let dx = 0, dz = 0; if (keyIsDown(87)) { dx += sin(rotY) * speed; dz += cos(rotY) * speed; } // W if (keyIsDown(83)) { dx -= sin(rotY) * speed; dz -= cos(rotY) * speed; } // S if (keyIsDown(65)) { dx += cos(rotY) * speed; dz -= sin(rotY) * speed; } // A if (keyIsDown(68)) { dx -= cos(rotY) * speed; dz += sin(rotY) * speed; } // D if (!checkCollision(pX + dx, pY, pZ)) pX += dx; if (!checkCollision(pX, pY, pZ + dz)) pZ += dz; velocityY -= 0.35; pY += velocityY; if (checkCollision(pX, pY, pZ)) { pY -= velocityY; velocityY = 0; isGrounded = true; } else { isGrounded = false; } if (pY < -800) { pX = 0; pZ = 0; pY = (getNoiseHeight(0,0) + 3) * BLOCK_SIZE; velocityY = 0; } } function keyPressed() { let k = key.toLowerCase(); if (k === 'e') { showInventory = !showInventory; } if (key >= '1' && key <= '9') { selectedSlot = parseInt(key) - 1; } if (keyCode === 32 && isGrounded && !showInventory) { // SPACE velocityY = 6.8; isGrounded = false; } } // Interacțiuni mouse (Săpat / Pus Blocuri complet desenate procedural) function mousePressed() { // Dacă inventarul e deschis, click-urile se duc în logica interfeței if (showInventory) { handleInventoryClicks(); return; } if (mouseButton === LEFT && !isSwinging) { isSwinging = true; swingProgress = 0; } let target = performRaycast(); if (!target) return; if (mouseButton === LEFT) { let type = getBlock(target.hx, target.hy, target.hz); if (type !== AIR) { addItem(type); setBlock(target.hx, target.hy, target.hz, AIR); triggerNotification("Adaugat in inventar: " + blockNames[type]); } } else if (mouseButton === RIGHT) { let handItem = hotbar[selectedSlot]; if (handItem === AIR || handItem === SWORD || handItem === PICKAXE || handItem === STICK) return; if (countItems(handItem) <= 0) return; if (!checkCollision(target.px * BLOCK_SIZE, target.py * BLOCK_SIZE, target.pz * BLOCK_SIZE)) { setBlock(target.px, target.py, target.pz, handItem); removeItem(handItem, 1); placeActionProgress = 1.0; } } } function performRaycast() { let currentX = pX; let currentY = pY + 45; let currentZ = pZ; let dirX = sin(rotY) * cos(rotX); let dirY = -sin(rotX); let dirZ = cos(rotY); let prevBx = round(pX / BLOCK_SIZE), prevBy = floor(currentY / BLOCK_SIZE), prevBz = round(pZ / BLOCK_SIZE); for (let d = 0; d < 180; d += 6) { currentX += dirX * 6; currentY += dirY * 6; currentZ += dirZ * 6; let bx = round(currentX / BLOCK_SIZE); let by = floor(currentY / BLOCK_SIZE); let bz = round(currentZ / BLOCK_SIZE); if (getBlock(bx, by, bz) !== AIR) { return { hx: bx, hy: by, hz: bz, px: prevBx, py: prevBy, pz: prevBz }; } prevBx = bx; prevBy = by; prevBz = bz; } return null; } // ========================================== // RENDER HAND MODEL (MODEL ANIMAT ÎN MÂNĂ) // ========================================== function renderHandModel() { let currentItem = hotbar[selectedSlot]; if (currentItem === AIR) return; push(); let tx = 110, ty = 80, tz = 50; let rx = 0.4, ry = -0.5, rz = (currentItem === PICKAXE) ? -0.4 : 0.0; let isMoving = (keyIsDown(87) || keyIsDown(83) || keyIsDown(65) || keyIsDown(68)) && isGrounded; if (isMoving) { tx += cos(millis() * 0.008) * 6; ty += abs(sin(millis() * 0.008)) * 6; } if (placeActionProgress > 0) { tz -= placeActionProgress * 30; placeActionProgress -= 0.15; } if (isSwinging) { swingProgress += 0.15; if (swingProgress >= 1.0) { isSwinging = false; swingProgress = 0; } let angle = sin(swingProgress * Math.PI); rx += angle * 1.2; ry -= angle * 0.4; tx -= angle * 30; } translate(tx, ty, tz); rotateX(rx); rotateY(ry); rotateZ(rz); // Desenare geometrie 3D obiect în mână stroke(0, 70); if (currentItem === SWORD) { fill('#dddddd'); push(); translate(0, -25, 0); box(6, 60, 6); pop(); fill('#5c3a21'); push(); box(22, 6, 6); translate(0, 15, 0); box(6, 20, 6); pop(); } else if (currentItem === PICKAXE) { fill('#5c3a21'); box(6, 60, 6); fill('#999999'); push(); translate(0, -25, 0); box(45, 8, 10); pop(); } else if (currentItem === STICK) { fill('#5c3a21'); box(6, 60, 6); } else { fill(blockColors[currentItem] || '#fff'); if (currentItem === TORCH) box(8, 30, 8); else box(32); } pop(); } // ========================================== // INTERFAȚĂ GRAFICĂ COMPLETĂ ÎN p5.js (HUD) // ========================================== function renderInGameHUD() { // Calculăm coordonatele scalate pentru ecran bidimensional în planul HUD (-300 adâncime) let w = width * 0.77; let h = height * 0.77; // Tăietură Crosshair central stroke(255, 180); strokeWeight(2); line(-8, 0, 8, 0); line(0, -8, 0, 8); strokeWeight(1); // Panou Informații Stânga-Sus fill(0, 180); noStroke(); rect(-w/2 + 10, -h/2 + 10, 230, 75, 4); fill(255); textSize(10); textAlign(LEFT, TOP); text("CRAFTCRAFT P5.JS PORTED", -w/2 + 18, -h/2 + 16); fill('#ffcc00'); text("Mers: W,A,S,D | Cam: SAGETI | Salt: SPACE", -w/2 + 18, -h/2 + 32); text("Interactiune: Click Stanga / Click Dreapta", -w/2 + 18, -h/2 + 46); text("Inventar & Retete Crafting: Tasta [E]", -w/2 + 18, -h/2 + 60); // Notificări dinamice if (notificationTimer > 0) { fill(0, 150); rect(-150, -h/2 + 10, 300, 26, 5); fill('#ffff00'); textAlign(CENTER, CENTER); textSize(11); text(notificationText, 0, -h/2 + 22); notificationTimer--; } // 1. RANDARE HOTBAR JOC (Jos central) let hbW = 360, hbH = 44; let hbX = -hbW / 2, hbY = h / 2 - 60; fill(30, 220); stroke(100); rect(hbX, hbY, hbW, hbH, 3); for (let i = 0; i < 9; i++) { let slotX = hbX + i * 40 + 2; let slotY = hbY + 2; if (i === selectedSlot) { fill(120, 150); stroke('#ffcc00'); strokeWeight(2); rect(slotX, slotY, 36, 40, 2); strokeWeight(1); } else { fill(15, 100); stroke(60); rect(slotX, slotY, 36, 40, 2); } // Afișare text item din Hotbar let type = hotbar[i]; if (type !== AIR) { fill(blockColors[type] || 255); noStroke(); textAlign(CENTER, CENTER); textSize(9); text(blockNames[type].substring(0, 5), slotX + 18, slotY + 15); fill(255); text(countItems(type), slotX + 18, slotY + 28); } } // 2. RANDARE ECRAN COMPLET INVENTAR & CRAFTING (Dacă e deschis cu E) if (showInventory) { let invW = 460, invH = 320; fill(20, 245); stroke(150); rect(-invW/2, -invH/2, invW, invH, 6); fill(255); textAlign(LEFT, TOP); textSize(13); text("INVENTAR COMPLET (Apasati click pe item pentru Hotbar)", -invW/2 + 15, -invH/2 + 15); // Grila de Inventar 3x9 for (let r = 0; r < 3; r++) { for (let c = 0; c < 9; c++) { let idx = r * 9 + c; let sX = -invW/2 + 15 + c * 38; let sY = -invH/2 + 45 + r * 38; fill(10); stroke(70); rect(sX, sY, 34, 34, 2); let item = inventory[idx]; if (item.id !== AIR) { fill(blockColors[item.id] || 255); noStroke(); textAlign(CENTER, CENTER); textSize(8); text(blockNames[item.id].substring(0, 4), sX + 17, sY + 12); fill(255); text(item.count, sX + 17, sY + 24); } } } // Sectiunea Retete Crafting (Partea de jos a ferestrei) fill('#ffcc00'); textAlign(LEFT, TOP); textSize(11); text("REȚETE CRAFTING DISPONIBILE (Click direct pe casetă pentru a produce):", -invW/2 + 15, -invH/2 + 165); let recipes = [ { name: "Scanduri x4", cost: "1 Lemn", id: "planks" }, { name: "Bete x4", cost: "2 Scanduri", id: "sticks" }, { name: "Tarnacop", cost: "3 Piatra+2 Bete", id: "pickaxe" }, { name: "Sabie", cost: "2 Piatra+1 Bat", id: "sword" }, { name: "Torta x4", cost: "1 Carbune+1 Bat", id: "torch" } ]; for (let i = 0; i < recipes.length; i++) { let bX = -invW/2 + 15 + (i % 2) * 215; let bY = -invH/2 + 185 + floor(i / 2) * 40; fill(45); stroke(100); rect(bX, bY, 205, 32, 4); fill(255); textAlign(LEFT, CENTER); textSize(10); text("🔨 " + recipes[i].name, bX + 8, bY + 16); fill(180); textAlign(RIGHT, CENTER); text(recipes[i].cost, bX + 195, bY + 16); } } } // ========================================== // COLECTARE ȘI MANAGEMENT INVENTAR // ========================================== function addItem(type) { for(let s of inventory) { if(s.id === type && s.count < 64) { s.count++; return; } } for(let s of inventory) { if(s.id === AIR) { s.id = type; s.count = 1; return; } } } function countItems(type) { let t = 0; for(let s of inventory) { if(s.id === type) t += s.count; } return t; } function removeItem(type, amt) { for(let s of inventory) { if(s.id === type) { if(s.count >= amt) { s.count -= amt; if(s.count===0) s.id = AIR; return; } } } } function handleInventoryClicks() { let w = width * 0.77; let h = height * 0.77; let invW = 460, invH = 320; // Translatăm coordonatele mouse-ului din sistemul nativ de canvas (0,0 stânga sus) în spațiul HUD (-w/2, -h/2) let mx = mouseX - width/2; let my = mouseY - height/2; // Verificare click în grila de Inventar pentru echipare în Hotbar for (let r = 0; r < 3; r++) { for (let c = 0; c < 9; c++) { let sX = -invW/2 + 15 + c * 38; let sY = -invH/2 + 45 + r * 38; // Scalare raportată la transformarea din HUD (-300 adâncime mărește ușor coordonata vizuală) let factor = 0.77; if (mx > sX*factor && mx < (sX+34)*factor && my > sY*factor && my < (sY+34)*factor) { let idx = r * 9 + c; if(inventory[idx].id !== AIR) { hotbar[selectedSlot] = inventory[idx].id; triggerNotification("Echipat in Hotbar: " + blockNames[inventory[idx].id]); } return; } } } // Verificare click pe butoanele de Crafting let recipes = ["planks", "sticks", "pickaxe", "sword", "torch"]; for (let i = 0; i < recipes.length; i++) { let bX = -invW/2 + 15 + (i % 2) * 215; let bY = -invH/2 + 185 + floor(i / 2) * 40; let factor = 0.77; if (mx > bX*factor && mx < (bX+205)*factor && my > bY*factor && my < (bY+32)*factor) { executeCraft(recipes[i]); return; } } } function executeCraft(recipe) { if(recipe === 'planks' && countItems(WOOD) >= 1) { removeItem(WOOD, 1); for(let i=0;i<4;i++) addItem(PLANKS); triggerNotification("Craftat: Scanduri x4"); } else if(recipe === 'sticks' && countItems(PLANKS) >= 2) { removeItem(PLANKS, 2); for(let i=0;i<4;i++) addItem(STICK); triggerNotification("Craftat: Bete x4"); } else if(recipe === 'pickaxe' && countItems(STONE) >= 3 && countItems(STICK) >= 2) { removeItem(STONE, 3); removeItem(STICK, 2); addItem(PICKAXE); triggerNotification("Craftat: Tarnacop"); } else if(recipe === 'sword' && countItems(STONE) >= 2 && countItems(STICK) >= 1) { removeItem(STONE, 2); removeItem(STICK, 1); addItem(SWORD); triggerNotification("Craftat: Sabie"); } else if(recipe === 'torch' && countItems(COAL) >= 1 && countItems(STICK) >= 1) { removeItem(COAL, 1); removeItem(STICK, 1); for(let i=0;i<4;i++) addItem(TORCH); triggerNotification("Craftat: Torte x4"); } else { triggerNotification("Resurse insuficiente pentru reteta!"); } } function triggerNotification(msg) { notificationText = msg; notificationTimer = 150; } function windowResized() { resizeCanvas(windowWidth, windowHeight); }
Duplicare
Executare
Cod
Cod HTML
<iframe sandbox="allow-scripts" src="/p5js/index.php?id=7237" style="width:408px; height:408px;border:solid 1px gray; overflow: scroll;"></iframe>
Duplicare script
Denumirea noului script
Du-te sus!