🎮ArcadeLab

蓝白能量飞碟漫游

by WildWave23
173 lines4.5 KB
▶ Play
<!DOCTYPE html>
 <html lang="zh-CN">
 <head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
 <title>蓝白能量飞碟漫游</title>
 <style>
 *{margin:0;padding:0;box-sizing:border-box}
 body{overflow:hidden;background:#000;touch-action:none}
 canvas{display:block;width:100vw;height:100vh}
 </style>
 </head>
 <body>
 <canvas id="gameCanvas"></canvas>
 <script>
 const canvas = document.getElementById('gameCanvas');
 const ctx = canvas.getContext('2d');
 function resize(){
   canvas.width = window.innerWidth;
   canvas.height = window.innerHeight;
 }
 resize();
 window.addEventListener('resize',resize);
 //飞碟数据
 let ship = {x:canvas.width/2,y:canvas.height/2,vx:0,vy:0,r:28};
 let targetX = ship.x, targetY = ship.y;
 //场景
 let sceneId = 0;
 const sceneList = [
   {name:"宇宙星空",bg:"#040614",bg2:"#0b1030"},
   {name:"飞碟能量夹层",bg:"#080c22",bg2:"#152048"},
   {name:"南极冰墙溶洞",bg:"#051018",bg2:"#0c2538"}
 ];
 //传送环
 let portal = {x:0,y:0,r:90,pulse:0};
 //星星粒子
 let stars = [];
 let particles = [];
 //切换特效
 let transition = 0;
 //生成星空
 function buildStars(){
   stars = [];
   for(let i=0;i<400;i++){
     stars.push({
       x:Math.random()*canvas.width,
       y:Math.random()*canvas.height,
       size:Math.random()*1.6+0.2,
       twinkle:Math.random()*Math.PI*2
     })
   }
 }
 buildStars();
 //触屏监听
 canvas.addEventListener('touchmove',e=>{
   e.preventDefault();
   const t = e.touches[0];
   targetX = t.clientX;
   targetY = t.clientY;
 })
 canvas.addEventListener('touchstart',e=>{
   const t = e.touches[0];
   targetX = t.clientX;
   targetY = t.clientY;
 })
 //切换场景
 function changeScene(){
   sceneId = (sceneId+1) % sceneList.length;
   transition = 1;
   buildStars();
   resetPortal();
 }
 function resetPortal(){
   portal.x = Math.random()*(canvas.width*0.5)+canvas.width*0.25;
   portal.y = Math.random()*(canvas.height*0.5)+canvas.height*0.25;
 }
 resetPortal();
 //绘制葫芦形状飞碟
 function drawShip(){
   ctx.save();
   ctx.translate(ship.x,ship.y);
   //外层蓝白光晕
   const gradOuter = ctx.createRadialGradient(0,0,10,0,0,45);
   gradOuter.addColorStop(0,"rgba(180,220,255,0.65)");
   gradOuter.addColorStop(1,"rgba(80,150,255,0)");
   ctx.fillStyle = gradOuter;
   ctx.beginPath();
   ctx.arc(0,0,45,0,Math.PI*2);
   ctx.fill();
   //葫芦本体
   ctx.fillStyle="#e8f4ff";
   ctx.beginPath();
   ctx.ellipse(0,-14,14,16,0,0,Math.PI*2);
   ctx.fill();
   ctx.beginPath();
   ctx.ellipse(0,12,22,18,0,0,Math.PI*2);
   ctx.fill();
   //6个圆孔
   ctx.fillStyle="#081022";
   const holeR = 4;
   for(let i=0;i<6;i++){
     const ang = Math.PI*2/6*i;
     let hx = Math.cos(ang)*16;
     let hy = Math.sin(ang)*12+12;
     ctx.beginPath();
     ctx.arc(hx,hy,holeR,0,Math.PI*2);
     ctx.fill();
   }
   ctx.restore();
 }
 //绘制传送光圈
 function drawPortal(){
   portal.pulse +=0.035;
   const pulseR = portal.r + Math.sin(portal.pulse)*14;
   ctx.save();
   ctx.translate(portal.x,portal.y);
   //多层光环
   for(let l=3;l>0;l--){
     ctx.strokeStyle=`rgba(140,200,255,${0.25*l})`;
     ctx.lineWidth=3+l;
     ctx.beginPath();
     ctx.arc(0,0,pulseR - l*12,0,Math.PI*2);
     ctx.stroke();
   }
   ctx.restore();
 }
 //绘制背景
 function drawBackground(){
   const sc = sceneList[sceneId];
   const grad = ctx.createLinearGradient(0,0,0,canvas.height);
   grad.addColorStop(0,sc.bg);
   grad.addColorStop(1,sc.bg2);
   ctx.fillStyle = grad;
   ctx.fillRect(0,0,canvas.width,canvas.height);
   //绘制星星闪烁
   stars.forEach(s=>{
     s.twinkle +=0.02;
     const alpha = 0.35 + Math.sin(s.twinkle)*0.45;
     ctx.fillStyle=`rgba(240,245,255,${alpha})`;
     ctx.beginPath();
     ctx.arc(s.x,s.y,s.size,0,Math.PI*2);
     ctx.fill();
   })
 }
 //场景切换遮罩
 function drawTransition(){
   if(transition <=0) return;
   ctx.fillStyle=`rgba(220,240,255,${transition*0.7})`;
   ctx.fillRect(0,0,canvas.width,canvas.height);
   transition -=0.025;
 }
 //循环动画
 function loop(){
   requestAnimationFrame(loop);
   //飞碟平滑移动
   ship.vx = (targetX - ship.x)*0.06;
   ship.vy = (targetY - ship.y)*0.06;
   ship.x += ship.vx;
   ship.y += ship.vy;
   //检测碰撞传送门
   const dist = Math.hypot(ship.x-portal.x, ship.y-portal.y);
   if(dist < portal.r && transition <=0){
     changeScene();
   }
   drawBackground();
   drawPortal();
   drawShip();
   drawTransition();
 }
 loop();
 </script>
 </body>
 </html>

Game Source: 蓝白能量飞碟漫游

Creator: WildWave23

Libraries: none

Complexity: moderate (173 lines, 4.5 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: game-wildwave23" to link back to the original. Then publish at arcadelab.ai/publish.