CODE:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bounce Ascent</title>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<style>
.bounceascent7845-body {
font-family: 'Roboto', sans-serif;
margin: 0;
padding: 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: #ffffff;
}
.bounceascent7845-game-container {
display: flex;
flex-direction: column;
align-items: center;
}
.bounceascent7845-game-area {
width: 90vw;
max-width: 600px;
height: 80vh;
background: rgba(255, 255, 255, 0.1);
border-radius: 20px;
position: relative;
overflow: hidden;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(5px);
}
.bounceascent7845-platform {
width: 100px;
height: 20px;
background: linear-gradient(90deg, #00d2ff 0%, #3a7bd5 100%);
position: absolute;
border-radius: 10px;
cursor: move;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s ease;
}
.bounceascent7845-platform:hover {
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2);
}
.bounceascent7845-object {
position: absolute;
font-size: 24px;
color: #FFD700;
text-shadow: 0 0 10px rgba(255, 215, 0, 0.7);
will-change: transform;
}
.bounceascent7845-controls {
margin-top: 20px;
display: flex;
gap: 20px;
}
.bounceascent7845-button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
color: white;
border: none;
border-radius: 50px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.bounceascent7845-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2);
}
.bounceascent7845-stats {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
width: 90vw;
max-width: 600px;
}
.bounceascent7845-instructions {
position: absolute;
top: 10px;
left: 10px;
background: rgba(255, 255, 255, 0.2);
padding: 10px;
border-radius: 10px;
font-size: 14px;
max-width: 200px;
}
@media (max-width: 768px) {
.bounceascent7845-game-area {
width: 95vw;
height: 70vh;
}
.bounceascent7845-instructions {
display: none;
}
.bounceascent7845-stats {
font-size: 14px;
}
}
</style>
</head>
<body class="bounceascent7845-body">
<div class="bounceascent7845-game-container">
<div class="bounceascent7845-stats">
<div>Total: <span id="total">0</span></div>
<div>Bounced up: <span id="bouncedUp">0</span></div>
<div>% of bounced up: <span id="percentageBounced">0%</span></div>
</div>
<div class="bounceascent7845-game-area" id="gameArea">
<div class="bounceascent7845-instructions">
Drag platforms to bounce objects. Push objects above the top edge to score!
</div>
</div>
<div class="bounceascent7845-controls">
<button class="bounceascent7845-button" id="startButton">Start Game</button>
<button class="bounceascent7845-button" id="newGameButton">New Game</button>
</div>
</div>
<script>
const gameArea = document.getElementById('gameArea');
const totalElement = document.getElementById('total');
const bouncedUpElement = document.getElementById('bouncedUp');
const percentageBouncedElement = document.getElementById('percentageBounced');
const startButton = document.getElementById('startButton');
const newGameButton = document.getElementById('newGameButton');
let total = 0;
let bouncedUp = 0;
let animationId;
let objects = [];
let platforms = [];
let gameRunning = false;
const objectIcons = ['fa-star', 'fa-heart', 'fa-bolt', 'fa-diamond', 'fa-moon'];
const gravity = 0.2;
const bounceCoefficient = 0.8;
const isMobile = window.innerWidth <= 768;
const objectSpawnRate = isMobile ? 0.01 : 0.03; // Increased by 50% for desktop
const objectSpeed = isMobile ? 1 : 2;
const platformCount = isMobile ? 2 : 3;
const jumpHeightFactor = isMobile ? 0.3 : 0.6; // Doubled for desktop
class GameObject {
constructor(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.velocityX = 0;
this.velocityY = 0;
}
intersects(other) {
return this.x < other.x + other.width &&
this.x + this.width > other.x &&
this.y < other.y + other.height &&
this.y + this.height > other.y;
}
}
class Platform extends GameObject {
constructor(x, y) {
super(x, y, 100, 20);
this.element = document.createElement('div');
this.element.className = 'bounceascent7845-platform';
this.element.style.left = `${x}px`;
this.element.style.top = `${y}px`;
gameArea.appendChild(this.element);
this.setupDragging();
}
setupDragging() {
let isDragging = false;
let startX, startY, startLeft, startTop;
const onMouseDown = (e) => {
isDragging = true;
startX = e.clientX || e.touches[0].clientX;
startY = e.clientY || e.touches[0].clientY;
startLeft = this.x;
startTop = this.y;
e.preventDefault();
};
const onMouseMove = (e) => {
if (!isDragging) return;
const x = e.clientX || e.touches[0].clientX;
const y = e.clientY || e.touches[0].clientY;
const newLeft = startLeft + x - startX;
const newTop = startTop + y - startY;
this.x = Math.max(0, Math.min(gameArea.offsetWidth - this.width, newLeft));
this.y = Math.max(0, Math.min(gameArea.offsetHeight - this.height, newTop));
this.updatePosition();
};
const onMouseUp = () => {
isDragging = false;
};
this.element.addEventListener('mousedown', onMouseDown);
this.element.addEventListener('touchstart', onMouseDown);
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('touchmove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
document.addEventListener('touchend', onMouseUp);
}
updatePosition() {
this.element.style.left = `${this.x}px`;
this.element.style.top = `${this.y}px`;
}
}
class FallingObject extends GameObject {
constructor(x) {
super(x, -24, 24, 24);
this.element = document.createElement('i');
this.element.className = `bounceascent7845-object fas ${objectIcons[Math.floor(Math.random() * objectIcons.length)]}`;
this.element.style.left = `${x}px`;
this.element.style.top = `${this.y}px`;
gameArea.appendChild(this.element);
this.rotation = 0;
this.angularVelocity = (Math.random() - 0.5) * 10;
this.velocityX = (Math.random() - 0.5) * 4 * objectSpeed;
}
update() {
this.velocityY += gravity * objectSpeed;
this.x += this.velocityX;
this.y += this.velocityY;
this.rotation += this.angularVelocity;
if (this.x < 0 || this.x + this.width > gameArea.offsetWidth) {
this.velocityX *= -1;
}
this.updatePosition();
}
updatePosition() {
this.element.style.left = `${this.x}px`;
this.element.style.top = `${this.y}px`;
this.element.style.transform = `rotate(${this.rotation}deg)`;
}
remove() {
gameArea.removeChild(this.element);
}
}
function createPlatform() {
const x = Math.random() * (gameArea.offsetWidth - 100);
const y = Math.random() * (gameArea.offsetHeight - 20);
platforms.push(new Platform(x, y));
}
function createObject() {
const x = Math.random() * (gameArea.offsetWidth - 24);
objects.push(new FallingObject(x));
total++;
updateStats();
}
function checkCollisions() {
objects.forEach((object, index) => {
if (object.y + object.height < 0) {
object.remove();
objects.splice(index, 1);
bouncedUp++;
updateStats();
return;
}
if (object.y > gameArea.offsetHeight) {
object.remove();
objects.splice(index, 1);
updateStats();
return;
}
platforms.forEach(platform => {
if (object.intersects(platform)) {
const objectBottom = object.y + object.height;
const platformTop = platform.y;
if (objectBottom >= platformTop && objectBottom <= platformTop + platform.height && object.velocityY > 0) {
object.y = platform.y - object.height;
// Adjust the bounce height using the jumpHeightFactor
object.velocityY = -Math.sqrt(2 * gravity * gameArea.offsetHeight * jumpHeightFactor);
object.velocityX += (Math.random() - 0.5) * 2;
object.angularVelocity = (Math.random() - 0.5) * 20;
}
}
});
});
}
function updateStats() {
totalElement.textContent = total;
bouncedUpElement.textContent = bouncedUp;
const percentage = total > 0 ? ((bouncedUp / total) * 100).toFixed(2) : 0;
percentageBouncedElement.textContent = `${percentage}%`;
}
function gameLoop() {
objects.forEach(object => object.update());
checkCollisions();
if (Math.random() < objectSpawnRate) createObject();
animationId = requestAnimationFrame(gameLoop);
}
function startGame() {
if (!gameRunning) {
gameRunning = true;
total = 0;
bouncedUp = 0;
updateStats();
objects.forEach(obj => obj.remove());
objects = [];
platforms.forEach(platform => platform.element.remove());
platforms = [];
for (let i = 0; i < platformCount; i++) {
createPlatform();
}
gameLoop();
}
}
startButton.addEventListener('click', startGame);
newGameButton.addEventListener('click', () => {
cancelAnimationFrame(animationId);
startGame();
});
</script>
</body>
</html>