素材 #15
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 96 KiB |
@@ -32,16 +32,51 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa
|
|||||||
display: flex; align-items: center; gap: 10px;
|
display: flex; align-items: center; gap: 10px;
|
||||||
}
|
}
|
||||||
#topBar .title img { width: 34px; height: 34px; border-radius: 7px; box-shadow: 0 0 12px rgba(74,175,255,.5); }
|
#topBar .title img { width: 34px; height: 34px; border-radius: 7px; box-shadow: 0 0 12px rgba(74,175,255,.5); }
|
||||||
|
#topBar .worldNameWrap {
|
||||||
|
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
#topBar .title .worldName {
|
#topBar .title .worldName {
|
||||||
font-size: 22px; font-weight: 700; color: #cfe1f3; -webkit-text-fill-color: #cfe1f3;
|
font-size: 22px; font-weight: 700; color: #cfe1f3; -webkit-text-fill-color: #cfe1f3;
|
||||||
pointer-events: auto;
|
|
||||||
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
padding: 4px 14px; border: 1.5px solid rgba(139,92,246,.55); border-radius: 8px;
|
padding: 4px 14px; border: 1.5px solid rgba(139,92,246,.55); border-radius: 8px;
|
||||||
background: rgba(10,14,23,.75); box-shadow: 0 0 12px rgba(139,92,246,.2);
|
background: rgba(10,14,23,.75); box-shadow: 0 0 12px rgba(139,92,246,.2);
|
||||||
}
|
}
|
||||||
#topBar .title .worldName.editable { cursor: pointer; padding: 2px 8px; border-radius: 5px; transition: background .15s; }
|
#topBar .title .worldName.editable { cursor: pointer; padding: 2px 8px; border-radius: 5px; transition: background .15s; }
|
||||||
#topBar .title .worldName.editable:hover { background: rgba(255,255,255,.08); }
|
#topBar .title .worldName.editable:hover { background: rgba(255,255,255,.08); }
|
||||||
|
|
||||||
|
/* 测试阶段金币编辑器(世界名称右侧) */
|
||||||
|
#topBar .goldEditor {
|
||||||
|
display: none;
|
||||||
|
align-items: center; gap: 6px;
|
||||||
|
padding: 4px 10px; border-radius: 8px;
|
||||||
|
background: rgba(10,14,23,.75);
|
||||||
|
border: 1.5px solid rgba(255,193,7,.45);
|
||||||
|
box-shadow: 0 0 12px rgba(255,193,7,.15);
|
||||||
|
font-size: 13px; color: #ffe082;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#topBar .goldEditor .ge-current { font-weight: 700; min-width: 36px; text-align: right; }
|
||||||
|
#topBar .goldEditor .ge-input {
|
||||||
|
width: 64px; height: 24px; padding: 0 6px;
|
||||||
|
background: rgba(0,0,0,.35); border: 1px solid rgba(255,193,7,.4);
|
||||||
|
border-radius: 5px; color: #ffe082; font-size: 12px; font-weight: 600;
|
||||||
|
outline: none; text-align: center;
|
||||||
|
}
|
||||||
|
#topBar .goldEditor .ge-input:focus { border-color: rgba(255,193,7,.8); }
|
||||||
|
#topBar .goldEditor .ge-btn {
|
||||||
|
width: 24px; height: 24px; border-radius: 5px; border: none;
|
||||||
|
font-size: 15px; font-weight: 700; line-height: 1; cursor: pointer;
|
||||||
|
display: inline-flex; align-items: center; justify-content: center;
|
||||||
|
transition: transform .12s, filter .12s;
|
||||||
|
}
|
||||||
|
#topBar .goldEditor .ge-btn:active { transform: scale(0.92); }
|
||||||
|
#topBar .goldEditor .ge-plus { background: rgba(76,175,80,.25); color: #81c784; }
|
||||||
|
#topBar .goldEditor .ge-plus:hover { background: rgba(76,175,80,.4); }
|
||||||
|
#topBar .goldEditor .ge-minus { background: rgba(239,83,80,.25); color: #ef5350; }
|
||||||
|
#topBar .goldEditor .ge-minus:hover { background: rgba(239,83,80,.4); }
|
||||||
|
#topBar .goldEditor .ge-hint { font-size: 10px; color: #b0a070; }
|
||||||
.worldName-input {
|
.worldName-input {
|
||||||
background: transparent; border: 1px solid rgba(124,199,255,.6); color: #cfe1f3;
|
background: transparent; border: 1px solid rgba(124,199,255,.6); color: #cfe1f3;
|
||||||
font-size: 15px; font-weight: 600; padding: 2px 6px; border-radius: 5px; width: 180px;
|
font-size: 15px; font-weight: 600; padding: 2px 6px; border-radius: 5px; width: 180px;
|
||||||
@@ -738,7 +773,7 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa
|
|||||||
#sceneToolbar .top-icon{width:40px;height:40px;font-size:19px;}
|
#sceneToolbar .top-icon{width:40px;height:40px;font-size:19px;}
|
||||||
}
|
}
|
||||||
@media (max-width:420px){
|
@media (max-width:420px){
|
||||||
#topBar .title .worldName{display:none;}
|
#topBar .title .worldNameWrap{display:none;}
|
||||||
#bottomBar .bb-btn{padding:7px 9px;font-size:11px;}
|
#bottomBar .bb-btn{padding:7px 9px;font-size:11px;}
|
||||||
#worldExpBarWrap{width:280px;gap:5px;}
|
#worldExpBarWrap{width:280px;gap:5px;}
|
||||||
#worldExpBarWrap .we-title{display:none;}
|
#worldExpBarWrap .we-title{display:none;}
|
||||||
@@ -859,7 +894,20 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa
|
|||||||
<div id="worldFrame"><span class="wf-tl"></span><span class="wf-tr"></span><span class="wf-bl"></span><span class="wf-br"></span></div>
|
<div id="worldFrame"><span class="wf-tl"></span><span class="wf-tr"></span><span class="wf-bl"></span><span class="wf-br"></span></div>
|
||||||
|
|
||||||
<div id="topBar">
|
<div id="topBar">
|
||||||
<span class="title"><span class="brand">宇森</span><span class="worldName editable" id="worldName" title="点击编辑世界名称">加载中…</span></span>
|
<span class="title">
|
||||||
|
<span class="brand">宇森</span>
|
||||||
|
<span class="worldNameWrap">
|
||||||
|
<span class="worldName editable" id="worldName" title="点击编辑世界名称">加载中…</span>
|
||||||
|
<span class="goldEditor" id="goldEditor" title="测试专用:调整角色金币">
|
||||||
|
<span>🪙</span>
|
||||||
|
<span class="ge-current" id="goldCurrent">0</span>
|
||||||
|
<input type="number" class="ge-input" id="goldInput" value="1000" min="1" step="1">
|
||||||
|
<button class="ge-btn ge-plus" id="goldPlus" type="button">+</button>
|
||||||
|
<button class="ge-btn ge-minus" id="goldMinus" type="button">−</button>
|
||||||
|
<span class="ge-hint">测试</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
<div class="topRight">
|
<div class="topRight">
|
||||||
<span class="coords" id="coords">坐标: (0, 0)</span>
|
<span class="coords" id="coords">坐标: (0, 0)</span>
|
||||||
<div class="timeInfo" title="世界时间">
|
<div class="timeInfo" title="世界时间">
|
||||||
@@ -1875,13 +1923,13 @@ const MICRO_BUILD_EXTRA = [
|
|||||||
{ id: 'temple', cat: 'build', icon: 'assets/buildings/spring/temple/temple_l.png?v=4', name: '神庙', desc: '供奉信仰的场所,提升居民精神状态与领地声望。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 160, statYield: { prestige: 3 }, costGold: 100 },
|
{ id: 'temple', cat: 'build', icon: 'assets/buildings/spring/temple/temple_l.png?v=4', name: '神庙', desc: '供奉信仰的场所,提升居民精神状态与领地声望。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 160, statYield: { prestige: 3 }, costGold: 100 },
|
||||||
{ id: 'clinic', cat: 'build', icon: 'assets/buildings/spring/clinic/clinic_l.png?v=5', name: '医务室', desc: '诊治伤病,恢复居民生命值。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 100, statYield: { heal: 2 }, costGold: 55 },
|
{ id: 'clinic', cat: 'build', icon: 'assets/buildings/spring/clinic/clinic_l.png?v=5', name: '医务室', desc: '诊治伤病,恢复居民生命值。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 100, statYield: { heal: 2 }, costGold: 55 },
|
||||||
{ id: 'restaurant', cat: 'build', icon: 'assets/buildings/spring/restaurant/restaurant_l.png?v=5',name: '酒馆', desc: '烹制料理,为居民提供饱食与心情加成。', flat: false, w: 2, h: 3, statLevel: 1, statHp: 95, statYield: { satiety: 3 }, costGold: 45 },
|
{ id: 'restaurant', cat: 'build', icon: 'assets/buildings/spring/restaurant/restaurant_l.png?v=5',name: '酒馆', desc: '烹制料理,为居民提供饱食与心情加成。', flat: false, w: 2, h: 3, statLevel: 1, statHp: 95, statYield: { satiety: 3 }, costGold: 45 },
|
||||||
{ id: 'pasture', cat: 'business', icon: 'assets/buildings/spring/pasture/pasture_l.png?v=13', name: '牧场', desc: '放养牲畜,稳定产出肉奶类资源。', flat: false, w: 4, h: 4, statLevel: 1, statHp: 105, statYield: { meat: 2, milk: 1 }, costGold: 70 },
|
{ id: 'pasture', cat: 'business', icon: 'assets/buildings/spring/pasture/pasture_l.png?v=17', name: '牧场', desc: '放养牲畜,稳定产出肉奶类资源。', flat: false, w: 4, h: 4, statLevel: 1, statHp: 105, statYield: { meat: 2, milk: 1 }, costGold: 70 },
|
||||||
{ id: 'blackmarket', cat: 'build', icon: 'assets/buildings/spring/blackmarket/blackmarket_l.png?v=7',name:'商城', desc: '灰色交易点,可换取稀有物资但伴随风险。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 80, statYield: { rare: 1 }, costGold: 120 },
|
{ id: 'blackmarket', cat: 'build', icon: 'assets/buildings/spring/blackmarket/blackmarket_l.png?v=7',name:'商城', desc: '灰色交易点,可换取稀有物资但伴随风险。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 80, statYield: { rare: 1 }, costGold: 120 },
|
||||||
{ id: 'farmland', cat: 'business', icon: 'assets/buildings/spring/farmland/farmland.png?v=202608251713', name: '农田', desc: '春季播种的耕地,定期产出粮食作物。', flat: true, w: 2, h: 2, statLevel: 1, statHp: 60, statYield: { food: 3 }, costGold: 10 },
|
{ id: 'farmland', cat: 'business', icon: 'assets/buildings/spring/farmland/farmland.png?v=202608251713', name: '农田', desc: '春季播种的耕地,定期产出粮食作物。', flat: true, w: 2, h: 2, statLevel: 1, statHp: 60, statYield: { food: 3 }, costGold: 10 },
|
||||||
{ id: 'well', cat: 'build', icon: 'assets/buildings/default/props/well_l.png', name: '水井', desc: '汲取地下水的圆井,保障饮水与灌溉。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 90, statYield: { water: 2 }, costGold: 15 },
|
{ id: 'well', cat: 'build', icon: 'assets/buildings/default/props/well_l.png', name: '水井', desc: '汲取地下水的圆井,保障饮水与灌溉。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 90, statYield: { water: 2 }, costGold: 15 },
|
||||||
{ id: 'school', cat: 'build', icon: 'assets/buildings/spring/school/school_l.png?v=6', name: '学堂', desc: '授业解惑之所,研读典籍提升领地科研与基础教学产出。', flat: false, w: 3, h: 2, statLevel: 1, statHp: 100, statYield: { research: 3, prestige: 1 }, costGold: 90 },
|
{ id: 'school', cat: 'build', icon: 'assets/buildings/spring/school/school_l.png?v=16', name: '学堂', desc: '授业解惑之所,研读典籍提升领地科研与基础教学产出。', flat: false, w: 3, h: 2, statLevel: 1, statHp: 100, statYield: { research: 3, prestige: 1 }, costGold: 90 },
|
||||||
{ id: 'library', cat: 'build', icon: 'assets/buildings/spring/library/library_l.png?v=5', name: '图书馆', desc: '收藏典籍与卷轴,提升领地科研与知识产出。', flat: false, w: 2, h: 3, statLevel: 1, statHp: 110, statYield: { research: 4 }, costGold: 110 },
|
{ id: 'library', cat: 'build', icon: 'assets/buildings/spring/library/library_l.png?v=5', name: '图书馆', desc: '收藏典籍与卷轴,提升领地科研与知识产出。', flat: false, w: 2, h: 3, statLevel: 1, statHp: 110, statYield: { research: 4 }, costGold: 110 },
|
||||||
{ id: 'barracks', cat: 'build', icon: 'assets/buildings/spring/barracks/barracks_l.png?v=6', name: '兵营', desc: '训练士兵与储备武备的军事建筑,提升领地军事产出。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 130, statYield: { military: 4 }, costGold: 130 },
|
{ id: 'barracks', cat: 'build', icon: 'assets/buildings/spring/barracks/barracks_l.png?v=9', name: '兵营', desc: '训练士兵与储备武备的军事建筑,提升领地军事产出。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 130, statYield: { military: 4 }, costGold: 130 },
|
||||||
{ id: 'guild', cat: 'build', icon: 'assets/buildings/spring/guild/guild_l.png?v=4', name: '公会', desc: '冒险者与住民集结之所,可发布委托与招募成员。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 140, statYield: { prestige: 2, coin: 1 }, costGold: 100 },
|
{ id: 'guild', cat: 'build', icon: 'assets/buildings/spring/guild/guild_l.png?v=4', name: '公会', desc: '冒险者与住民集结之所,可发布委托与招募成员。', flat: false, w: 2, h: 2, statLevel: 1, statHp: 140, statYield: { prestige: 2, coin: 1 }, costGold: 100 },
|
||||||
{ id: 'village', cat: 'build', icon: 'assets/buildings/spring/village/village_l.png?v=5', name: '村庄', desc: '族群聚落的核心,提升人口上限与基础产出。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 150, statYield: { population: 6, food: 1 }, costGold: 200 },
|
{ id: 'village', cat: 'build', icon: 'assets/buildings/spring/village/village_l.png?v=5', name: '村庄', desc: '族群聚落的核心,提升人口上限与基础产出。', flat: false, w: 3, h: 3, statLevel: 1, statHp: 150, statYield: { population: 6, food: 1 }, costGold: 200 },
|
||||||
// 生物分类:9 种族角色(点击进入"点地面放置"模式,不进入建筑模式)
|
// 生物分类:9 种族角色(点击进入"点地面放置"模式,不进入建筑模式)
|
||||||
@@ -2082,6 +2130,7 @@ async function microLoadGame() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
microRenderCharHud();
|
microRenderCharHud();
|
||||||
|
updateGoldEditorDisplay();
|
||||||
} catch (e) { /* 离线兜底:不阻塞微观世界 */ }
|
} catch (e) { /* 离线兜底:不阻塞微观世界 */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2138,6 +2187,48 @@ function microRenderCharHud() {
|
|||||||
</div>
|
</div>
|
||||||
<span style="font-size:11px;color:#9fb0c0;white-space:nowrap;">${exp}/${expMax} (${pct}%)</span>
|
<span style="font-size:11px;color:#9fb0c0;white-space:nowrap;">${exp}/${expMax} (${pct}%)</span>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
updateGoldEditorDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 顶部金币编辑器:测试阶段调试角色金币
|
||||||
|
function updateGoldEditorDisplay() {
|
||||||
|
const editor = document.getElementById('goldEditor');
|
||||||
|
const current = document.getElementById('goldCurrent');
|
||||||
|
if (!editor || !current) return;
|
||||||
|
if (!microChar) { editor.style.display = 'none'; return; }
|
||||||
|
editor.style.display = 'inline-flex';
|
||||||
|
current.textContent = Math.floor(microChar.gold || 0);
|
||||||
|
}
|
||||||
|
async function changeGoldEditor(delta) {
|
||||||
|
if (!microChar) { microToast('角色未加载,无法修改金币'); return; }
|
||||||
|
const input = document.getElementById('goldInput');
|
||||||
|
const val = parseInt(input.value, 10) || 0;
|
||||||
|
if (val <= 0) { microToast('请输入正整数'); return; }
|
||||||
|
const next = Math.max(0, Math.floor((microChar.gold || 0) + delta * val));
|
||||||
|
try {
|
||||||
|
const r = await API.saveChar({ gold: next });
|
||||||
|
if (r && r.ok && r.char) {
|
||||||
|
microChar.gold = r.char.gold;
|
||||||
|
updateGoldEditorDisplay();
|
||||||
|
microRenderCharHud();
|
||||||
|
microToast(`金币已调整为 🪙${microChar.gold}`);
|
||||||
|
} else {
|
||||||
|
microToast('金币保存失败:' + (r && r.error ? r.error : '未知错误'));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
microToast('网络错误,金币未保存');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function initGoldEditor() {
|
||||||
|
const plus = document.getElementById('goldPlus');
|
||||||
|
const minus = document.getElementById('goldMinus');
|
||||||
|
const input = document.getElementById('goldInput');
|
||||||
|
if (plus) plus.addEventListener('click', () => changeGoldEditor(1));
|
||||||
|
if (minus) minus.addEventListener('click', () => changeGoldEditor(-1));
|
||||||
|
if (input) input.addEventListener('keydown', (e) => {
|
||||||
|
if (e.key === 'Enter') { e.preventDefault(); changeGoldEditor(1); }
|
||||||
|
});
|
||||||
|
updateGoldEditorDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============ 任务系统(新手主线,后端驱动) ============
|
// ============ 任务系统(新手主线,后端驱动) ============
|
||||||
@@ -2199,6 +2290,7 @@ async function fetchTasks() {
|
|||||||
microChar.gold = r.char.gold;
|
microChar.gold = r.char.gold;
|
||||||
}
|
}
|
||||||
microRenderCharHud();
|
microRenderCharHud();
|
||||||
|
updateGoldEditorDisplay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) { /* 离线兜底 */ }
|
} catch (e) { /* 离线兜底 */ }
|
||||||
@@ -2437,13 +2529,14 @@ function microDrawPlaced(ctx, b, it, cell, ew, eh) {
|
|||||||
// 3/4 立绘建筑:按 rot 切换 _r/_l 视角;180/270 做水平翻转表示背面,取消 canvas 整体旋转
|
// 3/4 立绘建筑:按 rot 切换 _r/_l 视角;180/270 做水平翻转表示背面,取消 canvas 整体旋转
|
||||||
// 尺寸贴合占位地块:底宽 = 占位格宽,与格子边缘对齐;
|
// 尺寸贴合占位地块:底宽 = 占位格宽,与格子边缘对齐;
|
||||||
// 图片脚底对齐 footprint 菱形最下方顶点,避免建筑“浮”在占地左上角。
|
// 图片脚底对齐 footprint 菱形最下方顶点,避免建筑“浮”在占地左上角。
|
||||||
const dim = Math.max(ew, eh);
|
// 立绘本宽 = 等距菱形真实水平跨度 (ew+eh)*cell/2。
|
||||||
const w = cell * dim; // 建筑底宽 = 占位格宽
|
// 正方形时 = max(ew,eh)*cell(与旧逻辑一致);矩形时比 max 更窄,使底座精确齐平菱形左右顶点,不再溢出绿格。
|
||||||
|
const w = (ew + eh) * cell / 2;
|
||||||
const h = w / 0.85; // 维持原宽高比(建筑立绘偏高)
|
const h = w / 0.85; // 维持原宽高比(建筑立绘偏高)
|
||||||
const flip = (rot === 180 || rot === 270);
|
const flip = (rot === 180 || rot === 270);
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.scale(flip ? -1 : 1, 1);
|
ctx.scale(flip ? -1 : 1, 1);
|
||||||
ctx.drawImage(img, -w / 2, eh * cell / 4 - h, w, h);
|
ctx.drawImage(img, -w / 2, (ew + eh) * cell / 8 - h, w, h); // 脚底对齐菱形最下顶点
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -7521,6 +7614,7 @@ if (typeof fitWorld === 'function') fitWorld();
|
|||||||
if (wnEl) wnEl.textContent = local || '我的世界';
|
if (wnEl) wnEl.textContent = local || '我的世界';
|
||||||
}
|
}
|
||||||
fetchTasks(); // 登录即拉取新手主线任务(主世界初次进入也要触发,不只进地块时)
|
fetchTasks(); // 登录即拉取新手主线任务(主世界初次进入也要触发,不只进地块时)
|
||||||
|
initGoldEditor(); // 初始化测试阶段金币编辑器
|
||||||
const backdrop = document.getElementById('uaBackdrop');
|
const backdrop = document.getElementById('uaBackdrop');
|
||||||
const closeBtn = document.getElementById('uaClose');
|
const closeBtn = document.getElementById('uaClose');
|
||||||
const setMenuOpen = (open) => {
|
const setMenuOpen = (open) => {
|
||||||
|
|||||||