const { Engine, World, Bodies, Body, Runner } = Matter;
const engine = Engine.create();
const runner = Runner.create();
const degreesToRadians = degrees => degrees * (Math.PI / 180);
const createBody = (elementId, isStatic, options = {}, customProperties = {}) => {
const element = document.getElementById(elementId);
const [x, y] = [element.offsetLeft + element.offsetWidth / 2, element.offsetTop + element.offsetHeight / 2];
const cssTransform = window.getComputedStyle(element).transform;
let cssAngle = 0;
if (cssTransform && cssTransform !== 'none') {
const [a, b] = cssTransform.split('(')[1].split(')')[0].split(',');
cssAngle = Math.atan2(b, a);
}
return Bodies.rectangle(x, y, element.offsetWidth, element.offsetHeight, { isStatic, angle: cssAngle, ...options, ...customProperties });
};
// Custom properties
const playerProperties = { density: 0.9, restitution: 0.3, friction: 0.2, frictionAir: 0.04 };
const dynamicXProperties = { density: 0.7, restitution: 0.6, friction: 0.2, frictionAir: 0.05 };
const staticBodyProperties = { restitution: 0.9, friction: 1.0 };
const playerBody = createBody('home-player', false, {}, playerProperties);
const dynamicXBody = createBody('home-dynamic-x', false, {}, dynamicXProperties);
[...Array(21).keys()].map(i => createBody(`home-st-${i + 1}`, true, {}, staticBodyProperties))
.forEach(body => World.add(engine.world, body));
Body.setAngularVelocity(dynamicXBody, 0.1);
Body.setAngularVelocity(playerBody, 0);
const applyForceToPlayer = force => {
const maxVelocity = 4;
if (Math.hypot(playerBody.velocity.x, playerBody.velocity.y) < maxVelocity) {
Body.applyForce(playerBody, playerBody.position, force);
}
};
document.addEventListener('keydown', ({ keyCode }) => {
const forceMagnitude = 0.025 * playerBody.mass;
const forces = { 37: [-forceMagnitude, 0], 38: [0, -forceMagnitude * 1.2], 39: [forceMagnitude, 0] };
if (forces[keyCode]) applyForceToPlayer({ x: forces[keyCode][0], y: forces[keyCode][1] });
});
const updateElementFromBody = (elementId, body) => {
const element = document.getElementById(elementId);
element.style.cssText = `top: ${body.position.y - element.offsetHeight / 2}px; left: ${body.position.x - element.offsetWidth / 2}px; transform: rotate(${body.angle}rad);`;
};
Runner.run(runner, engine);
Matter.Events.on(engine, 'afterUpdate', () => {
updateElementFromBody('home-player', playerBody);
updateElementFromBody('home-dynamic-x', dynamicXBody);
[...Array(21).keys()].forEach(i => updateElementFromBody(`home-st-${i + 1}`, staticBodies[i]));
});
document.querySelector('.close').addEventListener('click', function() {
// Master volume control
const masterVolume = new Tone.Volume(-5).toDestination();
// Create synths with different wave types and connect them to the master volume control
const waveTypes = ['sine', 'triangle', 'square'];
const synths = waveTypes.map(waveType => {
const synth = new Tone.Synth().connect(masterVolume);
synth.oscillator.type = waveType;
return synth;
});
// Create an autoFilter, reverb, and distortion, and chain them together
const autoFilter = new Tone.AutoFilter({'frequency': '8m', 'min': 800, 'max': 15000}).connect(masterVolume);
const reverb = new Tone.Reverb().set({wet: 0.5}).connect(masterVolume);
const distortion = new Tone.Distortion(0.8).connect(masterVolume);
// Connect synths to autoFilter, which is already connected to reverb and distortion
synths.forEach(synth => synth.connect(autoFilter));
autoFilter.connect(reverb).connect(distortion);
// Start the autoFilter
autoFilter.start();
// Define and start loops for each synth with random volume adjustments
synths.forEach((synth, index) => {
new Tone.Loop(time => {
synth.volume.value = Math.random() * -10; // Random volume between -10 and 0 dB
synth.triggerAttackRelease(Tone.Midi(Math.random() * 5 + 44).toFrequency(), '8n', time);
}, ['4n', '2n', '1m'][index]).start(0); // Different loop intervals for each synth
});
// Start the Tone.js context
Tone.Transport.start();
});
// Generates a code based on the current time, character set, and offset multiplier
function generateCode(characters, offsetMultiplier) {
const currentTime = Math.floor(Date.now() / 60000);
let code = '';
for (let i = 0; i < 6; i++) {
const index = (currentTime + i * offsetMultiplier) % characters.length;
code += characters.charAt(index);
}
return code;
}
// Updates the displayed code for code1
function updateCode1Display() {
const code = generateCode('0123456789', 7);
document.getElementById('code1').textContent = code;
}
// Verifies the entered code against the generated code and updates the UI accordingly
function verifyCode2() {
const enteredCode = document.getElementById('enteredCode2').value;
const currentCode = generateCode('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 5);
const success = enteredCode === currentCode;
document.getElementById('hiddenElement2').style.display = success ? 'block' : 'none';
document.getElementById('errorMessage2').style.display = success ? 'none' : 'block';
document.getElementById('in-code').style.display = success ? 'none' : 'block';
if (success) {
// Start a 30-second timer to update UI elements
setTimeout(() => {
document.querySelectorAll('.home-ai-load, .home-em, .home-bt-ai').forEach(el => {
el.style.display = el.classList.contains('home-ai-load') ? 'none' : 'block';
});
}, 30000); // 30000 milliseconds = 30 seconds
}
}
// Set interval to update Code 1 display every second
setInterval(updateCode1Display, 1000);
// Add event listener to submit button for verifying code 2 on DOM content loaded
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('submitButton2').addEventListener('click', verifyCode2);
});
function
unlockMystery() {
// Behind the artefact, the secret awaits.
}
function
inputCode(code) {
// Enter the discovered code here.
if (code
=== '*****') {
// Mystery unlocked.
} else {
// Keep searching.
} }