JustPaste
HomeCategoriesAboutDonateContactTerms of UsePrivacy Policy
JustPaste

Free online notepad — write and share instantly

Navigate

  • Home
  • Timeline
  • Categories

Info

  • About
  • Donate
  • Contact

Legal

  • Terms of Use
  • Privacy Policy

© 2026 JustPaste.app. All rights reserved.

Made with ♥ by JustPaste

Code | JustPaste.app
11 days ago4 views
💻Technology

Code

<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>🚀 Rocket Factory</title>
<style>
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#050914;color:#fff;font-family:Tahoma,Arial,sans-serif}
body{touch-action:none}
#game{position:fixed;inset:0}
canvas{display:block}
.panel{
 position:fixed;z-index:10;left:8px;right:8px;top:8px;
 background:rgba(5,13,28,.84);border:1px solid #29466d;
 border-radius:16px;padding:9px;backdrop-filter:blur(8px)
}
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:6px}
.stat{background:#0d1a31;border-radius:11px;padding:5px;text-align:center;font-size:10px}
.stat b{display:block;font-size:14px;margin-top:2px;color:#b9eaff}
#height{color:#70e7ff;font-size:18px}
#bottom{
 position:fixed;z-index:11;bottom:8px;left:8px;right:8px;
 display:flex;gap:6px;justify-content:center
}
button{
 background:#172846;color:white;border:1px solid #31547f;border-radius:13px;
 padding:11px 12px;font-weight:bold;font-size:13px
}
button:active{transform:scale(.96)}
button.primary{background:#087fbd;border-color:#35c7ff}
button.danger{background:#8d2634}
#screen{
 position:fixed;inset:0;z-index:20;display:none;
 background:rgba(2,7,17,.91);padding:65px 12px 70px;overflow:auto
}
#screen.show{display:block}
.box{
 max-width:650px;margin:auto;background:#0a1529;border:1px solid #29466d;
 border-radius:18px;padding:15px
}
h2{margin:4px 0 14px;font-size:20px}
h3{font-size:15px;margin:15px 0 8px}
.row{
 display:flex;align-items:center;justify-content:space-between;
 gap:8px;background:#101f37;border-radius:12px;padding:10px;margin:6px 0
}
.row small{color:#9bb0cc;display:block;margin-top:3px}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:7px}
.card{background:#0f1e35;border-radius:13px;padding:10px}
.card strong{display:block;margin-bottom:5px}
.price{color:#ffd66e;font-size:12px}
.close{width:100%;margin-top:12px}
.bar{height:8px;background:#17243a;border-radius:20px;overflow:hidden;margin-top:6px}
.fill{height:100%;background:#31bce9;width:0%}
#message{
 position:fixed;z-index:30;top:115px;left:50%;transform:translateX(-50%);
 background:#0a162bde;border:1px solid #3c628d;padding:9px 13px;
 border-radius:12px;display:none;white-space:nowrap
}
#message.show{display:block}
#flightControls{
 position:fixed;z-index:12;bottom:75px;left:12px;right:12px;
 display:none;justify-content:space-between;pointer-events:none
}
.ctrl{
 pointer-events:auto;width:72px;height:72px;border-radius:50%;
 background:#10243dd9;border:2px solid #47749f;font-size:24px
}
#launchHint{
 position:fixed;z-index:4;left:50%;top:55%;transform:translate(-50%,-50%);
 text-align:center;color:#b9cce2;pointer-events:none
}
@media(max-width:430px){
 .stats{grid-template-columns:repeat(4,1fr)}
 .stat b{font-size:12px}
 button{font-size:11px;padding:10px 8px}
}
</style>
</head>
<body>

<div id="game"></div>

<div class="panel">
 <div class="stats">
  <div class="stat">پول<b id="money">10,000</b></div>
  <div class="stat">سوخت<b id="fuel">0</b></div>
  <div class="stat">سرعت<b id="speed">0 km/h</b></div>
  <div class="stat">ارتفاع<b id="height">0 m</b></div>
 </div>
 <div style="margin-top:6px;font-size:10px;color:#9fb5d1">
  رکورد: <span id="record">0 m</span> │ پروازها: <span id="flights">0</span>
 </div>
</div>

<div id="launchHint">برای شروع، موشکت را آماده کن 🚀</div>

<div id="message"></div>

<div id="bottom">
 <button onclick="openPanel('rocket')">🔧 موشک</button>
 <button onclick="openPanel('factory')">🏭 کارخانه</button>
 <button onclick="openPanel('shop')">🛒 فروشگاه</button>
 <button class="primary" id="launchBtn" onclick="launch()">🚀 پرتاب</button>
</div>

<div id="flightControls">
 <button class="ctrl" id="left">◀</button>
 <button class="ctrl" id="right">▶</button>
</div>

<div id="screen">
 <div class="box">
  <h2 id="screenTitle">موشک</h2>
  <div id="screenContent"></div>
  <button class="close" onclick="closePanel()">بستن</button>
 </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script>
/* =========================================================
   ذخیره بازی
========================================================= */
const SAVE_KEY="rocket_factory_save_v1";

let data=JSON.parse(localStorage.getItem(SAVE_KEY)||"null")||{
 money:10000,
 fuel:0,
 flights:0,
 record:0,
 iron:20,
 steel:5,
 aluminum:10,
 titanium:0,
 liquid:20,
 rocket:{
  body:1,
  engine:1,
  tank:1,
  fins:1
 }
};

function save(){
 localStorage.setItem(SAVE_KEY,JSON.stringify(data));
 updateHUD();
}

function money(n){
 return Math.floor(n).toLocaleString("fa-IR");
}

function msg(t){
 const e=document.getElementById("message");
 e.textContent=t;
 e.classList.add("show");
 clearTimeout(msg.timer);
 msg.timer=setTimeout(()=>e.classList.remove("show"),2200);
}

function updateHUD(){
 document.getElementById("money").textContent=money(data.money);
 document.getElementById("fuel").textContent=money(data.fuel);
 document.getElementById("record").textContent=money(data.record)+" m";
 document.getElementById("flights").textContent=money(data.flights);
 document.getElementById("height").textContent=money(state.altitude)+" m";
 document.getElementById("speed").textContent=money(Math.max(0,state.velocity*3.6))+" km/h";
}

/* =========================================================
   THREE.JS
========================================================= */
const scene=new THREE.Scene();
scene.background=new THREE.Color(0x071327);
scene.fog=new THREE.FogExp2(0x071327,.0018);

const camera=new THREE.PerspectiveCamera(
 65,innerWidth/innerHeight,.1,50000
);
camera.position.set(8,7,14);

const renderer=new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio(Math.min(devicePixelRatio,2));
renderer.setSize(innerWidth,innerHeight);
renderer.shadowMap.enabled=true;
document.getElementById("game").appendChild(renderer.domElement);

const ambient=new THREE.HemisphereLight(0xb9dcff,0x14200d,1.8);
scene.add(ambient);

const sun=new THREE.DirectionalLight(0xffffff,2.2);
sun.position.set(30,60,20);
sun.castShadow=true;
scene.add(sun);

/* زمین */
const groundMat=new THREE.MeshStandardMaterial({color:0x27351e});
const ground=new THREE.Mesh(
 new THREE.PlaneGeometry(10000,10000),
 groundMat
);
ground.rotation.x=-Math.PI/2;
ground.receiveShadow=true;
scene.add(ground);

/* سکوی پرتاب */
const pad=new THREE.Mesh(
 new THREE.CylinderGeometry(8,8,.5,32),
 new THREE.MeshStandardMaterial({color:0x505967,metalness:.7,roughness:.35})
);
pad.position.y=.25;
pad.receiveShadow=true;
scene.add(pad);

const padRing=new THREE.Mesh(
 new THREE.TorusGeometry(6,.18,10,48),
 new THREE.MeshStandardMaterial({color:0x24b8e8,emissive:0x06384a})
);
padRing.rotation.x=Math.PI/2;
padRing.position.y=.53;
scene.add(padRing);

/* ابرها */
const clouds=[];
for(let i=0;i<45;i++){
 const g=new THREE.Group();
 const m=new THREE.MeshStandardMaterial({
  color:0xdceaff,transparent:true,opacity:.7
 });
 for(let j=0;j<4;j++){
  const c=new THREE.Mesh(new THREE.SphereGeometry(
   18+Math.random()*18,10,8
  ),m);
  c.position.set(j*20,Math.random()*8,Math.random()*15);
  g.add(c);
 }
 g.position.set(
  (Math.random()-.5)*1400,
  300+Math.random()*1800,
  (Math.random()-.5)*1400
 );
 g.scale.setScalar(.7+Math.random()*1.5);
 scene.add(g);
 clouds.push(g);
}

/* =========================================================
   ساخت موشک
========================================================= */
let rocket=new THREE.Group();
scene.add(rocket);

function clearGroup(g){
 while(g.children.length){
  const o=g.children.pop();
  if(o.geometry)o.geometry.dispose();
  if(o.material)o.material.dispose();
 }
}

function createRocket(){
 clearGroup(rocket);

 const bodyLevel=data.rocket.body;
 const engineLevel=data.rocket.engine;
 const tankLevel=data.rocket.tank;
 const finLevel=data.rocket.fins;

 const bodyRadius=.9+.08*bodyLevel;
 const bodyLength=4.2+.35*bodyLevel;

 const bodyMat=new THREE.MeshStandardMaterial({
  color:0xcbd4df,
  metalness:.7,
  roughness:.27
 });

 const body=new THREE.Mesh(
  new THREE.CylinderGeometry(bodyRadius,bodyRadius,bodyLength,32),
  bodyMat
 );
 body.position.y=bodyLength/2+1;
 body.castShadow=true;
 rocket.add(body);

 const nose=new THREE.Mesh(
  new THREE.ConeGeometry(bodyRadius,1.8+.12*bodyLevel,32),
  new THREE.MeshStandardMaterial({
   color:0xeaf2fa,metalness:.6,roughness:.25
  })
 );
 nose.position.y=bodyLength+1.9;
 nose.castShadow=true;
 rocket.add(nose);

 const windowMat=new THREE.MeshStandardMaterial({
  color:0x28bce9,metalness:.4,roughness:.15,
  emissive:0x073e55
 });

 const window=new THREE.Mesh(
  new THREE.SphereGeometry(.35+.03*bodyLevel,24,16),
  windowMat
 );
 window.scale.z=.25;
 window.position.set(0,bodyLength*.68+1,bodyRadius*.92);
 rocket.add(window);

 /* حلقه‌ها */
 for(let i=0;i<2+bodyLevel;i++){
  const ring=new THREE.Mesh(
   new THREE.TorusGeometry(bodyRadius+.02,.07,8,32),
   new THREE.MeshStandardMaterial({color:0x596779,metalness:.8})
  );
  ring.rotation.x=Math.PI/2;
  ring.position.y=1.7+i*(bodyLength/(3+bodyLevel));
  rocket.add(ring);
 }

 /* باله‌ها */
 const finMat=new THREE.MeshStandardMaterial({
  color:0xc33c42,metalness:.5,roughness:.35
 });
 for(let i=0;i<3;i++){
  const fin=new THREE.Mesh(
   new THREE.BoxGeometry(.18,1.8+.2*finLevel,.75+.18*finLevel),
   finMat
  );
  const a=i*Math.PI*2/3;
  fin.position.set(
   Math.cos(a)*(bodyRadius+.32),
   1.65,
   Math.sin(a)*(bodyRadius+.32)
  );
  fin.rotation.y=-a;
  fin.castShadow=true;
  rocket.add(fin);
 }

 /* موتور */
 const nozzle=new THREE.Mesh(
  new THREE.CylinderGeometry(.7+.07*engineLevel,.42,1.05+.12*engineLevel,24),
  new THREE.MeshStandardMaterial({color:0x343b45,metalness:.9,roughness:.2})
 );
 nozzle.position.y=.65;
 rocket.add(nozzle);

 /* شعله */
 const flame=new THREE.Mesh(
  new THREE.ConeGeometry(.45+.06*engineLevel,2.2+.3*engineLevel,20),
  new THREE.MeshBasicMaterial({
   color:0xffa51f,transparent:true,opacity:.88
  })
 );
 flame.position.y=-.9;
 flame.name="flame";
 flame.visible=false;
 rocket.add(flame);

 rocket.position.set(0,.6,0);
 rocket.rotation.set(0,0,0);
}

createRocket();

/* =========================================================
   حالت پرواز
========================================================= */
const state={
 flying:false,
 altitude:0,
 velocity:0,
 fuel:0,
 time:0,
 horizontal:0,
 tilt:0,
 crashed:false
};

function flightCapacity(){
 return 18+data.rocket.tank*12;
}

function thrust(){
 return 17+
  data.rocket.engine*4+
  data.rocket.body*0.7;
}

function efficiency(){
 return .9+
 data.rocket.engine*.04+
 data.rocket.tank*.02;
}

function maxPotential(){
 return Math.floor(
  (flightCapacity()*thrust()*9)*
  efficiency()*
  (1+data.rocket.body*.045)
 );
}

function launch(){
 if(state.flying)return;

 if(data.fuel<=0){
  msg("⛽ سوخت نداری! از کارخانه سوخت بساز.");
  openPanel("factory");
  return;
 }

 state.flying=true;
 state.crashed=false;
 state.altitude=0;
 state.velocity=0;
 state.time=0;
 state.horizontal=0;
 state.tilt=0;

 state.fuel=Math.min(data.fuel,flightCapacity());
 data.fuel-=state.fuel;

 document.getElementById("launchBtn").disabled=true;
 document.getElementById("flightControls").style.display="flex";
 document.getElementById("launchHint").style.display="none";

 rocket.getObjectByName("flame").visible=true;
 camera.fov=68;
 camera.updateProjectionMatrix();

 msg("🚀 پرتاب آغاز شد!");
}

function finishFlight(reason){
 if(!state.flying)return;

 state.flying=false;
 rocket.getObjectByName("flame").visible=false;
 document.getElementById("launchBtn").disabled=false;
 document.getElementById("flightControls").style.display="none";

 const earned=Math.max(100,Math.floor(
  state.altitude*.65+
  state.velocity*5+
  data.rocket.body*30
 ));

 data.money+=earned;
 data.flights++;

 if(state.altitude>data.record){
  data.record=Math.floor(state.altitude);
  msg("🏆 رکورد جدید! +" + money(earned)+" تومان");
 }else{
  msg("💰 درآمد پرواز: +"+money(earned)+" تومان");
 }

 if(reason==="crash"){
  data.money=Math.max(0,data.money-50);
 }

 save();
}

/* =========================================================
   پنل‌ها
========================================================= */
function openPanel(type){
 const screen=document.getElementById("screen");
 const title=document.getElementById("screenTitle");
 const content=document.getElementById("screenContent");

 screen.classList.add("show");

 if(type==="rocket"){
  title.textContent="🔧 کارگاه موشک";
  content.innerHTML=`
   <div class="card">
    <strong>موشک فعلی</strong>
    ظرفیت سوخت: ${flightCapacity()} واحد<br>
    توان موتور: ${thrust()}<br>
    ارتفاع تخمینی: ${money(maxPotential())} متر
   </div>

   ${upgradeHTML("بدنه","body",data.rocket.body,650,
     "استحکام بیشتر و ارتفاع بهتر")}
   ${upgradeHTML("موتور","engine",data.rocket.engine,900,
     "نیروی رانش بیشتر")}
   ${upgradeHTML("مخزن سوخت","tank",data.rocket.tank,750,
     "ظرفیت سوخت بیشتر")}
   ${upgradeHTML("باله‌ها","fins",data.rocket.fins,500,
     "پایداری بهتر هنگام پرواز")}
  `;
 }else if(type==="factory"){
  title.textContent="🏭 کارخانه سوخت";
  content.innerHTML=`
   <div class="card">
    مایع: <b>${money(data.liquid)}</b> واحد<br>
    سوخت آماده: <b>${money(data.fuel)}</b> واحد
   </div>

   <div class="row">
    <div>تبدیل 5 مایع به 4 سوخت<small>فرآیند پایه</small></div>
    <button onclick="makeFuel(5,4)">تولید</button>
   </div>

   <div class="row">
    <div>تبدیل 10 مایع + 2 آهن به 10 سوخت<small>سوخت تقویت‌شده</small></div>
    <button onclick="makeFuelAdvanced()">تولید</button>
   </div>

   <div class="row">
    <div>تبدیل 15 مایع + 2 فولاد به 17 سوخت<small>سوخت صنعتی</small></div>
    <button onclick="makeFuelSteel()">تولید</button>
   </div>

   <h3>مواد اولیه</h3>
   <div class="grid">
    <div class="card">آهن<br><b>${money(data.iron)}</b></div>
    <div class="card">فولاد<br><b>${money(data.steel)}</b></div>
    <div class="card">آلومینیوم<br><b>${money(data.aluminum)}</b></div>
    <div class="card">تیتانیوم<br><b>${money(data.titanium)}</b></div>
   </div>
  `;
 }else if(type==="shop"){
  title.textContent="🛒 فروشگاه مواد";
  content.innerHTML=`
   <div class="grid">
    ${shopCard("آهن","iron",1,35)}
    ${shopCard("فولاد","steel",1,90)}
    ${shopCard("آلومینیوم","aluminum",1,70)}
    ${shopCard("تیتانیوم","titanium",1,250)}
    ${shopCard("مایع سوخت","liquid",5,80)}
    ${shopCard("مایع ویژه","liquid",20,290)}
   </div>
   <h3>پول فعلی: ${money(data.money)} تومان</h3>
  `;
 }
}

function upgradeHTML(name,key,level,base,desc){
 const price=Math.floor(base*Math.pow(1.55,level-1));
 return `
 <div class="row">
  <div style="flex:1">
   <b>${name} - سطح ${level}</b>
   <small>${desc}</small>
  </div>
  <button onclick="upgrade('${key}',${price})">${money(price)} تومان</button>
 </div>`;
}

function shopCard(name,key,amount,price){
 return `
 <div class="card">
  <strong>${name}</strong>
  +${amount} واحد
  <div class="price">${money(price)} تومان</div>
  <button style="margin-top:7px;width:100%" onclick="buy('${key}',${amount},${price})">خرید</button>
 </div>`;
}

function closePanel(){
 document.getElementById("screen").classList.remove("show");
}

function upgrade(key,price){
 if(data.money<price){
  msg("💸 پول کافی نیست.");
  return;
 }
 data.money-=price;
 data.rocket[key]++;
 createRocket();
 save();
 openPanel("rocket");
 msg("🔧 ارتقا انجام شد.");
}

function buy(key,amount,price){
 if(data.money<price){
  msg("💸 پول کافی نیست.");
  return;
 }
 data.money-=price;
 data[key]+=amount;
 save();
 openPanel("shop");
}

function makeFuel(liquidCost,out){
 if(data.liquid<liquidCost){
  msg("مایع کافی نیست.");
  return;
 }
 data.liquid-=liquidCost;
 data.fuel+=out;
 save();
 openPanel("factory");
 msg("⛽ سوخت ساخته شد.");
}

function makeFuelAdvanced(){
 if(data.liquid<10||data.iron<2){
  msg("مواد لازم کافی نیست.");
  return;
 }
 data.liquid-=10;
 data.iron-=2;
 data.fuel+=10;
 save();
 openPanel("factory");
 msg("🔥 سوخت تقویت‌شده آماده شد.");
}

function makeFuelSteel(){
 if(data.liquid<15||data.steel<2){
  msg("مواد لازم کافی نیست.");
  return;
 }
 data.liquid-=15;
 data.steel-=2;
 data.fuel+=17;
 save();
 openPanel("factory");
 msg("🏭 سوخت صنعتی آماده شد.");
}

/* =========================================================
   کنترل موبایل
========================================================= */
let steer=0;

function bindHold(id,val){
 const e=document.getElementById(id);
 const down=x=>{
  x.preventDefault();
  steer=val;
 };
 const up=x=>{
  x.preventDefault();
  if(steer===val)steer=0;
 };
 e.addEventListener("pointerdown",down);
 e.addEventListener("pointerup",up);
 e.addEventListener("pointercancel",up);
 e.addEventListener("pointerleave",up);
}
bindHold("left",-1);
bindHold("right",1);

window.addEventListener("keydown",e=>{
 if(e.key==="ArrowLeft")steer=-1;
 if(e.key==="ArrowRight")steer=1;
});
window.addEventListener("keyup",e=>{
 if(e.key==="ArrowLeft"&&steer===-1)steer=0;
 if(e.key==="ArrowRight"&&steer===1)steer=0;
});

/* =========================================================
   دوربین و فیزیک
========================================================= */
const clock=new THREE.Clock();

function updateFlight(dt){
 if(!state.flying)return;

 state.time+=dt;

 const flame=rocket.getObjectByName("flame");
 flame.visible=true;
 flame.scale.y=.7+Math.random()*.55;

 /* مصرف سوخت */
 const consumption=(.65+data.rocket.engine*.08)*dt;
 state.fuel-=consumption;

 if(state.fuel<=0){
  state.fuel=0;
  rocket.getObjectByName("flame").visible=false;
  state.velocity-=9*dt;
 }

 const gravity=9.81;
 const accel=thrust()*.85;

 state.velocity += (accel-gravity)*dt;
 state.velocity=Math.max(state.velocity,-25);

 state.altitude += state.velocity*dt;

 /* کنترل افقی */
 state.horizontal += steer*dt*(2.2+data.rocket.fins*.3);
 state.horizontal*=.985;

 state.tilt += steer*dt*.22;
 state.tilt*=.94;

 rocket.position.y=0.6+Math.max(0,state.altitude)/7;
 rocket.position.x=state.horizontal;
 rocket.rotation.z=state.tilt;

 /* باد و لرزش */
 rocket.rotation.x=Math.sin(state.time*5)*.008*(1+state.velocity/100);

 if(state.altitude<0){
  state.altitude=0;
  finishFlight("crash");
  return;
 }

 /* سوخت تمام شده و سرعت منفی شده */
 if(state.fuel<=0&&state.velocity<0){
  finishFlight("crash");
  return;
 }

 updateHUD();

 /* دوربین دنبال موشک */
 const targetY=rocket.position.y+3.5;
 const desired=new THREE.Vector3(
  rocket.position.x+8,
  targetY+5,
  rocket.position.z+14
 );

 camera.position.lerp(desired,Math.min(1,dt*2.2));

 const look=new THREE.Vector3(
  rocket.position.x,
  rocket.position.y+3,
  rocket.position.z
 );
 camera.lookAt(look);

 /* دوربین کمی بازتر می‌شود */
 camera.fov=Math.min(82,68+state.altitude/180);
 camera.updateProjectionMatrix();

 /* ابرها */
 for(const c of clouds){
  c.rotation.y+=dt*.005;
 }
}

/* =========================================================
   دوربین روی زمین
========================================================= */
function groundCamera(dt){
 if(state.flying)return;

 const desired=new THREE.Vector3(9,6,15);
 camera.position.lerp(desired,Math.min(1,dt*2));
 camera.lookAt(0,3,0);
 camera.fov=65;
 camera.updateProjectionMatrix();
}

/* =========================================================
   رندر
========================================================= */
function animate(){
 requestAnimationFrame(animate);

 const dt=Math.min(clock.getDelta(),.05);

 updateFlight(dt);
 groundCamera(dt);

 renderer.render(scene,camera);
}
animate();

window.addEventListener("resize",()=>{
 camera.aspect=innerWidth/innerHeight;
 camera.updateProjectionMatrix();
 renderer.setSize(innerWidth,innerHeight);
});

updateHUD();
</script>
</body>
</html>

⚠️Content was pasted as plain text and auto-formatted as a code block. Use the Code Block button in the editor for proper formatting.

← Back to timeline