sozdat-sayt-igra-v-kubik-rub/index.html

831 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru" data-theme="auto">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Кубик Рубика - Игра онлайн</title>
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
<link rel="stylesheet" href="design-system/kt-ai-components.css">
<link rel="stylesheet" href="design-system/kt-ai-page.css">
<link rel="icon" href="design-system/brand/kt-ai-logo.png">
<style>
.kt-ai-btn { text-decoration: none; }
.game-container {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--kt-ai-space-6);
padding: var(--kt-ai-space-6);
}
.scene {
width: 300px;
height: 300px;
perspective: 1200px;
margin: var(--kt-ai-space-4) 0;
}
.cube {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transform: rotateX(-25deg) rotateY(-35deg);
transition: transform 0.1s ease-out;
}
.cubie {
position: absolute;
width: 96px;
height: 96px;
transform-style: preserve-3d;
}
.face {
position: absolute;
width: 96px;
height: 96px;
border: 3px solid var(--kt-ai-fg-faint);
border-radius: 8px;
background: var(--kt-ai-bg);
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
backface-visibility: hidden;
}
.face-white { background: #f5f5f5; }
.face-yellow { background: #fbbf24; }
.face-red { background: #ef4444; }
.face-orange { background: #f97316; }
.face-blue { background: #3b82f6; }
.face-green { background: #22c55e; }
.face-front { transform: rotateY(0deg) translateZ(48px); }
.face-back { transform: rotateY(180deg) translateZ(48px); }
.face-right { transform: rotateY(90deg) translateZ(48px); }
.face-left { transform: rotateY(-90deg) translateZ(48px); }
.face-top { transform: rotateX(90deg) translateZ(48px); }
.face-bottom { transform: rotateX(-90deg) translateZ(48px); }
.controls {
display: flex;
flex-wrap: wrap;
gap: var(--kt-ai-space-3);
justify-content: center;
max-width: 600px;
}
.control-group {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--kt-ai-space-2);
padding: var(--kt-ai-space-3);
background: var(--kt-ai-bg-soft);
border-radius: var(--kt-ai-radius-lg);
}
.control-group-title {
font-size: var(--kt-ai-text-sm);
color: var(--kt-ai-fg-muted);
font-weight: var(--kt-ai-weight-medium);
}
.btn-row {
display: flex;
gap: var(--kt-ai-space-2);
}
.stats {
display: flex;
gap: var(--kt-ai-space-6);
margin-top: var(--kt-ai-space-4);
}
.stat-item {
text-align: center;
}
.stat-value {
font-size: var(--kt-ai-text-2xl);
font-weight: var(--kt-ai-weight-bold);
color: var(--kt-ai-primary);
}
.stat-label {
font-size: var(--kt-ai-text-sm);
color: var(--kt-ai-fg-muted);
}
.instructions {
max-width: 600px;
margin-top: var(--kt-ai-space-6);
padding: var(--kt-ai-space-4);
background: var(--kt-ai-bg-soft);
border-radius: var(--kt-ai-radius-lg);
}
.instructions h3 {
margin-bottom: var(--kt-ai-space-3);
color: var(--kt-ai-fg);
}
.instructions ul {
list-style: none;
padding: 0;
}
.instructions li {
padding: var(--kt-ai-space-2) 0;
color: var(--kt-ai-fg-muted);
line-height: 1.5;
}
.instructions li strong {
color: var(--kt-ai-fg);
}
.win-message {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--kt-ai-card-bg);
border: 2px solid var(--kt-ai-primary);
border-radius: var(--kt-ai-radius-2xl);
padding: var(--kt-ai-space-8);
text-align: center;
z-index: 1000;
display: none;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
.win-message.show {
display: block;
animation: popIn 0.3s ease-out;
}
@keyframes popIn {
from { transform: translate(-50%, -50%) scale(0.8); opacity: 0; }
to { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
.win-message h2 {
color: var(--kt-ai-primary);
margin-bottom: var(--kt-ai-space-4);
}
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 999;
display: none;
}
.overlay.show {
display: block;
}
</style>
</head>
<body>
<header class="kt-ai-pagehead">
<div class="kt-ai-wrap kt-ai-pagehead-in">
<a class="kt-ai-brand" href="#">
<img src="design-system/brand/kt-ai-logo.png" alt="KT AI" height="22">
<span>Кубик Рубика</span>
</a>
<span class="kt-ai-spacer"></span>
<a class="kt-ai-btn" data-variant="ghost" href="#instructions">Как играть</a>
</div>
</header>
<main class="kt-ai-wrap" style="padding-top: var(--kt-ai-space-8); padding-bottom: var(--kt-ai-space-8);">
<section class="kt-ai-hero" data-align="center" style="padding: var(--kt-ai-space-4) 0;">
<h1>Собери Кубик Рубика</h1>
<p class="kt-ai-hero-sub">Классическая 3D головоломка в твоём браузере</p>
</section>
<div class="game-container">
<div class="scene">
<div class="cube" id="cube"></div>
</div>
<div class="stats">
<div class="stat-item">
<div class="stat-value" id="moves">0</div>
<div class="stat-label">Ходов</div>
</div>
<div class="stat-item">
<div class="stat-value" id="time">00:00</div>
<div class="stat-label">Время</div>
</div>
</div>
<div class="controls">
<div class="control-group">
<div class="control-group-title">Горизонтальные</div>
<div class="btn-row">
<button class="kt-ai-btn" data-size="sm" onclick="rotateLayer('U', -1)">U</button>
<button class="kt-ai-btn" data-size="sm" onclick="rotateLayer('D', 1)">D</button>
</div>
</div>
<div class="control-group">
<div class="control-group-title">Вертикальные</div>
<div class="btn-row">
<button class="kt-ai-btn" data-size="sm" onclick="rotateLayer('L', -1)">L</button>
<button class="kt-ai-btn" data-size="sm" onclick="rotateLayer('R', 1)">R</button>
</div>
</div>
<div class="control-group">
<div class="control-group-title">Передние/Задние</div>
<div class="btn-row">
<button class="kt-ai-btn" data-size="sm" onclick="rotateLayer('F', 1)">F</button>
<button class="kt-ai-btn" data-size="sm" onclick="rotateLayer('B', -1)">B</button>
</div>
</div>
<div class="control-group">
<div class="control-group-title">Действия</div>
<div class="btn-row">
<button class="kt-ai-btn" data-variant="primary" data-size="sm" onclick="scramble()">Перемешать</button>
<button class="kt-ai-btn" data-size="sm" onclick="showHint()">Подсказать</button>
<button class="kt-ai-btn" data-variant="danger" data-size="sm" onclick="resetGame()">Заново</button>
</div>
</div>
</div>
<div class="instructions" id="instructions">
<h3>Как играть</h3>
<ul>
<li><strong>Вращение кубика:</strong> зажмите левую кнопку мыши на кубике и перетаскивайте</li>
<li><strong>Вращение слоёв:</strong> используйте кнопки U, D, L, R, F, B</li>
<li><strong>Цель:</strong> собрать кубик так, чтобы каждая грань была одного цвета</li>
<li><strong>Обозначения:</strong> U (верх), D (низ), L (лево), R (право), F (перед), B (зад)</li>
</ul>
</div>
</div>
</main>
<footer class="kt-ai-wrap kt-ai-pagefoot">
<span>© 2026 Кубик Рубика</span>
<span class="kt-ai-spacer"></span>
<span>Сделано с использованием KT AI Design System</span>
</footer>
<div class="overlay" id="overlay"></div>
<div class="win-message" id="winMessage">
<h2>Поздравляем!</h2>
<p style="margin-bottom: var(--kt-ai-space-4); color: var(--kt-ai-fg-muted);">Вы собрали кубик Рубика!</p>
<div class="stats" style="justify-content: center; margin-bottom: var(--kt-ai-space-4);">
<div class="stat-item">
<div class="stat-value" id="finalMoves">0</div>
<div class="stat-label">Ходов</div>
</div>
<div class="stat-item">
<div class="stat-value" id="finalTime">00:00</div>
<div class="stat-label">Время</div>
</div>
</div>
<button class="kt-ai-btn" data-variant="primary" onclick="resetGame()">Играть снова</button>
</div>
<script>
const COLORS = {
WHITE: 'white',
YELLOW: 'yellow',
RED: 'red',
ORANGE: 'orange',
BLUE: 'blue',
GREEN: 'green'
};
const FACES = ['front', 'back', 'right', 'left', 'top', 'bottom'];
const FACE_COLORS = {
front: COLORS.RED,
back: COLORS.ORANGE,
right: COLORS.BLUE,
left: COLORS.GREEN,
top: COLORS.WHITE,
bottom: COLORS.YELLOW
};
let cube = [];
let isAnimating = false;
let moveCount = 0;
let startTime = null;
let timerInterval = null;
let cubeRotationX = -25;
let cubeRotationY = -35;
let isDragging = false;
let lastMouseX = 0;
let lastMouseY = 0;
function createCubie(x, y, z) {
const cubie = document.createElement('div');
cubie.className = 'cubie';
cubie.dataset.x = x;
cubie.dataset.y = y;
cubie.dataset.z = z;
FACES.forEach(face => {
const faceEl = document.createElement('div');
faceEl.className = `face face-${face} face-${FACE_COLORS[face]}`;
if (face === 'front') faceEl.style.transform = 'rotateY(0deg) translateZ(48px)';
if (face === 'back') faceEl.style.transform = 'rotateY(180deg) translateZ(48px)';
if (face === 'right') faceEl.style.transform = 'rotateY(90deg) translateZ(48px)';
if (face === 'left') faceEl.style.transform = 'rotateY(-90deg) translateZ(48px)';
if (face === 'top') faceEl.style.transform = 'rotateX(90deg) translateZ(48px)';
if (face === 'bottom') faceEl.style.transform = 'rotateX(-90deg) translateZ(48px)';
cubie.appendChild(faceEl);
});
updateCubiePosition(cubie, x, y, z);
return cubie;
}
function updateCubiePosition(cubie, x, y, z) {
const offsetX = x * 100;
const offsetY = -y * 100;
const offsetZ = z * 100;
cubie.style.transform = `translate3d(${offsetX}px, ${offsetY}px, ${offsetZ}px)`;
}
function initCube() {
const cubeEl = document.getElementById('cube');
cubeEl.innerHTML = '';
cube = [];
for (let x = -1; x <= 1; x++) {
cube[x + 1] = [];
for (let y = -1; y <= 1; y++) {
cube[x + 1][y + 1] = [];
for (let z = -1; z <= 1; z++) {
const cubie = createCubie(x, y, z);
cube[x + 1][y + 1][z + 1] = {
element: cubie,
x, y, z,
colors: { ...FACE_COLORS }
};
cubeEl.appendChild(cubie);
}
}
}
}
function rotateLayer(layer, direction, isScramble = false) {
if (isAnimating) return;
isAnimating = true;
if (!startTime && !isScramble) startTimer();
const affectedCubies = [];
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
for (let z = 0; z < 3; z++) {
let include = false;
if (layer === 'U' && y === 1) include = true;
if (layer === 'D' && y === -1) include = true;
if (layer === 'L' && x === -1) include = true;
if (layer === 'R' && x === 1) include = true;
if (layer === 'F' && z === 1) include = true;
if (layer === 'B' && z === -1) include = true;
if (include) {
affectedCubies.push(cube[x + 1][y + 1][z + 1]);
}
}
}
}
const angle = 90 * direction;
const duration = 300;
const startTimeAnim = Date.now();
function animate() {
const elapsed = Date.now() - startTimeAnim;
const progress = Math.min(elapsed / duration, 1);
const easeProgress = 1 - Math.pow(1 - progress, 3);
const currentAngle = angle * easeProgress;
affectedCubies.forEach(cubie => {
let newX = cubie.x;
let newY = cubie.y;
let newZ = cubie.z;
if (layer === 'U' || layer === 'D') {
const cos = Math.cos(currentAngle * Math.PI / 180);
const sin = Math.sin(currentAngle * Math.PI / 180);
newX = Math.round(cubie.x * cos - cubie.z * sin);
newZ = Math.round(cubie.x * sin + cubie.z * cos);
} else if (layer === 'L' || layer === 'R') {
const cos = Math.cos(currentAngle * Math.PI / 180);
const sin = Math.sin(currentAngle * Math.PI / 180);
newY = Math.round(cubie.y * cos - cubie.z * sin);
newZ = Math.round(cubie.y * sin + cubie.z * cos);
} else if (layer === 'F' || layer === 'B') {
const cos = Math.cos(currentAngle * Math.PI / 180);
const sin = Math.sin(currentAngle * Math.PI / 180);
newX = Math.round(cubie.x * cos - cubie.y * sin);
newY = Math.round(cubie.x * sin + cubie.y * cos);
}
updateCubiePosition(cubie.element, newX, newY, newZ);
const faceElements = cubie.element.querySelectorAll('.face');
faceElements.forEach(face => {
face.style.transform = face.style.transform + ` rotate${getRotationAxis(layer)}(${currentAngle}deg)`;
});
});
if (progress < 1) {
requestAnimationFrame(animate);
} else {
affectedCubies.forEach(cubie => {
let newX = cubie.x;
let newY = cubie.y;
let newZ = cubie.z;
if (layer === 'U' || layer === 'D') {
const temp = newX;
if (direction > 0) {
newX = -newZ;
newZ = temp;
} else {
newX = newZ;
newZ = -temp;
}
} else if (layer === 'L' || layer === 'R') {
const temp = newY;
if (direction > 0) {
newY = -newZ;
newZ = temp;
} else {
newY = newZ;
newZ = -temp;
}
} else if (layer === 'F' || layer === 'B') {
const temp = newX;
if (direction > 0) {
newX = -newY;
newY = temp;
} else {
newX = newY;
newY = -temp;
}
}
cubie.x = newX;
cubie.y = newY;
cubie.z = newZ;
const tempColors = { ...cubie.colors };
if (layer === 'U' || layer === 'D') {
if (direction > 0) {
cubie.colors.front = tempColors.right;
cubie.colors.right = tempColors.back;
cubie.colors.back = tempColors.left;
cubie.colors.left = tempColors.front;
} else {
cubie.colors.front = tempColors.left;
cubie.colors.left = tempColors.back;
cubie.colors.back = tempColors.right;
cubie.colors.right = tempColors.front;
}
}
const newFaceElements = cubie.element.querySelectorAll('.face');
newFaceElements.forEach(face => {
face.style.transform = '';
const faceClass = Array.from(face.classList).find(c => c.startsWith('face-'));
if (faceClass) {
const faceName = faceClass.replace('face-', '');
face.className = `face face-${faceName} face-${cubie.colors[faceName]}`;
if (faceName === 'front') face.style.transform = 'rotateY(0deg) translateZ(48px)';
if (faceName === 'back') face.style.transform = 'rotateY(180deg) translateZ(48px)';
if (faceName === 'right') face.style.transform = 'rotateY(90deg) translateZ(48px)';
if (faceName === 'left') face.style.transform = 'rotateY(-90deg) translateZ(48px)';
if (faceName === 'top') face.style.transform = 'rotateX(90deg) translateZ(48px)';
if (faceName === 'bottom') face.style.transform = 'rotateX(-90deg) translateZ(48px)';
}
});
updateCubiePosition(cubie.element, cubie.x, cubie.y, cubie.z);
const oldCubie = cube[cubie.x + 1][cubie.y + 1][cubie.z + 1];
if (oldCubie && oldCubie !== cubie) {
const temp = { ...oldCubie };
cube[cubie.x + 1][cubie.y + 1][cubie.z + 1] = cubie;
} else {
cube[cubie.x + 1][cubie.y + 1][cubie.z + 1] = cubie;
}
});
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
for (let z = 0; z < 3; z++) {
const cubie = cube[x][y][z];
if (cubie.x !== x - 1 || cubie.y !== y - 1 || cubie.z !== z - 1) {
const targetCubie = cube[cubie.x + 1][cubie.y + 1][cubie.z + 1];
cube[x][y][z] = targetCubie;
}
}
}
}
isAnimating = false;
moveCount++;
document.getElementById('moves').textContent = moveCount;
checkWin();
}
}
animate();
}
function getRotationAxis(layer) {
if (layer === 'U' || layer === 'D') return 'Y';
if (layer === 'L' || layer === 'R') return 'X';
return 'Z';
}
function scramble() {
if (isAnimating) return;
const layers = ['U', 'D', 'L', 'R', 'F', 'B'];
const moves = 20;
let currentMove = 0;
resetGame();
moveHistory = [];
function nextMove() {
if (currentMove >= moves) return;
const layer = layers[Math.floor(Math.random() * layers.length)];
const direction = Math.random() > 0.5 ? 1 : -1;
moveHistory.push({ layer, direction });
rotateLayer(layer, direction, true);
currentMove++;
setTimeout(nextMove, 350);
}
nextMove();
}
function startTimer() {
startTime = Date.now();
timerInterval = setInterval(() => {
const elapsed = Math.floor((Date.now() - startTime) / 1000);
const minutes = Math.floor(elapsed / 60).toString().padStart(2, '0');
const seconds = (elapsed % 60).toString().padStart(2, '0');
document.getElementById('time').textContent = `${minutes}:${seconds}`;
}, 1000);
}
function checkWin() {
let isWin = true;
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
for (let z = 0; z < 3; z++) {
const cubie = cube[x][y][z];
if (cubie.x === -1 && cubie.colors.left !== COLORS.GREEN) isWin = false;
if (cubie.x === 1 && cubie.colors.right !== COLORS.BLUE) isWin = false;
if (cubie.y === 1 && cubie.colors.top !== COLORS.WHITE) isWin = false;
if (cubie.y === -1 && cubie.colors.bottom !== COLORS.YELLOW) isWin = false;
if (cubie.z === 1 && cubie.colors.front !== COLORS.RED) isWin = false;
if (cubie.z === -1 && cubie.colors.back !== COLORS.ORANGE) isWin = false;
}
}
}
if (isWin && moveCount > 0) {
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
}
document.getElementById('finalMoves').textContent = moveCount;
document.getElementById('finalTime').textContent = document.getElementById('time').textContent;
document.getElementById('winMessage').classList.add('show');
document.getElementById('overlay').classList.add('show');
}
}
function updateCubeRotation() {
const cubeEl = document.getElementById('cube');
cubeEl.style.transform = `rotateX(${cubeRotationX}deg) rotateY(${cubeRotationY}deg)`;
}
const scene = document.querySelector('.scene');
scene.addEventListener('mousedown', (e) => {
if (e.target.closest('.cubie')) {
isDragging = true;
lastMouseX = e.clientX;
lastMouseY = e.clientY;
scene.style.cursor = 'grabbing';
}
});
document.addEventListener('mousemove', (e) => {
if (isDragging) {
const deltaX = e.clientX - lastMouseX;
const deltaY = e.clientY - lastMouseY;
cubeRotationY += deltaX * 0.5;
cubeRotationX -= deltaY * 0.5;
cubeRotationX = Math.max(-90, Math.min(90, cubeRotationX));
updateCubeRotation();
lastMouseX = e.clientX;
lastMouseY = e.clientY;
}
});
document.addEventListener('mouseup', () => {
isDragging = false;
scene.style.cursor = 'grab';
});
scene.addEventListener('mouseleave', () => {
isDragging = false;
scene.style.cursor = 'grab';
});
scene.style.cursor = 'grab';
document.addEventListener('touchstart', (e) => {
if (e.target.closest('.cubie')) {
isDragging = true;
lastMouseX = e.touches[0].clientX;
lastMouseY = e.touches[0].clientY;
}
}, { passive: true });
document.addEventListener('touchmove', (e) => {
if (isDragging) {
e.preventDefault();
const deltaX = e.touches[0].clientX - lastMouseX;
const deltaY = e.touches[0].clientY - lastMouseY;
cubeRotationY += deltaX * 0.5;
cubeRotationX -= deltaY * 0.5;
cubeRotationX = Math.max(-90, Math.min(90, cubeRotationX));
updateCubeRotation();
lastMouseX = e.touches[0].clientX;
lastMouseY = e.touches[0].clientY;
}
}, { passive: false });
document.addEventListener('touchend', () => {
isDragging = false;
});
initCube();
let moveHistory = [];
let hintTimeout = null;
function showHint() {
const moveNames = {
'U': { name: 'Верх (U)', axis: 'Y' },
'D': { name: 'Низ (D)', axis: 'Y' },
'L': { name: 'Лево (L)', axis: 'X' },
'R': { name: 'Право (R)', axis: 'X' },
'F': { name: 'Перед (F)', axis: 'Z' },
'B': { name: 'Зад (B)', axis: 'Z' }
};
if (moveHistory.length === 0) {
showHintMessage('Нажмите «Перемешать» и начните решать!', 'info');
return;
}
const lastMove = moveHistory[moveHistory.length - 1];
const moveInfo = moveNames[lastMove.layer];
const directionText = lastMove.direction > 0 ? '→' : '←';
const message = `Последний ход: ${moveInfo.name} ${directionText}`;
showHintMessage(message, 'hint');
const cubies = getCubiesForLayer(lastMove.layer);
highlightCubies(cubies);
}
function getCubiesForLayer(layer) {
const cubies = [];
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
for (let z = 0; z < 3; z++) {
let include = false;
if (layer === 'U' && cube[x][y][z].y === 1) include = true;
if (layer === 'D' && cube[x][y][z].y === -1) include = true;
if (layer === 'L' && cube[x][y][z].x === -1) include = true;
if (layer === 'R' && cube[x][y][z].x === 1) include = true;
if (layer === 'F' && cube[x][y][z].z === 1) include = true;
if (layer === 'B' && cube[x][y][z].z === -1) include = true;
if (include) {
cubies.push(cube[x][y][z]);
}
}
}
}
return cubies;
}
function highlightCubies(cubies) {
cubies.forEach(cubie => {
cubie.element.style.filter = 'brightness(1.3) drop-shadow(0 0 8px var(--kt-ai-primary))';
});
if (hintTimeout) clearTimeout(hintTimeout);
hintTimeout = setTimeout(() => {
cubies.forEach(cubie => {
cubie.element.style.filter = '';
});
}, 2000);
}
function showHintMessage(text, type) {
let messageEl = document.getElementById('hintMessage');
if (!messageEl) {
messageEl = document.createElement('div');
messageEl.id = 'hintMessage';
messageEl.style.cssText = `
position: fixed;
top: 100px;
left: 50%;
transform: translateX(-50%);
background: var(--kt-ai-card-bg);
border: 2px solid var(--kt-ai-primary);
border-radius: var(--kt-ai-radius-lg);
padding: var(--kt-ai-space-4) var(--kt-ai-space-6);
z-index: 1001;
display: none;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
max-width: 400px;
text-align: center;
font-weight: var(--kt-ai-weight-medium);
`;
document.body.appendChild(messageEl);
}
messageEl.textContent = text;
messageEl.style.display = 'block';
setTimeout(() => {
messageEl.style.display = 'none';
}, 2500);
}
function resetGame() {
document.getElementById('winMessage').classList.remove('show');
document.getElementById('overlay').classList.remove('show');
moveCount = 0;
document.getElementById('moves').textContent = '0';
moveHistory = [];
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = null;
}
startTime = null;
document.getElementById('time').textContent = '00:00';
cubeRotationX = -25;
cubeRotationY = -35;
updateCubeRotation();
initCube();
}
</script>
</body>
</html>