<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Rocket Empire 3D</title>
<style>
*{box-sizing:border-box}
html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#07111f;color:#fff;font-family:Tahoma,Arial,sans-serif}
#scene{position:fixed;inset:0}
#scene canvas{display:block;width:100%;height:100%}
button{font-family:inherit}
.hidden{display:none!important}
#top{
position:fixed;
top:14px;
left:14px;
right:14px;
display:flex;
justify-content:space-between;
align-items:flex-start;
z-index:20;
pointer-events:none
}
.box{
background:rgba(7,17,32,.86);
border:1px solid rgba(112,170,255,.25);
box-shadow:0 12px 40px rgba(0,0,0,.35);
backdrop-filter:blur(12px);
border-radius:18px
}
#brand{
padding:13px 18px;
font-size:18px;
font-weight:900
}
#brand small{
display:block;
font-size:10px;
color:#87a6ce;
margin-top:4px
}
#stats{
display:flex;
gap:20px;
padding:11px 16px;
direction:rtl
}
.stat{text-align:center;min-width:70px}
.stat span{display:block;color:#8299b8;font-size:10px}
.stat b{display:block;font-size:16px;margin-top:3px}
.gold{color:#ffd34e}
#side{
position:fixed;
right:16px;
top:105px;
width:355px;
max-height:calc(100vh - 125px);
overflow:auto;
z-index:20
}
#tabs{
display:grid;
grid-template-columns:repeat(4,1fr);
gap:5px;
margin-bottom:8px
}
.tab{
border:0;
padding:11px 4px;
border-radius:11px;
background:#14263f;
color:#91a9c9;
font-weight:bold;
cursor:pointer
}
.tab.active{background:#287eff;color:white}
.panel{
display:none;
background:rgba(7,17,32,.94);
border:1px solid rgba(112,170,255,.25);
border-radius:18px;
padding:13px;
box-shadow:0 15px 50px rgba(0,0,0,.45)
}
.panel.active{display:block}
.panel h2{
margin:0 0 12px;
font-size:17px
}
.grid{
display:grid;
grid-template-columns:1fr 1fr;
gap:8px
}
.item{
background:linear-gradient(145deg,#12243b,#0c182b);
border:1px solid #203957;
border-radius:14px;
padding:11px
}
.item b{
display:block;
font-size:13px
}
.item p{
font-size:10px;
color:#8197b6;
line-height:1.7;
margin:5px 0 9px
}
.action{
width:100%;
border:0;
border-radius:9px;
padding:8px;
background:#236fe4;
color:#fff;
font-weight:bold;
cursor:pointer
}
.action:hover{background:#3986ff}
.action:disabled{
background:#27364b;
color:#718097;
cursor:not-allowed
}
.quantity{
font-size:10px;
color:#6e9edb;
margin-top:4px
}
#flightHud{
position:fixed;
left:50%;
top:92px;
transform:translateX(-50%);
z-index:30;
text-align:center;
display:none;
pointer-events:none
}
#flightHud .height{
font-size:42px;
font-weight:900;
text-shadow:0 3px 18px #000
}
#flightHud .unit{
font-size:11px;
color:#a8c4e8
}
#flightStats{
margin-top:8px;
display:flex;
gap:7px;
justify-content:center
}
.pill{
background:rgba(5,12,24,.78);
border:1px solid rgba(130,180,255,.2);
padding:7px 12px;
border-radius:10px;
font-size:11px
}
#rocketCard{
position:fixed;
left:16px;
bottom:16px;
width:270px;
z-index:20;
padding:14px
}
#rocketCard h3{
margin:0 0 10px;
font-size:14px
}
.line{
display:flex;
justify-content:space-between;
font-size:11px;
color:#8da5c5;
margin:7px 0
}
.line strong{color:#fff}
.bar{
height:8px;
border-radius:99px;
background:#17283e;
overflow:hidden
}
.bar i{
display:block;
height:100%;
width:100%;
background:#37d98b;
transition:.2s
}
#help{
position:fixed;
bottom:18px;
left:50%;
transform:translateX(-50%);
z-index:21;
background:rgba(5,12,23,.78);
border:1px solid rgba(120,170,240,.2);
padding:9px 16px;
border-radius:13px;
font-size:11px;
color:#a9bdd9;
pointer-events:none
}
.key{
background:#273b58;
padding:3px 7px;
border-radius:5px;
color:#fff;
font-weight:bold
}
#message{
position:fixed;
top:82px;
left:50%;
transform:translate(-50%,-20px);
z-index:100;
background:#10243d;
border:1px solid #315a89;
border-radius:12px;
padding:10px 18px;
opacity:0;
transition:.2s;
pointer-events:none;
font-size:12px
}
#message.show{
opacity:1;
transform:translate(-50%,0)
}
#result{
position:fixed;
inset:0;
z-index:90;
display:none;
align-items:center;
justify-content:center;
background:rgba(1,6,14,.7)
}
.resultBox{
width:min(420px,90vw);
background:#0b192c;
border:1px solid #315781;
border-radius:24px;
padding:25px;
text-align:center;
box-shadow:0 25px 90px #000
}
.resultBox h1{margin:0 0 15px}
.resultHeight{
font-size:48px;
font-weight:900;
color:#65b7ff
}
.resultMoney{
font-size:24px;
font-weight:bold;
color:#ffd34e;
margin-top:8px
}
.resultBox button{
margin-top:18px;
border:0;
background:#2678f4;
color:white;
padding:11px 30px;
border-radius:11px;
font-weight:bold;
cursor:pointer
}
@media(max-width:850px){
#side{width:310px}
#stats{gap:7px}
.stat{min-width:55px}
#brand{display:none}
}
@media(max-width:600px){
#side{
width:calc(100vw - 32px);
right:16px;
top:auto;
bottom:60px;
max-height:45vh
}
#rocketCard{width:205px}
#help{font-size:9px}
}
</style>
</head>
<body>
<div id="scene"></div>
<div id="top">
<div id="brand" class="box">
🚀 ROCKET EMPIRE
<small>مرکز مدیریت و پرتاب موشک</small>
</div>
<div id="stats" class="box">
<div class="stat">
<span>سرمایه</span>
<b class="gold" id="money">25,000</b>
</div>
<div class="stat">
<span>سوخت</span>
<b id="fuel">0</b>
</div>
<div class="stat">
<span>رکورد</span>
<b id="record">0 m</b>
</div>
<div class="stat">
<span>پرواز</span>
<b id="flights">0</b>
</div>
</div>
</div>
<div id="flightHud">
<div class="height"><span id="height">0</span> m</div>
<div class="unit">ارتفاع</div>
<div id="flightStats">
<div class="pill">سرعت: <b id="speed">0</b> m/s</div>
<div class="pill">سوخت: <b id="flightFuel">0</b></div>
</div>
</div>
<div id="side">
<div id="tabs">
<button class="tab active" data-panel="hangar">🚀 موشک</button>
<button class="tab" data-panel="shop">🏪 مغازه</button>
<button class="tab" data-panel="factory">🏭 کارخانه</button>
<button class="tab" data-panel="records">🏆 رکورد</button>
</div>
<div class="panel active" id="hangar">
<h2>آشیانه موشک</h2>
<div class="grid">
<div class="item">
<b>بدنه</b>
<p>افزایش استحکام و عملکرد موشک</p>
<button class="action" data-upgrade="body"></button>
</div>
<div class="item">
<b>موتور</b>
<p>افزایش شتاب و سرعت صعود</p>
<button class="action" data-upgrade="engine"></button>
</div>
<div class="item">
<b>مخزن</b>
<p>ظرفیت سوخت بیشتر</p>
<button class="action" data-upgrade="tank"></button>
</div>
<div class="item">
<b>بالههای هدایت</b>
<p>کنترل بهتر در هنگام پرواز</p>
<button class="action" data-upgrade="fins"></button>
</div>
</div>
</div>
<div class="panel" id="shop">
<h2>مغازه مواد اولیه</h2>
<div class="grid">
<div class="item">
<b>⛓️ آهن</b>
<p>ماده اولیه بدنه و سازه</p>
<div class="quantity" id="ironQty"></div>
<button class="action" data-buy="iron">خرید</button>
</div>
<div class="item">
<b>🔩 فولاد</b>
<p>برای قطعات مقاوم</p>
<div class="quantity" id="steelQty"></div>
<button class="action" data-buy="steel">خرید</button>
</div>
<div class="item">
<b>⬜ آلومینیوم</b>
<p>فلز سبک برای بدنه</p>
<div class="quantity" id="aluminumQty"></div>
<button class="action" data-buy="aluminum">خرید</button>
</div>
<div class="item">
<b>💠 تیتانیوم</b>
<p>فلز ویژه و بسیار مقاوم</p>
<div class="quantity" id="titaniumQty"></div>
<button class="action" data-buy="titanium">خرید</button>
</div>
<div class="item">
<b>🧪 مایع پایه</b>
<p>ماده اولیه کارخانه سوخت</p>
<div class="quantity" id="liquidQty"></div>
<button class="action" data-buy="liquid">خرید</button>
</div>
<div class="item">
<b>⚙️ آلیاژ ویژه</b>
<p>ترکیب فلزی برای پیشرفتهای بعدی</p>
<div class="quantity" id="alloyQty"></div>
<button class="action" data-buy="alloy">خرید</button>
</div>
</div>
</div>
<div class="panel" id="factory">
<h2>کارخانه سوخت</h2>
<div class="item">
<b>⛽ سوخت استاندارد</b>
<p>۱۰ واحد مایع پایه → ۲۰ واحد سوخت</p>
<button class="action" id="standardFuel">تولید ۲۰ سوخت</button>
</div>
<br>
<div class="item">
<b>🔥 سوخت تقویتشده</b>
<p>۲۰ مایع + ۲ فولاد → ۵۰ سوخت</p>
<button class="action" id="boostFuel">تولید ۵۰ سوخت</button>
</div>
<br>
<div class="item">
<b>📦 سوخت موجود</b>
<div style="font-size:25px;font-weight:bold;margin-top:8px" id="factoryFuel">0</div>
</div>
</div>
<div class="panel" id="records">
<h2>رکوردها</h2>
<div class="item">
<b>🏆 بیشترین ارتفاع</b>
<div style="font-size:32px;color:#62b7ff;font-weight:bold;margin-top:10px" id="recordBig">0 m</div>
</div>
<br>
<div class="item">
<b>💰 درآمد کل</b>
<div style="font-size:23px;color:#ffd34e;font-weight:bold;margin-top:10px" id="totalEarned">0</div>
</div>
<br>
<div class="item">
<b>🚀 تعداد پرواز</b>
<div style="font-size:23px;font-weight:bold;margin-top:10px" id="totalFlights">0</div>
</div>
</div>
</div>
<div id="rocketCard" class="box">
<h3>🔧 وضعیت موشک</h3>
<div class="line"><span>بدنه</span><strong id="bodyLevel">1</strong></div>
<div class="line"><span>موتور</span><strong id="engineLevel">1</strong></div>
<div class="line"><span>مخزن</span><strong id="tankLevel">1</strong></div>
<div class="line"><span>باله</span><strong id="finsLevel">1</strong></div>
<div class="line">
<span>سوخت</span>
<strong id="fuelLabel">0 / 100</strong>
</div>
<div class="bar">
<i id="fuelBar"></i>
</div>
</div>
<div id="help">
<span class="key">SPACE</span> پرتاب
<span class="key">A</span><span class="key">D</span> هدایت
<span class="key">ESC</span> پایان پرواز
</div>
<div id="message"></div>
<div id="result">
<div class="resultBox">
<h1>🚀 پرواز تمام شد</h1>
<div class="resultHeight"><span id="finalHeight">0</span> m</div>
<div style="color:#8ea8ca">ارتفاع نهایی</div>
<div style="margin-top:15px">درآمد پرواز</div>
<div class="resultMoney">+<span id="finalMoney">0</span> 💰</div>
<button id="continue">بازگشت به آشیانه</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script>
/* ==========================================================
Rocket Empire 3D
نسخه مستقل بازی
========================================================== */
const $=id=>document.getElementById(id);
let data={
money:25000,
fuel:0,
record:0,
flights:0,
earned:0,
iron:25,
steel:8,
aluminum:15,
titanium:2,
liquid:50,
alloy:0,
body:1,
engine:1,
tank:1,
fins:1
};
try{
const saved=localStorage.getItem("rocket_empire_save_v3");
if(saved){
const parsed=JSON.parse(saved);
Object.assign(data,parsed);
}
}catch(e){}
function save(){
try{
localStorage.setItem("rocket_empire_save_v3",JSON.stringify(data));
}catch(e){}
}
function money(n){
return Math.floor(n).toLocaleString("en-US");
}
function fuelCapacity(){
return 100+(data.tank-1)*50;
}
function message(text){
const el=$("message");
el.textContent=text;
el.classList.add("show");
clearTimeout(message.timer);
message.timer=setTimeout(()=>el.classList.remove("show"),1700);
}
function refresh(){
$("money").textContent=money(data.money);
$("fuel").textContent=money(data.fuel);
$("record").textContent=money(data.record)+" m";
$("flights").textContent=data.flights;
$("ironQty").textContent=data.iron+" واحد";
$("steelQty").textContent=data.steel+" واحد";
$("aluminumQty").textContent=data.aluminum+" واحد";
$("titaniumQty").textContent=data.titanium+" واحد";
$("liquidQty").textContent=data.liquid+" لیتر";
$("alloyQty").textContent=data.alloy+" واحد";
$("factoryFuel").textContent=money(data.fuel);
$("bodyLevel").textContent="سطح "+data.body;
$("engineLevel").textContent="سطح "+data.engine;
$("tankLevel").textContent="سطح "+data.tank;
$("finsLevel").textContent="سطح "+data.fins;
$("fuelLabel").textContent=money(data.fuel)+" / "+fuelCapacity();
$("fuelBar").style.width=
Math.max(0,Math.min(100,data.fuel/fuelCapacity()*100))+"%";
$("recordBig").textContent=money(data.record)+" m";
$("totalEarned").textContent=money(data.earned)+" 💰";
$("totalFlights").textContent=data.flights;
document.querySelectorAll("[data-upgrade]").forEach(btn=>{
const type=btn.dataset.upgrade;
const cost={
body:2500*data.body,
engine:3500*data.engine,
tank:3000*data.tank,
fins:1800*data.fins
}[type];
btn.textContent="ارتقا | "+money(cost)+" 💰";
btn.disabled=data.money<cost;
});
const shop={
iron:["+10 آهن | 300 💰",300],
steel:["+5 فولاد | 500 💰",500],
aluminum:["+10 آلومینیوم | 450 💰",450],
titanium:["+2 تیتانیوم | 900 💰",900],
liquid:["+25 مایع | 250 💰",250],
alloy:["+2 آلیاژ | 1200 💰",1200]
};
document.querySelectorAll("[data-buy]").forEach(btn=>{
const item=shop[btn.dataset.buy];
btn.textContent=item[0];
btn.disabled=data.money<item[1];
});
}
document.querySelectorAll(".tab").forEach(tab=>{
tab.addEventListener("click",()=>{
document.querySelectorAll(".tab").forEach(t=>t.classList.remove("active"));
document.querySelectorAll(".panel").forEach(p=>p.classList.remove("active"));
tab.classList.add("active");
$(tab.dataset.panel).classList.add("active");
});
});
/* =========================
خرید
========================= */
const shopPrices={
iron:{amount:10,cost:300},
steel:{amount:5,cost:500},
aluminum:{amount:10,cost:450},
titanium:{amount:2,cost:900},
liquid:{amount:25,cost:250},
alloy:{amount:2,cost:1200}
};
document.querySelectorAll("[data-buy]").forEach(btn=>{
btn.addEventListener("click",()=>{
const type=btn.dataset.buy;
const item=shopPrices[type];
if(!item)return;
if(data.money<item.cost){
message("💰 پول کافی نیست");
return;
}
data.money-=item.cost;
data[type]+=item.amount;
save();
refresh();
message("✅ خرید انجام شد");
});
});
/* =========================
ارتقا
========================= */
document.querySelectorAll("[data-upgrade]").forEach(btn=>{
btn.addEventListener("click",()=>{
const type=btn.dataset.upgrade;
const cost={
body:2500*data.body,
engine:3500*data.engine,
tank:3000*data.tank,
fins:1800*data.fins
}[type];
if(data.money<cost){
message("💰 پول کافی نیست");
return;
}
if(data[type]>=10){
message("این قطعه به حداکثر سطح رسیده");
return;
}
data.money-=cost;
data[type]++;
save();
refresh();
updateRocketAppearance();
message("🚀 ارتقا انجام شد");
});
});
/* =========================
کارخانه
========================= */
$("standardFuel").addEventListener("click",()=>{
if(data.liquid<10){
message("🧪 مایع پایه کافی نیست");
return;
}
if(data.fuel>=fuelCapacity()){
message("⛽ مخزن پر است");
return;
}
data.liquid-=10;
data.fuel=Math.min(fuelCapacity(),data.fuel+20);
save();
refresh();
message("⛽ ۲۰ واحد سوخت ساخته شد");
});
$("boostFuel").addEventListener("click",()=>{
if(data.liquid<20||data.steel<2){
message("🧪 مواد اولیه کافی نیست");
return;
}
if(data.fuel>=fuelCapacity()){
message("⛽ مخزن پر است");
return;
}
data.liquid-=20;
data.steel-=2;
data.fuel=Math.min(fuelCapacity(),data.fuel+50);
save();
refresh();
message("🔥 ۵۰ واحد سوخت تقویتشده ساخته شد");
});
/* ==========================================================
THREE.JS
========================================================== */
const scene=new THREE.Scene();
scene.background=new THREE.Color(0x78b8ed);
scene.fog=new THREE.Fog(0x78b8ed,90,260);
const camera=new THREE.PerspectiveCamera(
60,
innerWidth/innerHeight,
.1,
1000
);
camera.position.set(15,11,18);
const renderer=new THREE.WebGLRenderer({
antialias:true,
powerPreference:"high-performance"
});
renderer.setPixelRatio(Math.min(devicePixelRatio,2));
renderer.setSize(innerWidth,innerHeight);
renderer.shadowMap.enabled=true;
renderer.shadowMap.type=THREE.PCFSoftShadowMap;
renderer.outputColorSpace=THREE.SRGBColorSpace;
renderer.toneMapping=THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure=1.15;
$("scene").appendChild(renderer.domElement);
/* نور */
const hemi=new THREE.HemisphereLight(
0xdceeff,
0x34465d,
2.1
);
scene.add(hemi);
const sun=new THREE.DirectionalLight(0xffffff,3.2);
sun.position.set(-40,70,35);
sun.castShadow=true;
sun.shadow.mapSize.width=2048;
sun.shadow.mapSize.height=2048;
sun.shadow.camera.left=-80;
sun.shadow.camera.right=80;
sun.shadow.camera.top=80;
sun.shadow.camera.bottom=-80;
scene.add(sun);
/* زمین */
const groundMat=new THREE.MeshStandardMaterial({
color:0x263b3a,
roughness:.9
});
const ground=new THREE.Mesh(
new THREE.PlaneGeometry(400,400),
groundMat
);
ground.rotation.x=-Math.PI/2;
ground.receiveShadow=true;
scene.add(ground);
/* باند */
const runwayMat=new THREE.MeshStandardMaterial({
color:0x202b36,
roughness:.75
});
const runway=new THREE.Mesh(
new THREE.PlaneGeometry(12,120),
runwayMat
);
runway.rotation.x=-Math.PI/2;
runway.position.y=.015;
runway.receiveShadow=true;
scene.add(runway);
/* خطوط باند */
const lineMat=new THREE.MeshBasicMaterial({
color:0xf2d95c
});
for(let z=-55;z<60;z+=8){
const line=new THREE.Mesh(
new THREE.BoxGeometry(.35,.03,4),
lineMat
);
line.position.set(0,.04,z);
scene.add(line);
}
/* =========================
ساختمانها
========================= */
function building(x,z,w,d,h,color){
const mat=new THREE.MeshStandardMaterial({
color,
roughness:.75
});
const b=new THREE.Mesh(
new THREE.BoxGeometry(w,h,d),
mat
);
b.position.set(x,h/2,z);
b.castShadow=true;
b.receiveShadow=true;
scene.add(b);
const roof=new THREE.Mesh(
new THREE.BoxGeometry(w+.2,.3,d+.2),
new THREE.MeshStandardMaterial({
color:0x34495f,
roughness:.65
})
);
roof.position.set(x,h+.15,z);
roof.castShadow=true;
scene.add(roof);
for(let i=-1;i<=1;i++){
const window=new THREE.Mesh(
new THREE.BoxGeometry(.08,1.1,1.5),
new THREE.MeshStandardMaterial({
color:0x4e9ed1,
emissive:0x123b59,
emissiveIntensity:.6
})
);
window.position.set(
x+w/2+.01,
h*.58,
z+i*3
);
scene.add(window);
}
}
building(-22,-10,9,13,5,0x5a6876);
building(23,-15,11,15,7,0x455a70);
building(-23,18,10,12,6,0x566878);
building(24,18,12,12,5,0x4c5d72);
/* برج پرتاب */
const towerGroup=new THREE.Group();
const towerMat=new THREE.MeshStandardMaterial({
color:0x6c7884,
metalness:.8,
roughness:.35
});
for(const x of [-4.3,4.3]){
for(const z of [-2.2,2.2]){
const leg=new THREE.Mesh(
new THREE.BoxGeometry(.35,13,.35),
towerMat
);
leg.position.set(x,6.5,z);
leg.castShadow=true;
towerGroup.add(leg);
}
}
for(let y=1;y<13;y+=1.5){
const bar=new THREE.Mesh(
new THREE.BoxGeometry(8.7,.18,.18),
towerMat
);
bar.position.y=y;
towerGroup.add(bar);
}
scene.add(towerGroup);
/* سکوی پرتاب */
const pad=new THREE.Mesh(
new THREE.CylinderGeometry(5.2,5.2,.5,48),
new THREE.MeshStandardMaterial({
color:0x303943,
metalness:.55,
roughness:.5
})
);
pad.position.y=.25;
pad.receiveShadow=true;
pad.castShadow=true;
scene.add(pad);
const padRing=new THREE.Mesh(
new THREE.TorusGeometry(4.7,.09,12,64),
new THREE.MeshStandardMaterial({
color:0x2688ff,
emissive:0x0b3c7a,
emissiveIntensity:1.2
})
);
padRing.rotation.x=Math.PI/2;
padRing.position.y=.53;
scene.add(padRing);
/* =========================
موشک
========================= */
const rocket=new THREE.Group();
rocket.position.set(0,3,0);
scene.add(rocket);
let rocketParts={};
function mat(color,metal=.2,rough=.4){
return new THREE.MeshStandardMaterial({
color,
metalness:metal,
roughness:rough
});
}
function createRocket(){
rocket.clear();
const bodyMaterial=mat(
data.body>=7?0xb8c5d2:
data.body>=4?0x9aaabd:
0x8e9baa,
.8,.27
);
const body=new THREE.Mesh(
new THREE.CylinderGeometry(1.45,1.6,6,48),
bodyMaterial
);
body.castShadow=true;
body.receiveShadow=true;
body.position.y=0;
rocket.add(body);
rocketParts.body=body;
/* نوارها */
const stripeMat=new THREE.MeshStandardMaterial({
color:0x227cff,
metalness:.7,
roughness:.25
});
for(const y of [-1.5,1.4]){
const stripe=new THREE.Mesh(
new THREE.TorusGeometry(1.53,.08,12,48),
stripeMat
);
stripe.rotation.x=Math.PI/2;
stripe.position.y=y;
rocket.add(stripe);
}
/* دماغه */
const nose=new THREE.Mesh(
new THREE.ConeGeometry(1.45,2.4,48),
mat⚠️Content was pasted as plain text and auto-formatted as a code block. Use the Code Block button in the editor for proper formatting.