Neon Rush
by CyberFalcon70781 lines21.9 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
<title>Neon Rush</title>
<style>
*{box-sizing:border-box}
html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#08101f;font-family:Arial,sans-serif}
canvas{display:block;width:100%;height:100%;touch-action:none}
button{
border:0;border-radius:14px;padding:12px 20px;font-size:17px;font-weight:700;
color:white;background:#19a7ff;box-shadow:0 5px 0 #0875b9;cursor:pointer
}
button:active{transform:translateY(3px);box-shadow:0 2px 0 #0875b9}
#ui{position:fixed;inset:0;pointer-events:none;color:white}
#topbar{
position:absolute;top:12px;left:12px;right:12px;display:flex;
justify-content:space-between;align-items:flex-start;z-index:5
}
.stat{
background:rgba(0,0,0,.35);backdrop-filter:blur(5px);border:1px solid rgba(255,255,255,.18);
border-radius:13px;padding:7px 11px;margin-bottom:5px;text-shadow:0 2px 3px #000
}
#leftStats{display:flex;gap:7px;flex-wrap:wrap}
#rightControls{display:flex;gap:7px;pointer-events:auto}
.smallBtn{padding:9px 12px;font-size:16px}
#overlay{
position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
background:rgba(3,7,20,.65);backdrop-filter:blur(5px);pointer-events:auto;z-index:10
}
.panel{
width:min(92vw,500px);padding:30px;border-radius:25px;text-align:center;
background:linear-gradient(145deg,rgba(20,35,68,.96),rgba(7,14,32,.97));
border:1px solid rgba(255,255,255,.2);box-shadow:0 20px 70px rgba(0,0,0,.5)
}
h1{font-size:48px;margin:0 0 5px;letter-spacing:3px}
.subtitle{color:#8ddcff;margin:0 0 25px;font-size:16px}
.big{font-size:22px;margin:12px}
.hidden{display:none!important}
.controls{
margin:20px 0;color:#d8e8ff;line-height:1.7;font-size:14px
}
#powerText{
position:absolute;top:105px;left:50%;transform:translateX(-50%);
font-weight:bold;text-shadow:0 2px 4px #000;white-space:nowrap
}
#touchHint{
position:absolute;bottom:12px;left:50%;transform:translateX(-50%);
color:rgba(255,255,255,.6);font-size:12px
}
</style>
</head>
<body>
<canvas id="game"></canvas>
<div id="ui">
<div id="topbar">
<div id="leftStats">
<div class="stat">⭐ <span id="score">0</span></div>
<div class="stat">🪙 <span id="coins">0</span></div>
<div class="stat">🏆 <span id="high">0</span></div>
</div>
<div id="rightControls">
<button class="smallBtn" id="pauseBtn">Ⅱ</button>
<button class="smallBtn" id="muteBtn">🔊</button>
</div>
</div>
<div id="powerText"></div>
<div id="touchHint">Swipe ← → to move • Swipe ↑ to jump • Swipe ↓ to slide</div>
<div id="overlay">
<div class="panel" id="menuPanel">
<h1>NEON RUSH</h1>
<p class="subtitle">Run. Dodge. Collect. Survive.</p>
<div class="big">🏆 Best: <span id="menuHigh">0</span></div>
<button id="startBtn">START RUN</button>
<div class="controls">
← → / A D Move<br>
↑ / W / SPACE Jump<br>
↓ / S Slide<br>
P Pause
</div>
</div>
<div class="panel hidden" id="pausePanel">
<h1>PAUSED</h1>
<p class="subtitle">Catch your breath.</p>
<button id="resumeBtn">RESUME</button>
</div>
<div class="panel hidden" id="gameOverPanel">
<h1>RUN OVER</h1>
<p class="subtitle">The city keeps moving...</p>
<div class="big">Score: <span id="finalScore">0</span></div>
<div class="big">Coins: <span id="finalCoins">0</span></div>
<div class="big">Best: <span id="finalHigh">0</span></div>
<button id="restartBtn">RUN AGAIN</button>
</div>
</div>
</div>
<script>
"use strict";
const canvas=document.getElementById("game");
const ctx=canvas.getContext("2d");
let W=innerWidth,H=innerHeight,DPR=Math.min(devicePixelRatio||1,2);
function resize(){
W=innerWidth; H=innerHeight; DPR=Math.min(devicePixelRatio||1,2);
canvas.width=W*DPR; canvas.height=H*DPR;
canvas.style.width=W+"px"; canvas.style.height=H+"px";
ctx.setTransform(DPR,0,0,DPR,0,0);
}
addEventListener("resize",resize);
resize();
const scoreEl=document.getElementById("score");
const coinsEl=document.getElementById("coins");
const highEl=document.getElementById("high");
const menuHigh=document.getElementById("menuHigh");
const powerText=document.getElementById("powerText");
let highScore=Number(localStorage.getItem("neonRushHigh")||0);
highEl.textContent=highScore;
menuHigh.textContent=highScore;
let state="menu";
let score=0,coins=0,distance=0;
let speed=7;
let lane=1,targetLane=1;
let playerY=0,vy=0;
let slideTimer=0;
let spawnTimer=0;
let sceneryTimer=0;
let worldTime=0;
let shake=0;
let lastTime=0;
let muted=false;
let magnetTimer=0,shieldTimer=0,boostTimer=0;
let objects=[];
let particles=[];
let buildings=[];
let stars=[];
for(let i=0;i<70;i++){
stars.push({
x:Math.random(),y:Math.random()*.65,
r:Math.random()*1.8+.3,a:Math.random()*.7+.2
});
}
function roadY(){
return H*.78;
}
function roadTop(){
return H*.30;
}
function laneX(l,z){
const t=Math.max(0,Math.min(1,z));
const center=W/2;
const roadWidthTop=Math.min(W*.22,190);
const roadWidthBottom=Math.min(W*.92,700);
const width=roadWidthTop+(roadWidthBottom-roadWidthTop)*t;
return center+(l-1)*(width/3);
}
function depthY(z){
return roadTop()+(roadY()-roadTop())*z;
}
function resetBuildings(){
buildings=[];
for(let i=0;i<24;i++){
const side=i%2===0?-1:1;
buildings.push({
side,
z:Math.random(),
w:35+Math.random()*75,
h:80+Math.random()*190,
hue:Math.random()*360
});
}
}
resetBuildings();
function resetGame(){
state="playing";
score=0;coins=0;distance=0;
speed=7;
lane=1;targetLane=1;
playerY=0;vy=0;slideTimer=0;
spawnTimer=.4;
objects=[];
particles=[];
magnetTimer=shieldTimer=boostTimer=0;
shake=0;
worldTime=0;
resetBuildings();
overlay("none");
lastTime=performance.now();
beep(220,.06,"triangle",.04);
}
function overlay(type){
document.getElementById("overlay").classList.toggle("hidden",type==="none");
document.getElementById("menuPanel").classList.toggle("hidden",type!=="menu");
document.getElementById("pausePanel").classList.toggle("hidden",type!=="pause");
document.getElementById("gameOverPanel").classList.toggle("hidden",type!=="over");
}
function endGame(){
if(state!=="playing")return;
state="over";
const final=Math.floor(score);
if(final>highScore){
highScore=final;
localStorage.setItem("neonRushHigh",highScore);
}
document.getElementById("finalScore").textContent=final;
document.getElementById("finalCoins").textContent=coins;
document.getElementById("finalHigh").textContent=highScore;
highEl.textContent=highScore;
beep(100,.35,"sawtooth",.07);
overlay("over");
}
function pauseGame(){
if(state==="playing"){
state="paused";overlay("pause");
}else if(state==="paused"){
state="playing";overlay("none");lastTime=performance.now();
}
}
document.getElementById("startBtn").onclick=()=>resetGame();
document.getElementById("restartBtn").onclick=()=>resetGame();
document.getElementById("resumeBtn").onclick=()=>pauseGame();
document.getElementById("pauseBtn").onclick=()=>pauseGame();
document.getElementById("muteBtn").onclick=()=>{
muted=!muted;
document.getElementById("muteBtn").textContent=muted?"🔇":"🔊";
};
function beep(freq,dur,type="sine",vol=.05){
if(muted)return;
try{
const AC=window.AudioContext||window.webkitAudioContext;
if(!window.audioCtx)window.audioCtx=new AC();
const a=window.audioCtx;
const o=a.createOscillator(),g=a.createGain();
o.type=type;o.frequency.value=freq;
g.gain.setValueAtTime(vol,a.currentTime);
g.gain.exponentialRampToValueAtTime(.001,a.currentTime+dur);
o.connect(g);g.connect(a.destination);
o.start();o.stop(a.currentTime+dur);
}catch(e){}
}
function moveLeft(){if(state!=="playing")return;targetLane=Math.max(0,targetLane-1);beep(300,.045,"square",.025)}
function moveRight(){if(state!=="playing")return;targetLane=Math.min(2,targetLane+1);beep(380,.045,"square",.025)}
function jump(){
if(state!=="playing")return;
if(playerY===0 && slideTimer<=0){
vy=15.5;beep(520,.1,"triangle",.045);
}
}
function slide(){
if(state!=="playing")return;
if(playerY===0){
slideTimer=.65;beep(180,.08,"triangle",.035);
}
}
addEventListener("keydown",e=>{
if(["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"," "].includes(e.key))e.preventDefault();
if(e.key==="ArrowLeft"||e.key.toLowerCase()==="a")moveLeft();
if(e.key==="ArrowRight"||e.key.toLowerCase()==="d")moveRight();
if(e.key==="ArrowUp"||e.key.toLowerCase()==="w"||e.key===" ")jump();
if(e.key==="ArrowDown"||e.key.toLowerCase()==="s")slide();
if(e.key.toLowerCase()==="p")pauseGame();
});
let touchStartX=0,touchStartY=0;
canvas.addEventListener("touchstart",e=>{
const t=e.changedTouches[0];
touchStartX=t.clientX;touchStartY=t.clientY;
},{passive:true});
canvas.addEventListener("touchend",e=>{
const t=e.changedTouches[0];
const dx=t.clientX-touchStartX,dy=t.clientY-touchStartY;
if(Math.max(Math.abs(dx),Math.abs(dy))<25)return;
if(Math.abs(dx)>Math.abs(dy)){
dx>0?moveRight():moveLeft();
}else{
dy<0?jump():slide();
}
},{passive:true});
function spawn(type,l,z=-.02){
objects.push({type,lane:l,z,phase:Math.random()*Math.PI*2});
}
function spawnWave(){
const difficulty=Math.min(1,distance/1500);
const r=Math.random();
if(r<.46){
const blocked=Math.floor(Math.random()*3);
spawn(Math.random()<.55?"barrier":"crate",blocked);
if(Math.random()<.8){
const other=[0,1,2].filter(x=>x!==blocked);
const good=other[Math.floor(Math.random()*other.length)];
for(let i=0;i<4;i++)spawn("coin",good,-.12-i*.09);
}
}else if(r<.70){
const l=Math.floor(Math.random()*3);
for(let i=0;i<6;i++)spawn("coin",l,-.02-i*.075);
}else if(r<.84){
const l=Math.floor(Math.random()*3);
spawn("highbar",l);
for(let i=0;i<4;i++)spawn("coin",(l+1)%3,-.13-i*.09);
}else if(r<.94){
const l=Math.floor(Math.random()*3);
spawn("power",l);
}else{
const safe=Math.floor(Math.random()*3);
for(let l=0;l<3;l++){
if(l!==safe)spawn("crate",l);
}
for(let i=0;i<5;i++)spawn("coin",safe,-.1-i*.075);
}
if(difficulty>.55 && Math.random()<.25){
const l=Math.floor(Math.random()*3);
spawn("crate",l,-.45);
}
}
function update(dt){
worldTime+=dt;
distance+=speed*dt;
speed=7+Math.min(8,distance/500);
if(boostTimer>0)speed+=5;
score+=speed*dt*2;
targetLane=Math.max(0,Math.min(2,targetLane));
lane+=(targetLane-lane)*Math.min(1,dt*12);
if(playerY>0 || vy>0){
playerY+=vy*dt;
vy-=34*dt;
if(playerY<=0){playerY=0;vy=0}
}
if(slideTimer>0)slideTimer-=dt;
if(magnetTimer>0)magnetTimer-=dt;
if(shieldTimer>0)shieldTimer-=dt;
if(boostTimer>0)boostTimer-=dt;
spawnTimer-=dt;
const interval=Math.max(.36,.82-distance/4000);
if(spawnTimer<=0){
spawnWave();
spawnTimer=interval*(.8+Math.random()*.35);
}
for(const o of objects)o.z+=speed*dt*.075;
for(const b of buildings)b.z+=speed*dt*.012;
for(const b of buildings)if(b.z>1.15)b.z=-.1;
sceneryTimer+=dt;
if(sceneryTimer>.3){
sceneryTimer=0;
if(Math.random()<.4){
const side=Math.random()<.5?-1:1;
buildings.push({
side,z:-.05,w:35+Math.random()*70,h:80+Math.random()*190,
hue:Math.random()*360
});
}
}
handleObjects();
updateParticles(dt);
if(shake>0)shake=Math.max(0,shake-dt*20);
scoreEl.textContent=Math.floor(score);
coinsEl.textContent=coins;
highEl.textContent=Math.max(highScore,Math.floor(score));
let p=[];
if(magnetTimer>0)p.push("🧲 MAGNET "+magnetTimer.toFixed(1));
if(shieldTimer>0)p.push("🛡️ SHIELD "+shieldTimer.toFixed(1));
if(boostTimer>0)p.push("⚡ BOOST "+boostTimer.toFixed(1));
powerText.textContent=p.join(" ");
}
function handleObjects(){
const px=laneX(lane,1);
for(let i=objects.length-1;i>=0;i--){
const o=objects[i];
if(o.z>1.08){objects.splice(i,1);continue}
const x=laneX(o.lane,o.z);
const y=depthY(o.z);
const near=Math.abs(o.z-1)<.10;
const laneHit=Math.abs(x-px)<Math.max(32,W*.035);
if(o.type==="coin"){
if(
(near&&laneHit&&Math.abs(playerY)<55) ||
(magnetTimer>0&&o.z>.65&&Math.abs(x-px)<130)
){
collectCoin(o);
objects.splice(i,1);
}
continue;
}
if(o.type==="power"){
if(near&&laneHit&&Math.abs(playerY)<65){
const types=["magnet","shield","boost"];
const t=types[Math.floor(Math.random()*types.length)];
if(t==="magnet")magnetTimer=8;
if(t==="shield")shieldTimer=9;
if(t==="boost")boostTimer=6;
beep(700,.15,"sine",.06);
burst(x,y-35,18,1.5);
objects.splice(i,1);
}
continue;
}
if(near&&laneHit){
let safe=false;
if(o.type==="barrier"||o.type==="crate")safe=playerY>65;
if(o.type==="highbar")safe=slideTimer>0;
if(!safe){
if(shieldTimer>0){
shieldTimer=0;
burst(x,y-40,25,2);
shake=8;
beep(150,.16,"sawtooth",.05);
objects.splice(i,1);
}else{
shake=14;
burst(x,y-35,35,2.5);
endGame();
return;
}
}
}
}
}
function collectCoin(o){
coins++;
score+=50;
beep(800+Math.random()*250,.07,"sine",.045);
const x=laneX(o.lane,Math.min(1,o.z));
const y=depthY(Math.min(1,o.z));
burst(x,y-30,12,1.2);
}
function burst(x,y,n,power){
for(let i=0;i<n;i++){
const a=Math.random()*Math.PI*2;
const s=(30+Math.random()*100)*power;
particles.push({
x,y,
vx:Math.cos(a)*s,vy:Math.sin(a)*s,
life:.35+Math.random()*.5,
max:.8,
size:2+Math.random()*5
});
}
}
function updateParticles(dt){
for(let i=particles.length-1;i>=0;i--){
const p=particles[i];
p.x+=p.vx*dt;p.y+=p.vy*dt;
p.vy+=90*dt;p.vx*=.97;
p.life-=dt;
if(p.life<=0)particles.splice(i,1);
}
}
function skyGradient(){
const cycle=(worldTime*.018)%1;
const night=.5+.5*Math.sin(cycle*Math.PI*2-Math.PI/2);
const g=ctx.createLinearGradient(0,0,0,H);
const r1=Math.floor(10+night*20);
const g1=Math.floor(20+night*18);
const b1=Math.floor(55+night*65);
const r2=Math.floor(50+night*30);
const g2=Math.floor(100+night*30);
const b2=Math.floor(160+night*30);
g.addColorStop(0,`rgb(${r1},${g1},${b1})`);
g.addColorStop(1,`rgb(${r2},${g2},${b2})`);
return g;
}
function draw(){
ctx.save();
if(shake>0){
ctx.translate((Math.random()-.5)*shake,(Math.random()-.5)*shake);
}
ctx.fillStyle=skyGradient();
ctx.fillRect(0,0,W,H);
drawSky();
drawBuildings();
drawRoad();
drawObjects();
drawPlayer();
drawParticles();
ctx.restore();
}
function drawSky(){
const cycle=(worldTime*.018)%1;
const sunX=W*(.15+.7*cycle);
const sunY=H*.16+Math.sin(cycle*Math.PI)*H*.07;
ctx.globalAlpha=.75;
ctx.fillStyle="#fff4ad";
ctx.beginPath();ctx.arc(sunX,sunY,32,0,Math.PI*2);ctx.fill();
ctx.globalAlpha=1;
for(const s of stars){
ctx.globalAlpha=s.a*(.3+.7*Math.abs(Math.sin(worldTime*.2)));
ctx.fillStyle="white";
ctx.beginPath();ctx.arc(s.x*W,s.y*H,s.r,0,Math.PI*2);ctx.fill();
}
ctx.globalAlpha=1;
ctx.fillStyle="rgba(255,255,255,.08)";
for(let i=0;i<4;i++){
const x=((i*270+worldTime*5)%(W+300))-150;
ctx.beginPath();
ctx.ellipse(x,H*.22+i*22,90,18,0,0,Math.PI*2);
ctx.fill();
}
}
function drawBuildings(){
const horizon=roadTop();
for(const b of buildings){
const z=Math.max(.05,Math.min(1,b.z));
const scale=.35+z*1.15;
const x=W/2+b.side*(W*.25+z*W*.24);
const w=b.w*scale;
const h=b.h*scale;
const y=horizon-z*25;
ctx.fillStyle=`hsl(${b.hue},28%,${15+z*14}%)`;
ctx.fillRect(x-w/2,y-h,w,h);
const rows=Math.max(2,Math.floor(h/25));
const cols=Math.max(2,Math.floor(w/20));
for(let r=0;r<rows;r++){
for(let c=0;c<cols;c++){
if((r+c+Math.floor(worldTime*2))%3!==0){
ctx.fillStyle=(Math.sin(worldTime*3+r+c)>0)
?"rgba(255,225,120,.65)":"rgba(80,190,255,.35)";
ctx.fillRect(
x-w/2+7+c*(w-12)/cols,
y-h+9+r*(h-15)/rows,
Math.max(3,w/cols-7),Math.max(4,h/rows-9)
);
}
}
}
}
}
function drawRoad(){
const top=roadTop(),bottom=roadY();
ctx.fillStyle="#151a29";
ctx.beginPath();
ctx.moveTo(W*.5-W*.11,top);
ctx.lineTo(W*.5+W*.11,top);
ctx.lineTo(W*.5+W*.46,bottom+H*.2);
ctx.lineTo(W*.5-W*.46,bottom+H*.2);
ctx.closePath();ctx.fill();
ctx.fillStyle="#292d3c";
ctx.beginPath();
ctx.moveTo(0,top);ctx.lineTo(W,top);
ctx.lineTo(W,bottom+H*.2);ctx.lineTo(0,bottom+H*.2);
ctx.closePath();ctx.fill();
for(let l=1;l<3;l++){
for(let i=0;i<12;i++){
let z=((i/12)+(worldTime*speed*.018))%1;
const y=depthY(z);
const x=laneX(l,z);
const w=2+z*5;
ctx.fillStyle="rgba(120,210,255,.75)";
ctx.fillRect(x-w/2,y,w,Math.max(3,z*14));
}
}
for(let i=0;i<16;i++){
let z=((i/16)+(worldTime*speed*.014))%1;
const y=depthY(z);
const x1=laneX(0,z),x2=laneX(2,z);
ctx.fillStyle="rgba(255,255,255,.12)";
ctx.fillRect(x1-2,y,4,Math.max(2,z*8));
ctx.fillRect(x2-2,y,4,Math.max(2,z*8));
}
}
function drawObjects(){
const sorted=[...objects].sort((a,b)=>a.z-b.z);
for(const o of sorted){
const z=Math.max(.02,Math.min(1,o.z));
const x=laneX(o.lane,z);
const y=depthY(z);
const s=.35+z*1.05;
if(o.type==="coin"){
const bob=Math.sin(worldTime*8+o.phase)*4*s;
ctx.save();
ctx.translate(x,y-35*s+bob);
ctx.rotate(worldTime*5+o.phase);
ctx.fillStyle="#ffd43b";
ctx.beginPath();ctx.ellipse(0,0,12*s,12*s,0,0,Math.PI*2);ctx.fill();
ctx.fillStyle="#fff2a3";
ctx.beginPath();ctx.ellipse(-3*s,-3*s,4*s,7*s,0,0,Math.PI*2);ctx.fill();
ctx.restore();
}
if(o.type==="crate"){
const w=54*s,h=54*s;
ctx.fillStyle="#b85d31";
ctx.fillRect(x-w/2,y-h,w,h);
ctx.strokeStyle="#f0a15a";ctx.lineWidth=4*s;
ctx.strokeRect(x-w/2,y-h,w,h);
ctx.beginPath();ctx.moveTo(x-w/2,y-h);ctx.lineTo(x+w/2,y);ctx.moveTo(x+w/2,y-h);ctx.lineTo(x-w/2,y);ctx.stroke();
}
if(o.type==="barrier"){
const w=68*s,h=43*s;
ctx.fillStyle="#ed4c55";
ctx.fillRect(x-w/2,y-h,w,h);
ctx.fillStyle="#ffe05a";
for(let k=-1;k<=1;k++){
ctx.save();ctx.translate(x+k*23*s,y-h/2);ctx.rotate(-.6);
ctx.fillRect(-5*s,-18*s,10*s,36*s);ctx.restore();
}
}
if(o.type==="highbar"){
const w=74*s;
ctx.strokeStyle="#ef4c75";ctx.lineWidth=10*s;
ctx.beginPath();
ctx.moveTo(x-w/2,y);ctx.lineTo(x-w/2,y-70*s);
ctx.moveTo(x+w/2,y);ctx.lineTo(x+w/2,y-70*s);
ctx.stroke();
ctx.strokeStyle="#ffcb45";ctx.lineWidth=12*s;
ctx.beginPath();ctx.moveTo(x-w/2,y-62*s);ctx.lineTo(x+w/2,y-62*s);ctx.stroke();
}
if(o.type==="power"){
const bob=Math.sin(worldTime*6+o.phase)*5;
ctx.save();ctx.translate(x,y-50*s+bob);
ctx.fillStyle="#a86cff";
ctx.shadowBlur=20;ctx.shadowColor="#a86cff";
ctx.beginPath();ctx.arc(0,0,18*s,0,Math.PI*2);ctx.fill();
ctx.shadowBlur=0;
ctx.fillStyle="white";
ctx.font=`bold ${20*s}px Arial`;
ctx.textAlign="center";ctx.textBaseline="middle";
ctx.fillText("★",0,1);
ctx.restore();
}
}
}
function drawPlayer(){
const x=laneX(lane,1);
const base=roadY()-8;
const jumpY=playerY;
const sliding=slideTimer>0;
ctx.save();
ctx.translate(x,base-jumpY);
const shadowSize=Math.max(8,35-playerY*.18);
ctx.globalAlpha=.25;
ctx.fillStyle="#000";
ctx.beginPath();ctx.ellipse(0,8,shadowSize,8,0,0,Math.PI*2);ctx.fill();
ctx.globalAlpha=1;
if(shieldTimer>0){
ctx.strokeStyle="rgba(80,220,255,.8)";
ctx.lineWidth=4;
ctx.shadowBlur=18;ctx.shadowColor="#38d9ff";
ctx.beginPath();ctx.arc(0,-45,48,0,Math.PI*2);ctx.stroke();
ctx.shadowBlur=0;
}
if(sliding){
ctx.rotate(-.08);
ctx.fillStyle="#28d7ff";
roundRect(ctx,-30,-32,60,30,12);ctx.fill();
ctx.fillStyle="#ffcc67";
ctx.beginPath();ctx.arc(28,-29,12,0,Math.PI*2);ctx.fill();
ctx.fillStyle="#18233f";
ctx.fillRect(-24,-3,16,7);ctx.fillRect(8,-3,16,7);
}else{
ctx.fillStyle="#28d7ff";
roundRect(ctx,-19,-63,38,45,12);ctx.fill();
ctx.fillStyle="#ffcc67";
ctx.beginPath();ctx.arc(0,-78,18,0,Math.PI*2);ctx.fill();
ctx.fillStyle="#202943";
ctx.fillRect(-15,-85,30,8);
ctx.fillRect(-13,-76,7,5);ctx.fillRect(6,-76,7,5);
ctx.fillStyle="#ff5c91";
ctx.fillRect(-28,-55,10,29);
ctx.fillRect(18,-55,10,29);
ctx.fillStyle="#8b5cff";
ctx.fillRect(-17,-18,12,25);
ctx.fillRect(5,-18,12,25);
}
ctx.restore();
}
function roundRect(c,x,y,w,h,r){
c.beginPath();
c.moveTo(x+r,y);
c.arcTo(x+w,y,x+w,y+h,r);
c.arcTo(x+w,y+h,x,y+h,r);
c.arcTo(x,y+h,x,y,r);
c.arcTo(x,y,x+w,y,r);
c.closePath();
}
function drawParticles(){
for(const p of particles){
ctx.globalAlpha=Math.max(0,p.life/p.max);
ctx.fillStyle="#ffd84a";
ctx.beginPath();ctx.arc(p.x,p.y,p.size,0,Math.PI*2);ctx.fill();
}
ctx.globalAlpha=1;
}
function loop(t){
requestAnimationFrame(loop);
const dt=Math.min(.035,(t-lastTime)/1000||0);
lastTime=t;
if(state==="playing")update(dt);
draw();
}
requestAnimationFrame(loop);
overlay("menu");
</script>
</body>
</html>Game Source: Neon Rush
Creator: CyberFalcon70
Libraries: none
Complexity: complex (781 lines, 21.9 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: neon-rush-cyberfalcon70" to link back to the original. Then publish at arcadelab.ai/publish.