// ------------- GAME STATES -------------- let gameRunning = true; // true = playing, false = game over let score = 0; // obstacles passed (distance) let bestScore = 0; let frameRequest = null; // ------------- TIMER (speedrun timer) -------------- let startTime = null; // performance timestamp when game starts/reset let currentTimer = 0; // seconds elapsed (only while running) // ------------- PLAYER -------------- const PLAYER_WIDTH = 24; const PLAYER_HEIGHT = 24; const GROUND_Y = H - 48; // ground level from top (y coord where feet land) let player = x: 80, y: GROUND_Y - PLAYER_HEIGHT, // on ground vy: 0, isOnGround: true, width: PLAYER_WIDTH, height: PLAYER_HEIGHT ; // physics constants const GRAVITY = 0.9; const JUMP_POWER = -12; // ------------- OBSTACLES (pixel blocks) -------------- let obstacles = []; const OBSTACLE_WIDTH = 20; const OBSTACLE_HEIGHT = 24; const OBSTACLE_BASE_SPEED = 4.6; // scrolling speed (pixels per frame) let currentSpeed = OBSTACLE_BASE_SPEED; let frameCounter = 0; let spawnGapFrames = 70; // initial spawn delay frames let dynamicGap = 70; // min distance between obstacles let lastSpawnFrame = 0; // ------------- VISUAL EFFECTS -------------- let groundTiles = []; for(let i=0; i<20; i++) groundTiles.push(i*40); // particles for jump/dust let particles = []; // -------- HELPER FUNCTIONS ---------- function saveBest() if(score > bestScore) bestScore = score; localStorage.setItem('pixelSpeedrunBest', bestScore); document.getElementById('bestValue').innerText = bestScore; function loadBest() let saved = localStorage.getItem('pixelSpeedrunBest'); if(saved !== null) bestScore = parseInt(saved,10); if(isNaN(bestScore)) bestScore = 0; else bestScore = 0; document.getElementById('bestValue').innerText = bestScore; // reset entire game state (fresh speedrun) function fullReset() gameRunning = true; score = 0; currentSpeed = OBSTACLE_BASE_SPEED; obstacles = []; frameCounter = 0; lastSpawnFrame = -40; // allow spawn soon dynamicGap = 70; // reset player player.y = GROUND_Y - PLAYER_HEIGHT; player.vy = 0; player.isOnGround = true; // reset timer (start new run) startTime = performance.now(); currentTimer = 0; updateTimerDisplay(0); // particles cleanup particles = []; document.getElementById('scoreValue').innerText = "0"; // keep best score unchanged saveBest(); // but score is 0, best remains, just call update display document.getElementById('bestValue').innerText = bestScore; // game over handler function gameOver() if(!gameRunning) return; gameRunning = false; saveBest(); // ensure best recorded // jump action function attemptJump() if(!gameRunning) // if game over, restart on jump? some speedrun style quick restart fullReset(); return; // only jump if on ground if(player.isOnGround) player.vy = JUMP_POWER; player.isOnGround = false; // add dust particles for(let i=0;i<6;i++) particles.push( x: player.x + PLAYER_WIDTH/2 + (Math.random() - 0.5)*8, y: GROUND_Y - 2, vx: (Math.random() - 0.5)*2, vy: -Math.random()*3 - 1, life: 0.8, size: 3+Math.random()*3 ); // update timer display mmss function updateTimerDisplay(seconds) let mins = Math.floor(seconds / 60); let secs = Math.floor(seconds % 60); let timeStr = `$mins.toString().padStart(2,'0'):$secs.toString().padStart(2,'0')`; document.getElementById('timerDisplay').innerText = timeStr; // spawn obstacle (pixel crate) function spawnObstacle() obstacles.push( x: W, y: GROUND_Y - OBSTACLE_HEIGHT, width: OBSTACLE_WIDTH, height: OBSTACLE_HEIGHT, scored: false ); // update collisions and movement function updateGame() if(!gameRunning) return; // 1. timer update if(startTime !== null && gameRunning) let now = performance.now(); let elapsed = (now - startTime) / 1000; currentTimer = elapsed; updateTimerDisplay(currentTimer); // 2. dynamic difficulty: speed increases with score (max 9.5) currentSpeed = OBSTACLE_BASE_SPEED + Math.floor(score / 280) * 0.45; if(currentSpeed > 9.2) currentSpeed = 9.2; // spawn timing: faster spawn when speed increases (gap reduces) let rawGap = Math.max(48, 70 - Math.floor(score / 90)); dynamicGap = Math.floor(rawGap); // 3. spawn obstacles based on frames frameCounter++; if(frameCounter - lastSpawnFrame > dynamicGap && gameRunning) (W - obstacles[obstacles.length-1].x) > 150) spawnObstacle(); lastSpawnFrame = frameCounter; // 4. update obstacles & collision + scoring for(let i=0; i<obstacles.length; i++) const obs = obstacles[i]; obs.x -= currentSpeed; // scoring: when obstacle passes player without collision & not scored if(!obs.scored && obs.x + obs.width < player.x) obs.scored = true; score++; document.getElementById('scoreValue').innerText = score; // dynamic best update during run (only if new best) if(score > bestScore) bestScore = score; document.getElementById('bestValue').innerText = bestScore; localStorage.setItem('pixelSpeedrunBest', bestScore); // remove offscreen obstacles obstacles = obstacles.filter(obs => obs.x + obs.width > 0); // 5. player physics player.vy += GRAVITY; player.y += player.vy; // ground collision if(player.y + PLAYER_HEIGHT >= GROUND_Y) player.y = GROUND_Y - PLAYER_HEIGHT; player.vy = 0; player.isOnGround = true; else player.isOnGround = false; // ceiling / top limit (optional) if(player.y < 0) player.y = 0; if(player.vy < 0) player.vy = 0; // 6. COLLISION DETECTION (pixel perfect AABB) const playerRect = x: player.x, y: player.y, w: PLAYER_WIDTH, h: PLAYER_HEIGHT ; for(let obs of obstacles) const obsRect = x: obs.x, y: obs.y, w: OBSTACLE_WIDTH, h: OBSTACLE_HEIGHT ; if(playerRect.x < obsRect.x + obsRect.w && playerRect.x + playerRect.w > obsRect.x && playerRect.y < obsRect.y + obsRect.h && playerRect.y + playerRect.h > obsRect.y) // collision -> GAME OVER gameOver(); break; // 7. update particles for(let i=0;i<particles.length;i++) particles[i].x += particles[i].vx; particles[i].y += particles[i].vy; particles[i].vy += 0.2; particles[i].life -= 0.02; if(particles[i].life <= 0 // ---------- DRAW EVERYTHING (retro pixel style) ---------- function draw() ctx.clearRect(0, 0, W, H); // ---- SKY gradient (pixel dither style) ---- let grad = ctx.createLinearGradient(0, 0, 0, H*0.6); grad.addColorStop(0, "#1a2a3a"); grad.addColorStop(1, "#2a3f4a"); ctx.fillStyle = grad; ctx.fillRect(0, 0, W, H); // distant pixel clouds ctx.fillStyle = "#6d8f9f"; for(let i=0;i<5;i++) let cloudX = (frameCounter*0.3 + i*170) % (W+200) - 100; ctx.fillRect(cloudX, 60, 40, 18); ctx.fillRect(cloudX+18, 48, 28, 16); ctx.fillRect(cloudX-12, 68, 30, 14); // ---- GROUND (pixel art road) ---- ctx.fillStyle = "#3f2b1d"; ctx.fillRect(0, GROUND_Y, W, H-GROUND_Y+2); // ground stripe pattern ctx.fillStyle = "#ebb45e"; for(let i=0; i<20; i++) let xOff = (frameCounter * 2 + i*55) % 90; ctx.fillRect(i*55 + xOff - 30, GROUND_Y-4, 22, 6); ctx.fillStyle = "#8b6946"; ctx.fillRect(0, GROUND_Y-6, W, 6); ctx.fillStyle = "#d9a13b"; for(let i=0;i<12;i++) ctx.fillRect(i*70 + (frameCounter%70), GROUND_Y-2, 32, 4); // ---- obstacles (danger pixel blocks) ---- for(let obs of obstacles) // main block ctx.fillStyle = "#d64531"; ctx.fillRect(obs.x, obs.y, OBSTACLE_WIDTH, OBSTACLE_HEIGHT); ctx.fillStyle = "#a1220e"; ctx.fillRect(obs.x+4, obs.y+4, 5, 6); ctx.fillRect(obs.x+11, obs.y+4, 5, 6); ctx.fillStyle = "#2c1a10"; ctx.fillRect(obs.x+3, obs.y+14, 14, 6); // spikes ctx.fillStyle = "#ff7256"; ctx.fillRect(obs.x+2, obs.y-4, 5, 6); ctx.fillRect(obs.x+12, obs.y-4, 5, 6); // ---- PLAYER (pixel runner) with dynamic pose ---- let legOffset = (player.isOnGround ? Math.sin(Date.now() * 0.018) * 3 : 4); ctx.fillStyle = "#3ecf8e"; ctx.fillRect(player.x, player.y, PLAYER_WIDTH, PLAYER_HEIGHT); // pixel face ctx.fillStyle = "#000000"; ctx.fillRect(player.x+6, player.y+6, 4, 4); ctx.fillRect(player.x+14, player.y+6, 4, 4); ctx.fillStyle = "#f0d050"; ctx.fillRect(player.x+10, player.y+12, 4, 3); // cape / scarf ctx.fillStyle = "#e34d8c"; ctx.fillRect(player.x-6, player.y+8, 6, 12); // legs animation ctx.fillStyle = "#2f9e6e"; ctx.fillRect(player.x+4, player.y+18, 5, 6); ctx.fillRect(player.x+15, player.y+18, 5, 6); // pixel sneakers ctx.fillStyle = "#2c2e3e"; ctx.fillRect(player.x+3, player.y+22, 7, 4); ctx.fillRect(player.x+14, player.y+22, 7, 4); // ---- speed lines (when high speed) ---- if(currentSpeed > 6) ctx.globalAlpha = 0.35; for(let i=0;i<12;i++) ctx.fillStyle = "#ffffff"; let lineX = (frameCounter*8 + i*70) % W; ctx.fillRect(lineX, GROUND_Y-14, 4, 2); ctx.fillRect(lineX+30, GROUND_Y-22, 6, 2); ctx.globalAlpha = 1; // ---- particles ---- for(let p of particles) ctx.fillStyle = `rgba(255, 200, 100, $p.life*0.8)`; ctx.fillRect(p.x, p.y, p.size, p.size); // ---- game over overlay ---- if(!gameRunning) ctx.fillStyle = "#000000aa"; ctx.fillRect(0, 0, W, H); ctx.font = "bold 36px 'Courier New', monospace"; ctx.fillStyle = "#ff4d6d"; ctx.shadowBlur = 0; ctx.fillText("⚡ GAME OVER ⚡", W/2-140, H/2-40); ctx.font = "22px monospace"; ctx.fillStyle = "#f6ecc2"; ctx.fillText("press [SPACE] or [RESTART]", W/2-150, H/2+30); ctx.font = "18px monospace"; ctx.fillStyle = "#aaffdd"; ctx.fillText("score: "+score+" // --- UI in canvas (tiny extra pixel info) ctx.font = "bold 14px 'Courier New'"; ctx.fillStyle = "#caffb9"; ctx.shadowBlur = 0; ctx.fillText("◀ PIXEL SPEEDRUN 66 ▶", W-180, 28); ctx.fillStyle = "#ffbc6e"; ctx.fillText("⚡ speed: "+currentSpeed.toFixed(1), W-130, 55); // ---- ANIMATION LOOP (classic requestFrame) ---- function gameLoop() updateGame(); draw(); frameRequest = requestAnimationFrame(gameLoop); // ---- EVENT HANDLERS (keyboard + mobile friendly) ---- function handleJump(e) // spacebar or click/tap on canvas if(e.type === 'keydown') else if(e.type === 'click') attemptJump(); // restart button document.getElementById('resetBtn').addEventListener('click', () => fullReset(); ); // touch / mouse support for canvas canvas.addEventListener('click', (e) => e.preventDefault(); attemptJump(); ); window.addEventListener('keydown', handleJump); // disable page scroll on space window.addEventListener('keydown', function(e) ); // ---- INIT GAME ---- function init() loadBest(); fullReset(); // sets timer start, gameRunning true, score 0 // ensure timer start is valid startTime = performance.now(); gameRunning = true; lastSpawnFrame = -20; frameCounter = 0; gameLoop(); init(); )(); </script> </body> </html>
.stat span color: #f5c542; font-size: 1rem; background: #00000080; padding: 2px 8px; border-radius: 20px; margin-left: 6px; pixel speedrun unblocked 66
@media (max-width: 560px) .stat font-size: 1rem; .timer-box font-size: 1.2rem; button font-size: 0.9rem; padding: 4px 12px; .stats gap: 12px; .info-panel justify-content: center; </style> </head> <body> <div> <div class="game-container"> <canvas id="gameCanvas" width="800" height="480"></canvas> <div class="info-panel"> <div class="stats"> <div class="stat">🏆 SCORE <span id="scoreValue">0</span></div> <div class="stat">⚡ BEST <span id="bestValue">0</span></div> </div> <div class="timer-box" id="timerDisplay">00:00</div> <div class="controls"> <button id="resetBtn">🔄 RESTART</button> </div> </div> <div style="display: flex; justify-content: space-between; margin-top: 12px; padding: 0 8px;"> <div class="status">🎮 [SPACEBAR / CLICK] → JUMP</div> <div class="status">🏁 PIXEL SPEEDRUN 66</div> </div> </div> </div> dynamic difficulty: speed increases with score (max 9
/* retro pixel container */ .game-container background: #000000aa; border-radius: 32px; padding: 20px 20px 24px; box-shadow: 0 20px 35px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255,255,255,0.1); backdrop-filter: blur(2px); player physics player
SmartCarve — это программное обеспечения для лазерных станков Yueming серии CMA. Вы можете скачать ПО с нашего сайта и установить его на свой компьютер.
Андрей Ответить
Добрый день, подскажите, есть возможность ссылки обновить, эти не работают.
Валерий Ответить
Здравствуйте, как скачать? при попытке скачать фа
Валерий Ответить
Здравствуйте, как скачать? при попытке скачать файлы отсутствуют на яндекс диске у Вас, обновите ссылки пожалуйста
Сергей Ответить
Добрый день, подскажите для yueming PN 6040 какая программа подойдет? была SmartCarve 3,016