0% found this document useful (0 votes)
68 views12 pages

Rubik

The document outlines a web-based 3D game for solving a Rubik's Cube, featuring interactive controls and a visually appealing design. It includes HTML, CSS, and JavaScript code to create the game interface, manage user interactions, and render the 3D cube using Three.js. Players can rotate cube faces, scramble, and reset the cube, with a win message displayed upon solving it.

Uploaded by

codytran8
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
68 views12 pages

Rubik

The document outlines a web-based 3D game for solving a Rubik's Cube, featuring interactive controls and a visually appealing design. It includes HTML, CSS, and JavaScript code to create the game interface, manage user interactions, and render the 3D cube using Three.js. Players can rotate cube faces, scramble, and reset the cube, with a win message displayed upon solving it.

Uploaded by

codytran8
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

<!

DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Rubik's Cube 3D Game</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
color: white;
overflow: hidden;
height: 100vh;
display: flex;
flex-direction: column;
}

header {
background: rgba(0, 0, 0, 0.3);
padding: 1rem;
text-align: center;
backdrop-filter: blur(10px);
z-index: 100;
}

h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}

.game-container {
flex: 1;
display: flex;
position: relative;
}

#canvas-container {
flex: 1;
position: relative;
}

.controls {
position: absolute;
top: 20px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 20px;
border-radius: 10px;
backdrop-filter: blur(10px);
max-width: 300px;
}
.control-group {
margin-bottom: 15px;
}

.control-group h3 {
margin-bottom: 10px;
color: #ffd700;
font-size: 1.1rem;
}

.control-row {
display: flex;
gap: 10px;
margin-bottom: 8px;
flex-wrap: wrap;
}

button {
background: linear-gradient(145deg, #4a90e2, #357abd);
color: white;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
}

button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.4);
background: linear-gradient(145deg, #5ba0f2, #4080cd);
}

button:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.action-buttons {
display: flex;
gap: 10px;
margin-top: 15px;
}

.action-buttons button {
flex: 1;
padding: 12px;
font-weight: bold;
}

.scramble-btn {
background: linear-gradient(145deg, #e74c3c, #c0392b) !important;
}

.reset-btn {
background: linear-gradient(145deg, #27ae60, #229954) !important;
}
.info {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 10px;
backdrop-filter: blur(10px);
max-width: 250px;
}

.info h3 {
color: #ffd700;
margin-bottom: 10px;
}

.info p {
font-size: 14px;
line-height: 1.5;
margin-bottom: 5px;
}

.win-message {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.9);
padding: 40px;
border-radius: 20px;
text-align: center;
display: none;
z-index: 1000;
animation: fadeIn 0.5s ease;
}

.win-message h2 {
font-size: 3rem;
color: #ffd700;
margin-bottom: 20px;
text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.5);
}

