<!DOCTYPE html><html lang="ru"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Kirakims Runner — 1 флакон = 1 бонус‑рубль</title> <style> :root{ --pink:#ff2aa6; /* фирменный оттенок */ --bg:#0a0a0a; --ink:#ffffff; --muted:#8a8a8a; } *{box-sizing:border-box} html,body{height:100%;margin:0;background:var(--bg);color:var(--ink);font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif} .wrap{display:grid;place-items:center;height:100%;padding:16px} .game{position:relative;width:min(100vw,880px);aspect-ratio:16/9;border-radius:24px;overflow:hidden;box-shadow:0 12px 50px rgba(0,0,0,.45),0 0 0 2px rgba(255,255,255,.06) inset} canvas{display:block;width:100%;height:100%;background:linear-gradient(180deg,#121212 0%,#0c0c0c 60%,#050505 100%)}.hud{position:absolute;inset:0;pointer-events:none} .row{position:absolute;display:flex;gap:12px;align-items:center} .row.top{top:14px;left:14px} .row.top-right{top:14px;right:14px} .badge{pointer-events:auto;background:rgba(0,0,0,.5);backdrop-filter:blur(6px);border:1px solid rgba(255,255,255,.08);padding:8px 12px;border-radius:999px;display:flex;align-items:center;gap:8px;font-weight:600} .btn{pointer-events:auto;background:var(--pink);border:none;color:#000;font-weight:800;padding:10px 14px;border-radius:999px;cursor:pointer;transition:transform .05s ease;box-shadow:0 8px 24px rgba(255,42,166,.35)} .btn:active{transform:translateY(1px)} .center{position:absolute;inset:0;display:grid;place-items:center;text-align:center} .card{max-width:78%;background:rgba(0,0,0,.6);border:1px solid rgba(255,255,255,.08);backdrop-filter:blur(8px);padding:22px 24px;border-radius:20px} .title{font-size:clamp(22px,4.5vw,38px);font-weight:900;letter-spacing:.5px;margin:0 0 10px} .subtitle{margin:0 0 16px;color:var(--muted)} .controls{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-top:10px} .legend{font-size:13px;color:#c9c9c9;margin-top:8px} .tapZone{position:absolute;inset:0;} /* Mobile hint pulse */ @keyframes pulse{0%{transform:scale(1)}50%{transform:scale(1.06)}100%{transform:scale(1)}} .pulse{animation:pulse 1.4s ease-in-out infinite} </style> </head> <body> <div class="wrap"> <div class="game" id="game"> <canvas id="canvas" width="1280" height="720" aria-label="Kirakims Runner"></canvas> <div class="hud"> <div class="row top"> <div class="badge" id="scoreBadge">Бонус‑рубли: <span id="score">0</span></div> <div class="badge" id="lifeBadge">Жизни: <span id="lives">3</span></div> </div> <div class="row top-right"> <button class="btn" id="pauseBtn" title="Пауза (P)">Пауза</button> </div> <div class="center" id="startScreen"> <div class="card"> <h1 class="title">Kirakims Runner</h1> <p class="subtitle">Кореянка собирает флаконы духов. <strong>1 флакон = 1 бонус‑рубль.</strong><br/>Перепрыгивайте препятствия с оградительными розовыми полосами.</p> <div class="controls"> <button class="btn pulse" id="startBtn">Старт</button> <button class="btn" id="howBtn">Как играть</button> </div> <p class="legend">Прыжок: <b>Пробел</b> / <b>Клик/Тап</b> • Пауза: <b>P</b></p> </div> </div> <div class="center" id="howScreen" style="display:none"> <div class="card"> <h2 class="title">Как играть</h2> <p class="subtitle" style="text-align:left"> • Собирайте флакончики духов Kirakims — каждый добавляет 1 бонус‑рубль к счёту.<br/> • Перепрыгивайте препятствия‑барьеры в фирменных розово‑чёрных полосках.<br/> • Три столкновения — игра окончена. Дойдите как можно дальше!<br/> • На фоне — логотип Kirakims (водяной знак). Загрузите свой PNG/JPG логотип ниже, чтобы заменить встроенный. </p> <div class="controls"> <input class="badge" id="logoInput" type="file" accept="image/*" /> <button class="btn" id="backBtn">Назад</button> </div> </div> </div> <div class="center" id="gameOver" style="display:none"> <div class="card"> <h2 class="title">Игра окончена</h2> <p class="subtitle">Ваши бонус‑рубли: <b id="finalScore">0</b></p> <div class="controls"> <button class="btn" id="restartBtn">Играть снова</button> <button class="btn" id="shareBtn">Поделиться</button> </div> </div> </div> </div> <div class="tapZone" id="tap"></div> </div> </div><script> (() => { const W = 1280, H = 720; // внутреннее разрешение канваса const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // HUD elements const scoreEl = document.getElementById('score'); const livesEl = document.getElementById('lives'); const startScreen = document.getElementById('startScreen'); const howScreen = document.getElementById('howScreen'); const gameOverEl = document.getElementById('gameOver'); const finalScoreEl = document.getElementById('finalScore'); const logoInput = document.getElementById('logoInput'); const pauseBtn = document.getElementById('pauseBtn'); const startBtn = document.getElementById('startBtn'); const howBtn = document.getElementById('howBtn'); const backBtn = document.getElementById('backBtn'); const restartBtn = document.getElementById('restartBtn'); const shareBtn = document.getElementById('shareBtn'); const tapZone = document.getElementById('tap'); // GAME STATE let running = false, paused = false, over = false; let t = 0, score = 0, lives = 3; let gravity = 2100, jumpV = -900, speed = 420; const rand = (a,b)=> a + Math.random()*(b-a); // Assets: allow custom logo let logoImg = null; logoInput?.addEventListener('change', (e)=>{ const file = e.target.files?.[0]; if(!file) return; const url = URL.createObjectURL(file); const img = new Image(); img.onload = ()=>{ logoImg = img; URL.revokeObjectURL(url); }; img.src = url; }); // Runner (Кореянка) — стилизованный персонаж const girl = { x: 200, y: H-160, w: 52, h: 82, vy: 0, onGround: true, blink:0 }; // Pools const bottles = []; // collectible items const obstacles = []; // barriers const particles = []; function reset(){ t = 0; score = 0; lives = 3; paused = false; over = false; running = true; girl.x = 200; girl.y = H-160; girl.vy = 0; girl.onGround = true; girl.blink=0; bottles.length = 0; obstacles.length = 0; particles.length = 0; spawnInitial(); hide(startScreen); hide(gameOverEl); hide(howScreen); updateHud(); } function updateHud(){ scoreEl.textContent = score; livesEl.textContent = lives; } // Spawn logic function spawnInitial(){ for(let i=1;i<=6;i++){ scheduleBottle(W + i*220 + rand(-60,80)); scheduleBarrier(W + i*320 + rand(-80,120)); } } function scheduleBottle(x){ bottles.push({x, y: H-200-rand(-40,120), r: 16, taken:false}); } function scheduleBarrier(x){ const w = rand(36,64), h = rand(70,120); obstacles.push({x, y:H-100, w, h}); } // Input function jump(){ if(!running paused  over) return; if(girl.onGround){ girl.vy = jumpV; girl.onGround = false; } } window.addEventListener('keydown', (e)=>{ if(e.code === 'Space'){ e.preventDefault(); jump(); } if(e.code === 'KeyP'){ togglePause(); } }); tapZone.addEventListener('pointerdown', jump); function togglePause(){ if(!running || over) return; paused = !paused; pauseBtn.textContent = paused? 'Продолжить' : 'Пауза'; } pauseBtn.addEventListener('click', togglePause); startBtn.addEventListener('click', reset); howBtn.addEventListener('click', ()=>{ show(howScreen); hide(startScreen); }); backBtn.addEventListener('click', ()=>{ show(startScreen); hide(howScreen); }); restartBtn.addEventListener('click', reset); shareBtn.addEventListener('click', ()=>{ const text = Я набрал(а) ${score} бонус‑рублей в Kirakims Runner!; if(navigator.share){ navigator.share({title:'Kirakims Runner', text}); } else { navigator.clipboard?.writeText(text); alert('Текст результата скопирован в буфер обмена!'); } }); function show(el){ el.style.display='grid'; } function hide(el){ el.style.display='none'; } // Game loop let last = performance.now(); function loop(now){ const dt = Math.min(0.032, (now-last)/1000); // clamp delta for stability last = now; if(running && !paused && !over){ step(dt); draw(); } else { // still redraw for pause overlays / responsive draw(); } requestAnimationFrame(loop); } requestAnimationFrame(loop); function step(dt){ t += dt; // increase difficulty slightly over time speed += 0.2*dt; // gentle ramp // physics: runner girl.vy += gravity*dt; girl.y += girl.vy*dt; const groundY = H-100 - girl.h; // ground line adjusted for height if(girl.y >= groundY){ girl.y = groundY; girl.vy = 0; girl.onGround = true; } // move items for(const b of bottles){ b.x -= speed*dt; } for(const o of obstacles){ o.x -= speed*dt; } // spawn new if(bottles.length < 10 && (t % 0.6) < dt){ scheduleBottle(W + rand(0,420)); } if(obstacles.length < 7 && (t % 0.9) < dt){ scheduleBarrier(W + rand(0,540)); } // collisions for(const b of bottles){ if(!b.taken && Math.abs((girl.x+girl.w/2) - b.x) < 32 && Math.abs((girl.y+girl.h/2) - b.y) < 42){ b.taken = true; score += 1; updateHud(); burst(b.x,b.y,10); } } for(const o of obstacles){ if(rectsOverlap(girl.x, girl.y, girl.w, girl.h, o.x, o.y - o.h, o.w, o.h)){ // damage obstacles.splice(obstacles.indexOf(o),1); girl.blink = 0.8; lives -= 1; updateHud(); burst(girl.x+girl.w/2, girl.y+girl.h/2, 20, true); if(lives <= 0){ gameOver(); return; } } } // clean up while(bottles.length && (bottles[0].x < -40 || bottles[0].taken)) bottles.shift(); while(obstacles.length && obstacles[0].x < -60) obstacles.shift(); // particles for(const p of particles){ p.vx *= 0.99; p.vy += 900*dt; p.x += p.vx*dt; p.y += p.vy*dt; p.a -= 0.9*dt; } for(let i=particles.length-1;i>=0;i--){ if(particles[i].a<=0) particles.splice(i,1); } if(girl.blink>0) girl.blink -= dt; } function rectsOverlap(x1,y1,w1,h1,x2,y2,w2,h2){ return x1 < x2+w2 && x1+w1 > x2 && y1 < y2+h2 && y1+h1 > y2; } function burst(x,y,n,hit=false){ for(let i=0;i<n;i++){ const a = Math.random()*Math.PI*2; const s = hit? rand(80,220): rand(60,140); particles.push({x,y,vx:Math.cos(a)*s,vy:Math.sin(a)*s,a:1,hit}); } } // DRAWING function draw(){ ctx.clearRect(0,0,W,H); // Background gradient and parallax lines drawBackground(); // Ground ctx.fillStyle = '#121212'; ctx.fillRect(0,H-100,W,140); // Logo watermark row drawLogoWatermark(); // Obstacles — pink/black hazard bars for(const o of obstacles){ drawBarrier(o); } // Bottles — stylized perfume bottle icon for(const b of bottles){ drawBottle(b); } // Girl drawGirl(girl); // Particles for(const p of particles){ ctx.globalAlpha = Math.max(0, p.a); ctx.fillStyle = p.hit? '#ff2aa6' : '#ffd7ef'; ctx.fillRect(p.x-2,p.y-2,4,4); ctx.globalAlpha = 1; } } function drawBackground(){ // subtle moving stripes const stripeH = 18; const offset = (t*60)%stripeH; ctx.save(); ctx.globalAlpha = 0.06; ctx.fillStyle = '#ffffff'; for(let y=-stripeH;y<H;y+=stripeH){ ctx.fillRect(0,y+offset,W,2); } ctx.restore(); } function drawLogoWatermark(){ ctx.save(); ctx.globalAlpha = 0.09; const step = 320; for(let x = -((t*speed*0.3)%step); x < W+step; x += step){ if(logoImg){ const size = 170; // square logo render ctx.drawImage(logoImg, x, 60, size, size); } else { // Fallback: draw circular KIRAKIMS emblem const cx = x+85, cy = 145, r = 78; ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(cx,cy,r,0,Math.PI*2); ctx.fill(); // magenta stripe ctx.fillStyle = '#ff2aa6'; ctx.fillRect(cx-r+14, cy-18, r*2-28, 36); // text ctx.fillStyle = '#000'; ctx.font = 'bold 20px system-ui, sans-serif'; ctx.textAlign = 'center'; ctx.fillText('KIRA KIMS', cx, cy+7); } } ctx.restore(); } function drawGirl(g){ const x=g.x, y=g.y, w=g.w, h=g.h; // shadow ctx.save(); ctx.globalAlpha = 0.25; ctx.fillStyle = '#000'; const shw = 34, shh = 10; const sx = x + w/2 - shw/2, sy = H-100 + 46; ctx.beginPath(); ctx.ellipse(sx+shw/2, sy, shw, shh, 0, 0, Math.PI*2); ctx.fill(); ctx.restore(); // body ctx.save(); if(g.blink>0 && ((t*20)|0)%2===0) ctx.globalAlpha = 0.35; // damage blink // hair ctx.fillStyle = '#1b1b1b'; ctx.fillRect(x+6,y-6,w-12,22); // head ctx.fillStyle = '#ffd7c2'; ctx.fillRect(x+14,y,24,24); // dress (pink) ctx.fillStyle = '#ff2aa6'; ctx.fillRect(x+8, y+24, 36, 40); // legs (running animation) const step = Math.sin(t*14)*10; ctx.fillStyle = '#ffd7c2'; ctx.fillRect(x+14+step/2, y+64, 8, 18); ctx.fillRect(x+30-step/2, y+64, 8, 18); // eyes ctx.fillStyle = '#000'; ctx.fillRect(x+22, y+8, 3,3); ctx.restore(); } function drawBottle(b){ const {x,y,r} = b; ctx.save(); ctx.translate(x,y); // bottle glass ctx.fillStyle = '#ffd7ef'; ctx.strokeStyle = '#ff2aa6'; roundedRect(-r,-r,r*2,r*2,6); ctx.fill(); ctx.stroke(); // cap ctx.fillStyle = '#ff2aa6'; ctx.fillRect(-r*0.5,-r-12,r,10); // sparkle ctx.fillStyle = 'white'; ctx.globalAlpha = 0.7; ctx.beginPath(); ctx.arc(-6,-2,3,0,Math.PI*2); ctx.fill(); ctx.restore(); } function drawBarrier(o){ // striped hazard column (brand tape) const x=o.x, y=o.y, w=o.w, h=o.h; ctx.save(); ctx.translate(x,y-h); // base ctx.fillStyle = '#0e0e0e'; ctx.fillRect(0,0,w,h); // stripes const s=14; for(let i=-s;i<h+s;i+=s){ ctx.fillStyle = i%28===0 ? '#000' : '#ff2aa6'; ctx.beginPath(); ctx.moveTo(-6, i); ctx.lineTo(w+6, i-10); ctx.lineTo(w+6, i+4); ctx.lineTo(-6, i+14); ctx.closePath(); ctx.fill(); } // top light ctx.globalAlpha=0.4; ctx.fillStyle='#ffffff'; ctx.fillRect(0,0,w,4); ctx.restore(); } function roundedRect(x,y,w,h,r){ ctx.beginPath(); ctx.moveTo(x+r,y); ctx.arcTo(x+w,y,x+w,y+h,r); ctx.arcTo(x+w,y+h,x,y+h,r); ctx.arcTo(x,y+h,x,y,r); ctx.arcTo(x,y,x+w,y,r); ctx.closePath(); } function gameOver(){ over = true; running = false; finalScoreEl.textContent = score; show(gameOverEl); } // Initial draw draw(); })(); </script></body> </html>

Обратный звонок
Запрос успешно отправлен!
Имя *
Телефон *
Предзаказ
Предзаказ успешно отправлен!
Имя *
Телефон *
Добавить в корзину
Название товара
100 ₽
1 шт.
Перейти в корзину
Предзаказ
Предзаказ успешно оформлен!
Имя *
Телефон *