Scan to open on your phone
Point a camera at the QR code - it opens this exact paste, no app needed.
https://codepastes.com/zzgspt5yparpx3rqAsteroid BlasterPlain Text
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<!-- iOS PWA Meta Tags for Web App Installation -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Cosmic Defender">
<title>Cosmic Defender</title>
<style>
* {
box-sizing: border-box;
user-select: none;
-webkit-user-select: none;
margin: 0;
padding: 0;
}
body, html {
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
position: fixed;
}
#gameContainer {
position: relative;
width: 100vw;
height: 100vh;
background: radial-gradient(circle at center, #0c102b 0%, #010206 100%);
}
canvas {
display: block;
width: 100%;
height: 100%;
}
/* HUD Layout */
.hud {
position: absolute;
top: env(safe-area-inset-top, 20px);
left: 20px;
right: 20px;
display: flex;
justify-content: space-between;
color: #fff;
pointer-events: none;
font-size: 16px;
font-weight: bold;
text-shadow: 0 2px 4px rgba(0,0,0,0.8);
z-index: 10;
}
.health-container {
width: 140px;
height: 12px;
background: rgba(255,255,255,0.2);
border-radius: 6px;
overflow: hidden;
margin-top: 5px;
border: 1px solid rgba(255,255,255,0.4);
}
#healthBar {
width: 100%;
height: 100%;
background: linear-gradient(90deg, #ff416c, #ff4b2b);
transition: width 0.2s ease;
}
/* Split Control Interface */
.control-layer {
position: absolute;
bottom: env(safe-area-inset-bottom, 20px);
left: 0;
right: 0;
height: 160px;
display: flex;
justify-content: space-between;
padding: 0 40px;
pointer-events: none;
z-index: 20;
}
.btn-group {
display: flex;
flex-direction: column;
justify-content: center;
gap: 15px;
pointer-events: auto;
}
.ctrl-btn {
width: 70px;
height: 70px;
background: rgba(255, 255, 255, 0.12);
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
color: white;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
.ctrl-btn:active {
background: rgba(255, 255, 255, 0.35);
border-color: #fff;
}
/* Slider Region */
.slider-region {
width: 180px;
height: 80px;
background: rgba(255, 255, 255, 0.08);
border: 2px dashed rgba(255, 255, 255, 0.2);
border-radius: 40px;
align-self: center;
position: relative;
pointer-events: auto;
display: flex;
align-items: center;
justify-content: center;
color: rgba(255,255,255,0.4);
font-size: 12px;
}
.slider-handle {
position: absolute;
width: 64px;
height: 64px;
background: radial-gradient(circle, #4facfe 0%, #00f2fe 100%);
border-radius: 50%;
box-shadow: 0 0 15px #00f2fe;
left: calc(50% - 32px);
top: calc(50% - 32px);
touch-action: none;
}
/* Action Buttons Right Side */
.right-actions {
display: flex;
align-items: center;
gap: 20px;
pointer-events: auto;
}
.action-btn {
width: 80px;
height: 80px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: #fff;
box-shadow: 0 4px 15px rgba(0,0,0,0.5);
}
#fireBtn {
background: radial-gradient(circle, #ff0844 0%, #ffb199 100%);
box-shadow: 0 0 20px #ff0844;
font-size: 18px;
}
#shopBtn {
background: radial-gradient(circle, #f6d365 0%, #fda085 100%);
font-size: 14px;
width: 65px;
height: 65px;
}
/* Shop Modal Layer */
.modal {
display: none;
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
background: rgba(0,0,0,0.85);
z-index: 100;
justify-content: center;
align-items: center;
color: white;
}
.shop-box {
background: #111625;
border: 2px solid #4facfe;
border-radius: 16px;
padding: 25px;
width: 85%;
max-width: 400px;
text-align: center;
}
.shop-title {
font-size: 24px;
margin-bottom: 20px;
color: #00f2fe;
}
.shop-item {
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(255,255,255,0.05);
padding: 12px;
margin-bottom: 12px;
border-radius: 8px;
}
.shop-item button {
background: #00f2fe;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-weight: bold;
color: #000;
}
.close-shop {
margin-top: 15px;
background: #ff0844;
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
font-weight: bold;
}
</style>
</head>
<body>
<div id="gameContainer">
<!-- Game HUD -->
<div class="hud">
<div>
<div id="scoreDisplay">SCORE: 0</div>
<div class="health-container"><div id="healthBar"></div></div>
</div>
<div style="text-align: right;">
<div id="levelDisplay">LEVEL: 1</div>
<div id="scrapDisplay">SCRAP: 0</div>
</div>
</div>
<canvas id="gameCanvas"></canvas>
<!-- Interactive Splits Interface -->
<div class="control-layer">
<!-- Left Wing: Fixed Up/Down layout -->
<div class="btn-group">
<div class="ctrl-btn" id="upBtn">▲</div>
<div class="ctrl-btn" id="downBtn">▼</div>
</div>
<!-- Center-Right: Axis slider for side-to-side navigation -->
<div class="slider-region" id="sliderRegion">
SLIDE
<div class="slider-handle" id="sliderHandle"></div>
</div>
<!-- Far Right Side: Combat & Utility Actions -->
<div class="right-actions">
<div class="action-btn" id="shopBtn">SHOP</div>
<div class="action-btn" id="fireBtn">FIRE</div>
</div>
</div>
</div>
<!-- Shop UI Window -->
<div class="modal" id="shopModal">
<div class="shop-box">
<div class="shop-title">UPGRADE SHOP</div>
<div class="shop-item">
<div>Laser Speed (<span id="laserLvl">1</span>)</div>
<button id="buyLaser">Cost: 15</button>
</div>
<div class="shop-item">
<div>Max Health (<span id="healthLvl">1</span>)</div>
<button id="buyHealth">Cost: 20</button>
</div>
<button class="close-shop" id="closeShopBtn">BACK TO SPACE</button>
</div>
</div>
<script>
// --- Secure Mathematical Integrity State Architecture ---
const _secureState = {
_scoreHash: 0,
_scoreSalt: 4829,
setScore(val) {
this._scoreHash = val ^ this._scoreSalt;
},
getScore() {
return this._scoreHash ^ this._scoreSalt;
}
};
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// Display scaling normalization
function resize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
resize();
// Global Systems Configs
let player = {
x: canvas.width / 2,
y: canvas.height * 0.7,
r: 18,
hp: 100,
maxHp: 100,
speed: 6,
lastRegenTime: Date.now()
};
let scrap = 0;
let currentLevel = 1;
let lastFireTime = 0;
let fireDelay = 400; //ms
let lastDamageTime = 0;
let lasers = [];
let asteroids = [];
let stars = [];
// Controller variables
let moveUp = false;
let moveDown = false;
let slideXValue = 0;
// Starfield Background Initialization
for(let i=0; i<60; i++) {
stars.push({x: Math.random()*canvas.width, y: Math.random()*canvas.height, s: Math.random()*2 + 0.5});
}
// --- Dynamic Slider Engine Layout Config ---
const sliderRegion = document.getElementById('sliderRegion');
const sliderHandle = document.getElementById('sliderHandle');
let sliderActive = false;
let sliderStartX = 0;
Use code with caution.
sliderHandle.addEventListener('touchstart', (e) => {
sliderActive = true;
sliderStartX = e.touches.clientX - sliderHandle.offsetLeft;
});
window.addEventListener('touchmove', (e) => {
if (!sliderActive) return;
let bounds = sliderRegion.getBoundingClientRect();
let clientX = e.touches.clientX;
let relativeX = clientX - bounds.left - 32; // handle half-width center lock
// Strict boundary constraints
let maxLimit = bounds.width - 64;
if(relativeX < 0) relativeX = 0;
if(relativeX > maxLimit) relativeX = maxLimit;
sliderHandle.style.left = relativeX + 'px';
// Map positional parameters directly to scalar speed velocities (-1 to 1)
let midpoint = maxLimit / 2;
slideXValue = (relativeX - midpoint) / midpoint;
});
window.addEventListener('touchend', () => {
if(!sliderActive) return;
sliderActive = false;
sliderHandle.style.left = 'calc(50% - 32px)';
slideXValue = 0; // Return velocity back to baseline axis rest
});
// Fixed Buttons Event Routing
const bindBtn = (el, pressCallback, releaseCallback) => {
el.addEventListener('touchstart', (e) => { e.preventDefault(); pressCallback(); });
el.addEventListener('touchend', (e) => { e.preventDefault(); releaseCallback(); });
};
bindBtn(document.getElementById('upBtn'), () => moveUp = true, () => moveUp = false);
bindBtn(document.getElementById('downBtn'), () => moveDown = true, () => moveDown = false);
// Continuous fire system mapping
let continuousFiring = false;
document.getElementById('fireBtn').addEventListener('touchstart', (e) => { e.preventDefault(); continuousFiring = true; });
document.getElementById('fireBtn').addEventListener('touchend', () => continuousFiring = false);
// --- Upgrade Progression Engine Layout ---
const shopModal = document.getElementById('shopModal');
document.getElementById('shopBtn').addEventListener('click', () => shopModal.style.display = 'flex');
document.getElementById('closeShopBtn').addEventListener('click', () => shopModal.style.display = 'none');
let upgLaserLvl = 1;
let upgHealthLvl = 1;
document.getElementById('buyLaser').addEventListener('click', () => {
let cost = upgLaserLvl * 15;
if(scrap >= cost) {
scrap -= cost;
upgLaserLvl++;
fireDelay = Math.max(150, fireDelay - 60);
document.getElementById('laserLvl').innerText = upgLaserLvl;
document.getElementById('buyLaser').innerText = Cost: ${upgLaserLvl * 15};
updateHUD();
}
});
document.getElementById('buyHealth').addEventListener('click', () => {
let cost = upgHealthLvl * 20;
if(scrap >= cost) {
scrap -= cost;
upgHealthLvl++;
player.maxHp += 25;
player.hp = player.maxHp;
document.getElementById('healthLvl').innerText = upgHealthLvl;
document.getElementById('buyHealth').innerText = Cost: ${upgHealthLvl * 20};
updateHUD();
}
});
function updateHUD() {
document.getElementById('scoreDisplay').innerText = SCORE: ${_secureState.getScore()};
document.getElementById('scrapDisplay').innerText = SCRAP: ${scrap};
document.getElementById('levelDisplay').innerText = LEVEL: ${currentLevel};
document.getElementById('healthBar').style.width = ${(player.hp / player.maxHp) * 100}%;
}
function spawnAsteroid() {
let types = ['Standard', 'Fast', 'Armored', 'Explosive'];
let weights = [0.6, 0.2, 0.1, 0.1];
// Randomly select type based on raw procedural metrics
let rand = Math.random();
let selectedType = 'Standard';
let sum = 0;
for(let i=0; i<types.length; i++) {
sum += weights[i];
if(rand <= sum) { selectedType = types[i]; break; }
}
let radius = 20;
let speed = (Math.random() * 2 + 1.5) * (1 + currentLevel * 0.15);
let hp = 1;
let color = '#a1a8b8';
if(selectedType === 'Fast') {
radius = 12; speed *= 1.8; color = '#38ef7d';
} else if(selectedType === 'Armored') {
radius = 35; speed *= 0.6; hp = 4; color = '#ff9900';
} else if(selectedType === 'Explosive') {
radius = 22; speed *= 1.1; color = '#ff0844';
}
asteroids.push({
x: Math.random() * (canvas.width - 40) + 20,
y: -radius,
r: radius,
speed: speed,
hp: hp,
maxHp: hp,
type: selectedType,
color: color
});
}
function createExplosion(x, y, radius) {
// Trigger damage updates to hazards within immediate proximity metrics
for(let i = asteroids.length - 1; i >= 0; i--) {
let a = asteroids[i];
let dist = Math.hypot(a.x - x, a.y - y);
if(dist < radius + a.r) {
a.hp -= 3;
}
}
}
// --- Processing Game Loop Context ---
function update(dt) {
// Passive Nano Shield Regeneration Check
if(Date.now() - lastDamageTime > 4000) { // 4 seconds of avoiding threat vector
if(player.hp < player.maxHp) {
player.hp = Math.min(player.maxHp, player.hp + 0.12);
updateHUD();
}
}
// Navigation positioning parameters updates
if(moveUp) player.y -= player.speed;
if(moveDown) player.y += player.speed;
player.x += slideXValue * player.speed * 1.3;
// Screen space limits configuration
if(player.x < player.r) player.x = player.r;
if(player.x > canvas.width - player.r) player.x = canvas.width - player.r;
if(player.y < player.r) player.y = player.r;
if(player.y > canvas.height - player.r) player.y = canvas.height - player.r;
// Fire rate evaluation loops
if(continuousFiring && Date.now() - lastFireTime > fireDelay) {
lasers.push({x: player.x, y: player.y - player.r, speed: 9});
lastFireTime = Date.now();
}
// Update standard objects layout arrays
stars.forEach(s => {
s.y += s.s;
if(s.y > canvas.height) s.y = 0;
});
lasers.forEach((l, index) => {
l.y -= l.speed;
if(l.y < 0) lasers.splice(index, 1);
});
// Dynamic difficulty progression calculations
let targetScore = currentLevel * 150;
if(_secureState.getScore() >= targetScore) {
currentLevel++;
updateHUD();
}
if(Math.random() < 0.02 + (currentLevel * 0.005)) {
spawnAsteroid();
}
for (let i = asteroids.length - 1; i >= 0; i--) {
let a = asteroids[i];
a.y += a.speed;
// Handle off screen memory clearance
if(a.y > canvas.height + a.r) {
asteroids.splice(i, 1);
continue;
}
// Object overlapping calculations (Laser to Asteroid)
for(let j = lasers.length - 1; j >= 0; j--) {
let l = lasers[j];
if(Math.hypot(a.x - l.x, a.y - l.y) < a.r) {
lasers.splice(j, 1);
a.hp--;
if(a.hp <= 0) {
if(a.type === 'Explosive') {
createExplosion(a.x, a.y, 120);
}
_secureState.setScore(_secureState.getScore() + (a.maxHp * 10));
scrap += Math.random() > 0.4 ? 1 : 0; // Scrap drop calculation mechanics
asteroids.splice(i, 1);
updateHUD();
break;
}
}
}
// Ship to Hazard Collision calculation loops
if(asteroids[i] && Math.hypot(a.x - player.x, a.y - player.y) < a.r + player.r) {
let dmg = a.type === 'Armored' ? 35 : 15;
player.hp -= dmg;
lastDamageTime = Date.now();
asteroids.splice(i, 1);
updateHUD();
if(player.hp <= 0) {
alert(GAME OVER\nFinal Score: ${_secureState.getScore()});
// State memory recovery back to initial defaults
_secureState.setScore(0);
scrap = 0;
currentLevel = 1;
player.maxHp = 100;
player.hp = 100;
asteroids = [];
lasers = [];
updateHUD();
}
}
}
}
// Visual rendering loop contexts
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw structural elements (Stars Background)
ctx.fillStyle = 'rgba(255,255,255,0.7)';
stars.forEach(s => {
ctx.fillRect(s.x, s.y, s.s, s.s);
});
// Draw combat assets (Lasers)
ctx.fillStyle = '#00f2fe';
lasers.forEach(l => {
ctx.fillRect(l.x - 2, l.y, 4, 12);
});
// Draw structural hazard assets (Asteroids)
asteroids.forEach(a => {
ctx.fillStyle = a.color;
ctx.beginPath();
ctx.arc(a.x, a.y, a.r, 0, Math.PI*2);
ctx.fill();
// Render health indicators on heavily armored rocks
if(a.type === 'Armored' && a.hp < a.maxHp) {
ctx.fillStyle = '#ff0000';
ctx.fillRect(a.x - 15, a.y - a.r - 8, 30, 4);
ctx.fillStyle = '#00ff00';
ctx.fillRect(a.x - 15, a.y - a.r - 8, (a.hp / a.maxHp) * 30, 4);
}
});
// Render Player Avatar Model
ctx.fillStyle = '#ffffff';
ctx.shadowColor = '#4facfe';
ctx.shadowBlur = 10;
ctx.beginPath();
ctx.moveTo(player.x, player.y - player.r);
ctx.lineTo(player.x - player.r, player.y + player.r);
ctx.lineTo(player.x + player.r, player.y + player.r);
ctx.closePath();
ctx.fill();
ctx.shadowBlur = 0; // Clear blur constraints filter for optimization performance
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
// Begin main system loops execution context
updateHUD();
loop();
18,052 chars · codepastes.com