.win-message button {
padding: 15px 30px;
font-size: 18px;
background: linear-gradient(145deg, #ffd700, #ffed4e);
color: #333;
}

@keyframes fadeIn {
from {
opacity: 0;
transform: translate(-50%, -50%) scale(0.8);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}

.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
color: #ffd700;
}
</style>
</head>
<body>
<header>
<h1>🎲 Rubik's Cube 3D</h1>
<p>Solve the classic puzzle in 3D!</p>
</header>

<div class="game-container">
<div id="canvas-container">
<div class="loading">Loading 3D Environment...</div>
</div>

<div class="controls">
<div class="control-group">
<h3>🎮 Face Controls</h3>
<div class="control-row">
<button onclick="rotateFace('F')">F (Front)</button>
<button onclick="rotateFace('B')">B (Back)</button>
</div>
<div class="control-row">
<button onclick="rotateFace('U')">U (Up)</button>
<button onclick="rotateFace('D')">D (Down)</button>
</div>
<div class="control-row">
<button onclick="rotateFace('L')">L (Left)</button>
<button onclick="rotateFace('R')">R (Right)</button>
</div>
</div>

<div class="control-group">
<h3>⌨️ Keyboard Shortcuts</h3>
<p>F/B/U/D/L/R - Rotate faces</p>
<p>Shift + Key - Counter-clockwise</p>
<p>Mouse - Rotate view</p>
<p>Scroll - Zoom</p>
</div>

<div class="action-buttons">
<button class="scramble-btn" onclick="scrambleCube()">🔀
Scramble</button>
<button class="reset-btn" onclick="resetCube()">🔄 Reset</button>
</div>
</div>

<div class="info">
<h3>📊 Game Info</h3>
<p>Moves: <span id="move-count">0</span></p>
<p>Status: <span id="game-status">Ready</span></p>
</div>
</div>

<div class="win-message" id="win-message">


<h2>🎉 Congratulations!</h2>
<p>You solved the Rubik's Cube!</p>
<p>Total moves: <span id="final-moves">0</span></p>
<button onclick="hideWinMessage()">Play Again</button>
</div>

<script
src="[Link]
<script>
// Global variables
let scene, camera, renderer;
let cubeGroup;
let cubies = [];
let isRotating = false;
let moveCount = 0;
let mouse = { x: 0, y: 0 };
let mouseDown = false;

// Colors for each face


const colors = {
F: 0xff0000, // Red - Front
B: 0xff8c00, // Orange - Back
U: 0xffffff, // White - Up
D: 0xffff00, // Yellow - Down
L: 0x00ff00, // Green - Left
R: 0x0000ff // Blue - Right
};

// Initialize [Link] scene


function init() {
// Scene setup
scene = new [Link]();
[Link] = new [Link](0x1a1a2e);

// Camera setup
camera = new [Link](
75,
[Link] / [Link],
0.1,
1000
);
[Link](5, 5, 5);
[Link](0, 0, 0);

// Renderer setup
renderer = new [Link]({ antialias: true });
[Link]([Link], [Link]);
[Link] = true;
[Link] = [Link];

const container = [Link]('canvas-container');


[Link] = '';
[Link]([Link]);
// Lighting
const ambientLight = new [Link](0xffffff, 0.6);
[Link](ambientLight);

const directionalLight = new [Link](0xffffff, 0.8);


[Link](10, 10, 5);
[Link] = true;
[Link] = 0.1;
[Link] = 50;
[Link] = -10;
[Link] = 10;
[Link] = 10;
[Link] = -10;
[Link](directionalLight);

// Create cube
createCube();

// Event listeners
setupEventListeners();

// Start animation loop


animate();
}

// Create the Rubik's cube


function createCube() {
cubeGroup = new [Link]();
cubies = [];

const geometry = new [Link](0.95, 0.95, 0.95);

for (let x = -1; x <= 1; x++) {


for (let y = -1; y <= 1; y++) {
for (let z = -1; z <= 1; z++) {
if (x === 0 && y === 0 && z === 0) continue; // Skip center

const materials = [];


for (let i = 0; i < 6; i++) {
[Link](new [Link]({
color: 0x333333,
shininess: 100
}));
}

const cubie = new [Link](geometry, materials);


[Link](x, y, z);
[Link] = true;
[Link] = true;

// Store original position


[Link] = { x, y, z };

// Set face colors


updateCubieColors(cubie);

[Link](cubie);
[Link](cubie);
}
}
}

[Link](cubeGroup);
}

// Update cubie face colors based on position


function updateCubieColors(cubie) {
const { x, y, z } = [Link];
const materials = [Link];

// Front face (z = 1)
if (z === 1) materials[0].[Link](colors.F);
else materials[0].[Link](0x333333);

// Back face (z = -1)


if (z === -1) materials[1].[Link](colors.B);
else materials[1].[Link](0x333333);

// Top face (y = 1)
if (y === 1) materials[2].[Link](colors.U);
else materials[2].[Link](0x333333);

// Bottom face (y = -1)


if (y === -1) materials[3].[Link](colors.D);
else materials[3].[Link](0x333333);

// Right face (x = 1)
if (x === 1) materials[4].[Link](colors.R);
else materials[4].[Link](0x333333);

// Left face (x = -1)


if (x === -1) materials[5].[Link](colors.L);
else materials[5].[Link](0x333333);
}

// Rotate a face of the cube


function rotateFace(face, counterClockwise = false) {
if (isRotating) return;

isRotating = true;
moveCount++;
[Link]('move-count').textContent = moveCount;

const rotationGroup = new [Link]();


const affectedCubies = [];

// Determine which cubies to rotate


[Link](cubie => {
const { x, y, z } = [Link];
let shouldRotate = false;

switch (face) {
case 'F': shouldRotate = z === 1; break;
case 'B': shouldRotate = z === -1; break;
case 'U': shouldRotate = y === 1; break;
case 'D': shouldRotate = y === -1; break;
case 'L': shouldRotate = x === -1; break;
case 'R': shouldRotate = x === 1; break;
}

if (shouldRotate) {
[Link](cubie);
[Link](cubie);
}
});

[Link](rotationGroup);

// Perform rotation
const angle = counterClockwise ? [Link] / 2 : -[Link] / 2;
const duration = 300;
const startTime = [Link]();

function animateRotation() {
const elapsed = [Link]() - startTime;
const progress = [Link](elapsed / duration, 1);
const easeProgress = 1 - [Link](1 - progress, 3); // Ease out
cubic

let axis;
switch (face) {
case 'F':
case 'B':
axis = new THREE.Vector3(0, 0, face === 'F' ? 1 : -1);
break;
case 'U':
case 'D':
axis = new THREE.Vector3(0, face === 'U' ? 1 : -1, 0);
break;
case 'L':
case 'R':
axis = new THREE.Vector3(face === 'R' ? 1 : -1, 0, 0);
break;
}

[Link](
new [Link]().setFromAxisAngle(axis, angle *
easeProgress)
);

if (progress < 1) {
requestAnimationFrame(animateRotation);
} else {
// Update positions
[Link](cubie => {
const worldPos = new THREE.Vector3();
[Link](worldPos);
[Link](worldPos);
[Link](0, 0, 0);

// Update user data


[Link].x = [Link]([Link].x);
[Link].y = [Link]([Link].y);
[Link].z = [Link]([Link].z);

// Update colors
updateCubieColors(cubie);
});

[Link](rotationGroup);
[Link](...affectedCubies);
isRotating = false;

// Check win condition


if (checkWin()) {
showWinMessage();
}
}
}

animateRotation();
}

// Check if the cube is solved


function checkWin() {
// Check each face
const faces = ['F', 'B', 'U', 'D', 'L', 'R'];

for (let face of faces) {


let faceColor = null;
let faceCubies = [];

// Get cubies on this face


[Link](cubie => {
const { x, y, z } = [Link];
let onFace = false;

switch (face) {
case 'F': onFace = z === 1; break;
case 'B': onFace = z === -1; break;
case 'U': onFace = y === 1; break;
case 'D': onFace = y === -1; break;
case 'L': onFace = x === -1; break;
case 'R': onFace = x === 1; break;
}

if (onFace) {
[Link](cubie);
}
});

// Check if all cubies on this face have the same color


for (let cubie of faceCubies) {
const materialIndex = getMaterialIndexForFace(face);
const color = [Link][materialIndex].[Link]();

if (faceColor === null) {


faceColor = color;
} else if (faceColor !== color) {
return false;
}
}
}

return true;
}
// Get material index for a face
function getMaterialIndexForFace(face) {
switch (face) {
case 'F': return 0;
case 'B': return 1;
case 'U': return 2;
case 'D': return 3;
case 'L': return 5;
case 'R': return 4;
}
}

// Scramble the cube


function scrambleCube() {
if (isRotating) return;

[Link]('game-status').textContent = 'Scrambling...';
moveCount = 0;
[Link]('move-count').textContent = moveCount;

const faces = ['F', 'B', 'U', 'D', 'L', 'R'];


const moves = 20;
let currentMove = 0;

function performScrambleMove() {
if (currentMove >= moves) {
[Link]('game-status').textContent =
'Scrambled!';
return;
}

const randomFace = faces[[Link]([Link]() * [Link])];


const randomDirection = [Link]() < 0.5;

rotateFace(randomFace, randomDirection);
currentMove++;

setTimeout(performScrambleMove, 350);
}

performScrambleMove();
}

// Reset the cube


function resetCube() {
if (isRotating) return;

[Link](cubeGroup);
createCube();
moveCount = 0;
[Link]('move-count').textContent = moveCount;
[Link]('game-status').textContent = 'Ready';
}

// Show win message


function showWinMessage() {
[Link]('final-moves').textContent = moveCount;
[Link]('win-message').[Link] = 'block';
[Link]('game-status').textContent = 'Solved!';
}

// Hide win message


function hideWinMessage() {
[Link]('win-message').[Link] = 'none';
resetCube();
}

// Setup event listeners


function setupEventListeners() {
// Mouse controls
[Link]('mousedown', (e) => {
mouseDown = true;
mouse.x = [Link];
mouse.y = [Link];
});

[Link]('mousemove', (e) => {


if (!mouseDown) return;

const deltaX = [Link] - mouse.x;


const deltaY = [Link] - mouse.y;

[Link].y += deltaX * 0.01;


[Link].x += deltaY * 0.01;

mouse.x = [Link];
mouse.y = [Link];
});

[Link]('mouseup', () => {
mouseDown = false;
});

// Mouse wheel zoom


[Link]('wheel', (e) => {
[Link]();
[Link](1 + [Link] * 0.001);
});

// Keyboard controls
[Link]('keydown', (e) => {
const key = [Link]();
const counterClockwise = [Link];

switch (key) {
case 'F':
case 'B':
case 'U':
case 'D':
case 'L':
case 'R':
rotateFace(key, counterClockwise);
break;
}
});

// Window resize
[Link]('resize', () => {
[Link] = [Link] / [Link];
[Link]();
[Link]([Link], [Link]);
});
}

// Animation loop
function animate() {
requestAnimationFrame(animate);

// Auto-rotate when not interacting


if (!mouseDown) {
[Link].y += 0.002;
}

[Link](scene, camera);
}

// Initialize the game


init();
</script>
</body>
</html>

You might also like