微件:GGLScratchGame:修订间差异
来自Limbo Wiki Mirror
无编辑摘要 标签:(旧)WikiEditor |
无编辑摘要 标签:(旧)WikiEditor |
||
| 第1行: | 第1行: | ||
<noinclude> | <noinclude> | ||
<!-- | <!-- Widget文档区 --> | ||
这个Widget用于生成剧情向伪刮刮乐游戏。 | |||
调用方法: {{#widget:GGLScratchGame}} | 调用方法: {{#widget:GGLScratchGame}} | ||
</noinclude> | </noinclude> | ||
| 第9行: | 第9行: | ||
<style> | <style> | ||
/* 游戏容器 */ | /* 游戏容器 */ | ||
. | .ggl-scratch-game-wrapper { | ||
font-family: 'Courier New', Courier, monospace; | font-family: 'Courier New', Courier, monospace; | ||
background: | background: transparent; | ||
padding: 20px; | padding: 20px; | ||
max-width: | max-width: 500px; | ||
margin: 20px auto; | margin: 20px auto; | ||
user-select: none; | user-select: none; | ||
position: relative; | position: relative; | ||
color: #333; | color: #333; | ||
text-align: center; | |||
} | } | ||
/* | /* 顶部状态栏 */ | ||
.game-header { | .game-header { | ||
margin-bottom: 10px; | |||
font-weight: bold; | |||
font-size: 16px; | |||
color: #555; | |||
display: flex; | display: flex; | ||
justify-content: space-between; | justify-content: space-between; | ||
padding: 0 10px; | |||
} | } | ||
/* | /* 彩票主体容器 */ | ||
.ticket-container { | .ticket-container { | ||
width: | width: 100%; | ||
background: #fff; | max-width: 350px; /* 彩票宽度 */ | ||
margin: 0 auto; | |||
/* --- 在这里替换彩票底图 --- */ | |||
background: #fff; | |||
/* background-image: url('你的彩票底图URL'); background-size: 100% 100%; */ | |||
border: 2px dashed #999; | border: 2px dashed #999; | ||
padding: | padding: 15px; | ||
box-shadow: | box-shadow: 0 5px 15px rgba(0,0,0,0.2); | ||
position: relative; | position: relative; | ||
transition: transform 0. | border-radius: 5px; | ||
transition: transform 0.3s; | |||
} | } | ||
.ticket-header { | .ticket-header { | ||
background: #d32f2f; | background: #d32f2f; /* 彩票头红色 */ | ||
color: white; | color: white; | ||
padding: | padding: 8px 10px; | ||
display: flex; | display: flex; | ||
justify-content: space-between; | justify-content: space-between; | ||
font-weight: bold; | font-weight: bold; | ||
border-radius: 4px | border-radius: 4px; | ||
margin-bottom: 10px; | |||
} | } | ||
/* 刮奖区 */ | |||
.scratch-grid-area { | .scratch-grid-area { | ||
background: #fdd835; | /* --- 这里是刮奖区的黄色背景 --- */ | ||
padding: | background: #fdd835; | ||
padding: 8px; | |||
display: grid; | display: grid; | ||
grid-template-columns: repeat(5, 1fr); | grid-template-columns: repeat(5, 1fr); | ||
grid-template-rows: repeat(6, 1fr); | grid-template-rows: repeat(6, 1fr); | ||
gap: 4px; | gap: 4px; | ||
border: 2px solid #f9a825; | border: 2px solid #f9a825; | ||
margin-bottom: 15px; | |||
} | } | ||
| 第103行: | 第76行: | ||
.grid-cell { | .grid-cell { | ||
width: 100%; | width: 100%; | ||
aspect-ratio: 1; /* | aspect-ratio: 1; | ||
background: # | /* --- 在这里替换覆盖层图片 --- */ | ||
color: # | background: #222; | ||
/* background-image: url('你的覆盖层URL'); background-size: cover; */ | |||
color: #222; /* 隐藏文字 */ | |||
display: flex; | display: flex; | ||
align-items: center; | align-items: center; | ||
| 第113行: | 第89行: | ||
overflow: hidden; | overflow: hidden; | ||
position: relative; | position: relative; | ||
} | } | ||
.grid-cell:hover { | .grid-cell:hover { | ||
opacity: 0.9; | |||
} | } | ||
/* 刮开后的状态 */ | /* 刮开后的状态 */ | ||
.grid-cell.revealed { | .grid-cell.revealed { | ||
/* --- 在这里替换刮开后的底图 --- */ | |||
background: #eee; | background: #eee; | ||
color: # | /* background-image: url('你的刮开后底图URL'); background-size: cover; */ | ||
color: #000; | |||
cursor: default; | cursor: default; | ||
font-weight: bold; | font-weight: bold; | ||
} | } | ||
/* | /* === 底部控制区 (新布局) === */ | ||
.ticket- | .ticket-controls-area { | ||
display: flex; | |||
justify-content: space-between; /* 左右分开 */ | |||
align-items: flex-end; /* 底部对齐 */ | |||
margin-top: 10px; | margin-top: 10px; | ||
min-height: 60px; | |||
} | |||
/* 左侧:颜文字 + 吐槽气泡 */ | |||
.mascot-section { | |||
display: flex; | |||
flex-direction: column; | |||
align-items: flex-start; | |||
flex: 1; | |||
margin-right: 10px; | |||
text-align: left; | |||
} | |||
.speech-bubble { | |||
background: #fff; | |||
border: 1px solid #333; | |||
border-radius: 8px 8px 8px 0; /* 左下角尖尖 */ | |||
padding: 8px; | |||
font-size: 12px; | font-size: 12px; | ||
margin-bottom: 5px; | |||
box-shadow: 2px 2px 5px rgba(0,0,0,0.1); | |||
position: relative; | position: relative; | ||
height: | min-height: 20px; | ||
line-height: 1.3; | |||
width: 100%; | |||
} | } | ||
.mascot- | /* 颜文字本体 */ | ||
.mascot-face { | |||
font-size: 18px; | |||
font-size: | |||
font-weight: bold; | font-weight: bold; | ||
color: #333; | |||
margin-left: 5px; | |||
} | } | ||
/* | /* 右侧:按钮 */ | ||
.main-btn { | .main-btn { | ||
padding: | padding: 8px 15px; | ||
font-size: | font-size: 14px; | ||
background: #2196F3; | background: #2196F3; | ||
color: white; | color: white; | ||
| 第159行: | 第155行: | ||
border-radius: 5px; | border-radius: 5px; | ||
cursor: pointer; | cursor: pointer; | ||
white-space: nowrap; | |||
height: 36px; | |||
box-shadow: 2px 2px 0 #000; | |||
transition: all 0.1s; | |||
} | |||
.main-btn:active { | |||
transform: translate(2px, 2px); | |||
box-shadow: none; | |||
} | } | ||
.main-btn:disabled { | .main-btn:disabled { | ||
background: #ccc; | background: #ccc; | ||
box-shadow: none; | |||
cursor: not-allowed; | cursor: not-allowed; | ||
} | } | ||
.main-btn.next-mode { | .main-btn.next-mode { | ||
background: #4CAF50; | background: #4CAF50; /* 绿色 */ | ||
} | |||
.main-btn.danger-mode { | |||
background: #000; | |||
color: red; | |||
border: 1px solid red; | |||
} | } | ||
| 第173行: | 第183行: | ||
background: black !important; | background: black !important; | ||
} | } | ||
.crash-screen { | .crash-screen { | ||
position: fixed; | position: fixed; | ||
| 第192行: | 第200行: | ||
<!-- 2. HTML 结构部分 --> | <!-- 2. HTML 结构部分 --> | ||
<div class=" | <div class="ggl-scratch-game-wrapper" id="ggl-game-root"> | ||
<div class="game-header"> | <div class="game-header"> | ||
<span | <span>GGL-LOTTERY</span> | ||
<span>剩余: <span id="count-val">3</span> 张</span> | |||
</div> | </div> | ||
<div class=" | <!-- 彩票本体 --> | ||
< | <div class="ticket-container" id="ticket-container"> | ||
<div class="ticket-header"> | |||
<div class=" | <div class="ticket-logo">SCRATCH-OFF</div> | ||
<div class="ticket-id">NO. <span id="ticket-id-display">001</span></div> | |||
</div> | |||
<!-- 刮奖格 --> | |||
<div class="scratch-grid-area" id="scratch-grid"> | |||
<!-- JS生成 --> | |||
</div> | </div> | ||
<!-- | <!-- 底部控制区:左吐槽,右按钮 --> | ||
<div class="ticket- | <div class="ticket-controls-area"> | ||
< | <!-- 左下 --> | ||
<div class="mascot-section"> | |||
<div class="speech-bubble" id="mascot-text">请刮开覆盖层...</div> | |||
<div class="mascot-face" id="mascot-face">(・ω・)</div> | |||
<div class="mascot- | |||
</div> | </div> | ||
<!-- 右下 --> | |||
<button id="action-btn" class="main-btn">扫描结果</button> | |||
</div> | </div> | ||
</div> | </div> | ||
</div> | </div> | ||
<!-- | <!-- 结局伪词条 (隐藏内容) --> | ||
<div id="fake-wiki-entry" style="display:none; padding:20px; background:#fff; border:1px solid #ccc; max-width:800px; margin:0 auto;"> | <div id="fake-wiki-entry" style="display:none; padding:20px; background:#fff; border:1px solid #ccc; max-width:800px; margin:0 auto;"> | ||
<h1 style="border-bottom: 1px solid #aaa;">六世恶言</h1> | <h1 style="border-bottom: 1px solid #aaa;">六世恶言</h1> | ||
<div class="wiki-content"> | <div class="wiki-content"> | ||
<div style="float:right; border:1px solid #333; padding:10px; background:#f9f9f9; width: 250px; margin-left:15px;"> | <div style="float:right; border:1px solid #333; padding:10px; background:#f9f9f9; width: 250px; margin-left:15px; margin-bottom:10px;"> | ||
<b> | <b>档案编号:</b> ERROR-666<br> | ||
<b> | <b>风险等级:</b> 极高<br> | ||
<b>来源:</b> 网页劫持 | |||
</div> | </div> | ||
<p><b>描述:</b> | <p><b>描述:</b>“六世恶言”是一种具有高度认知危害的网络异常,常伪装成互动式网页组件(如抽奖、刮刮乐)诱导用户点击。</p> | ||
<p>收藏品1:[ | <hr> | ||
<p>收藏品2:[ | <h3>调查记录</h3> | ||
<p>收藏品3:[回复] <b> | <p><b>收藏品1:</b> [短信记录] “你好,我查到了这个域名的注册人,但是那个地址...是个废弃的火葬场。”</p> | ||
<p><b>收藏品2:</b> [短信记录] “网站代码被篡改过,不仅仅是我们,我已经把警告短信向所有访问过该IP的人都发了一遍。”</p> | |||
<p><b>收藏品3:</b> [回复] <b>“它是我藏在赛博刮刮乐内的,是被惩罚的人。”</b></p> | |||
</div> | </div> | ||
</div> | </div> | ||
| 第249行: | 第252行: | ||
<script> | <script> | ||
(function() { | (function() { | ||
var root = document.getElementById('ggl-game-root'); | |||
var root = document.getElementById(' | |||
if (!root) return; | if (!root) return; | ||
| 第262行: | 第264行: | ||
var elGrid = root.querySelector('#scratch-grid'); | var elGrid = root.querySelector('#scratch-grid'); | ||
var elBtn = root.querySelector('#action-btn'); | var elBtn = root.querySelector('#action-btn'); | ||
var | var elMascotText = root.querySelector('#mascot-text'); | ||
var | var elMascotFace = root.querySelector('#mascot-face'); | ||
var elTicketId = root.querySelector('#ticket-id-display'); | var elTicketId = root.querySelector('#ticket-id-display'); | ||
var elFakeEntry = document.getElementById('fake-wiki-entry'); | var elFakeEntry = document.getElementById('fake-wiki-entry'); | ||
| 第269行: | 第271行: | ||
// 剧情配置 | // 剧情配置 | ||
var cardsData = [ | var cardsData = [ | ||
{ type: 'normal', mascot: '', broadcast: ' | { type: 'normal', mascot: '', broadcast: '结果:谢谢惠顾。' }, // 1. 无 | ||
{ type: 'normal', mascot: '(・ω・)', broadcast: ' | { type: 'normal', mascot: '(・ω・)', broadcast: '检测到异常字符。' }, // 2. 颜文字出场 | ||
{ type: 'bonus', mascot: '(^▽^)', broadcast: ' | { type: 'bonus', mascot: '(^▽^)', broadcast: '恭喜!触发连击,奖励+2张!' }, // 3. 欢呼+加票 | ||
{ type: 'normal', mascot: 'o(*≧▽≦)ツ', broadcast: ' | { type: 'normal', mascot: 'o(*≧▽≦)ツ', broadcast: '结果:1 Data 2。好耶!' }, // 4. 思考 | ||
{ type: 'cheat', mascot: '( ・_・)', broadcast: ' | { type: 'cheat', mascot: '( ・_・)', broadcast: '结果:中奖...?数据好像变了。' }, // 5. 意识到不对 | ||
{ type: 'narrative_bubble', mascot: '', broadcast: ' | { type: 'narrative_bubble', mascot: '', broadcast: '对象已消失。', override: 'Data' }, // 6. 消失 | ||
{ type: 'glitch', mascot: '...', broadcast: 'ERR_#0x00 | { type: 'glitch', mascot: '...', broadcast: 'ERR_#0x00 数据损坏', override: '???' }, // 7. 乱码 | ||
{ type: 'pain', mascot: '', broadcast: '声音检测: | { type: 'pain', mascot: '', broadcast: '声音检测:"好痛!"', override: 'Pain' }, // 8. 受击 | ||
{ type: 'talk', mascot: '', broadcast: ' | { type: 'talk', mascot: '', broadcast: '收到文本:"你是谁?"', override: 'Info' }, // 9. 交流 | ||
{ type: 'stop', mascot: '', broadcast: ' | { type: 'stop', mascot: '', broadcast: '警告:立即停止操作。', override: '停下' }, // 10. 停下 | ||
{ type: 'final', mascot: 'ERROR', broadcast: '你知道的太多了。', override: '平安喜乐' } | { type: 'final', mascot: 'ERROR', broadcast: '你知道的太多了。', override: '平安喜乐' } // 11. 结局 | ||
]; | ]; | ||
function | function updateMascot(text, face) { | ||
if(text) elMascotText.innerText = text; | |||
if(face !== undefined) elMascotFace.innerText = face; | |||
} | } | ||
function generateRandomContent() { | function generateRandomContent() { | ||
var opts = ['10mb', '50Gb', '5Kb', '1Tb', '福', '寿', '乐', '奖', '空 | var opts = ['10mb', '50Gb', '5Kb', '1Tb', '福', '寿', '乐', '奖', '空']; | ||
return opts[Math.floor(Math.random() * opts.length)]; | return opts[Math.floor(Math.random() * opts.length)]; | ||
} | } | ||
| 第295行: | 第297行: | ||
isScanned = false; | isScanned = false; | ||
revealedCount = 0; | revealedCount = 0; | ||
// 按钮重置 | |||
elBtn.innerText = "扫描结果"; | elBtn.innerText = "扫描结果"; | ||
elBtn.className = "main-btn"; | elBtn.className = "main-btn"; | ||
elBtn.disabled = false; | elBtn.disabled = false; | ||
elBtn.style = ""; // 清除内联样式 | |||
elTicketId.innerText = (index + 1).toString().padStart(3, '0'); | elTicketId.innerText = (index + 1).toString().padStart(3, '0'); | ||
elCount.innerText = remainingTickets; | elCount.innerText = remainingTickets; | ||
| 第303行: | 第309行: | ||
var data = cardsData[index]; | var data = cardsData[index]; | ||
elGrid.innerHTML = ''; | elGrid.innerHTML = ''; | ||
// | // 更新颜文字,气泡重置为默认提示 | ||
updateMascot("请刮开覆盖层...", data.mascot); | |||
// 卡片10: 红色警告 | |||
// 卡片10: | |||
if (data.type === 'stop') { | if (data.type === 'stop') { | ||
elBtn.style.border = " | elBtn.style.border = "2px solid red"; | ||
elBtn.style. | elBtn.style.color = "red"; | ||
} | } | ||
| 第321行: | 第325行: | ||
var content = data.override ? data.override : generateRandomContent(); | var content = data.override ? data.override : generateRandomContent(); | ||
// | // 特殊格内容修正 | ||
if(index === 2 && i === 10 | if(index === 2 && (i === 10 || i === 11)) content = "大奖"; | ||
if(index === 8) content = "你是谁"; | if(index === 8) content = "你是谁"; | ||
| 第331行: | 第332行: | ||
cell.dataset.idx = i; | cell.dataset.idx = i; | ||
// | // 绑定点击 | ||
(function(c, cIdx, d){ | (function(c, cIdx, d){ | ||
c.addEventListener('click', function() { | c.addEventListener('click', function() { | ||
| 第340行: | 第341行: | ||
c.innerText = c.dataset.content; | c.innerText = c.dataset.content; | ||
// | // 实时剧情吐槽 | ||
if(cIdx === 5) { // 消失,气泡说话 | |||
if(cIdx === 5) { | |||
var msg = ["别点了", "我在看你", "停下"][Math.floor(Math.random()*3)]; | var msg = ["别点了", "我在看你", "停下"][Math.floor(Math.random()*3)]; | ||
updateMascot(msg, ""); | |||
c.innerText = ""; | c.innerText = ""; | ||
} | } | ||
if(cIdx === 7) { // 喊疼 | |||
if(cIdx === 7) { | c.innerText = ["痛!", "别!", "啊!"][Math.floor(Math.random()*3)]; | ||
c.style.color = "red"; | c.style.color = "red"; | ||
updateMascot("别挠我!", ">_<"); | |||
} | } | ||
if(cIdx === 4 && revealedCount === 15) { // 改字 | |||
if(cIdx === 4 && revealedCount === 15) { | updateMascot("诶...?", "(;゚д゚)"); | ||
var cells = elGrid.querySelectorAll('.grid-cell'); | var cells = elGrid.querySelectorAll('.grid-cell'); | ||
if(cells[29]) cells[29].dataset.content = "中奖"; | if(cells[29]) cells[29].dataset.content = "中奖"; | ||
| 第370行: | 第366行: | ||
elBtn.addEventListener('click', function() { | elBtn.addEventListener('click', function() { | ||
if (isScanned) { | if (isScanned) { | ||
// [再来一张] | // [再来一张] | ||
currentCardIndex++; | currentCardIndex++; | ||
if (currentCardIndex < TOTAL_CARDS) { | if (currentCardIndex < TOTAL_CARDS) { | ||
| 第376行: | 第372行: | ||
} | } | ||
} else { | } else { | ||
// [扫描结果] | // [扫描结果] | ||
if (revealedCount < 30 && currentCardIndex < 9) { | if (revealedCount < 30 && currentCardIndex < 9) { | ||
if(!confirm(" | if(!confirm("还没刮完,确定扫描吗?")) return; | ||
} | } | ||
var data = cardsData[currentCardIndex]; | var data = cardsData[currentCardIndex]; | ||
isScanned = true; | isScanned = true; | ||
elBtn.innerText = "扫描中..."; | |||
setTimeout(function(){ | setTimeout(function(){ | ||
// 显示扫描结果到气泡里 | |||
updateMascot(data.broadcast); | |||
// | // 剧情逻辑 | ||
if (data.type === 'bonus') { | if (data.type === 'bonus') { | ||
remainingTickets += 2; | remainingTickets += 2; | ||
| 第394行: | 第391行: | ||
} | } | ||
if (data.type === 'stop') { | if (data.type === 'stop') { | ||
setTimeout(function(){ | setTimeout(function(){ | ||
updateMascot("严重错误。排出异物..."); | |||
elBtn.innerText = "取出未知票据"; | elBtn.innerText = "取出未知票据"; | ||
elBtn. | elBtn.className = "main-btn danger-mode"; | ||
}, 800); | |||
}, | |||
return; | return; | ||
} | } | ||
if (data.type === 'final') { | if (data.type === 'final') { | ||
triggerEnding(); | triggerEnding(); | ||
| 第415行: | 第409行: | ||
if (remainingTickets < 0) { | if (remainingTickets < 0) { | ||
updateMascot("票据耗尽。"); | |||
elBtn.disabled = true; | elBtn.disabled = true; | ||
return; | return; | ||
| 第423行: | 第417行: | ||
elBtn.classList.add('next-mode'); | elBtn.classList.add('next-mode'); | ||
}, | }, 400); | ||
} | } | ||
}); | }); | ||
| 第432行: | 第426行: | ||
var crash = document.createElement('div'); | var crash = document.createElement('div'); | ||
crash.className = 'crash-screen'; | crash.className = 'crash-screen'; | ||
crash.innerHTML = "<div>FATAL ERROR | crash.innerHTML = "<div>FATAL ERROR</div>"; | ||
document.body.appendChild(crash); | document.body.appendChild(crash); | ||
setTimeout(function(){ | setTimeout(function(){ | ||
crash.remove(); | crash.remove(); | ||
document.body.classList.remove('invert-filter'); | document.body.classList.remove('invert-filter'); | ||
root.style.display = 'none'; // 隐藏游戏 | root.style.display = 'none'; // 隐藏游戏 | ||
if(elFakeEntry) elFakeEntry.style.display = 'block'; // | if(elFakeEntry) elFakeEntry.style.display = 'block'; // 显示伪词条 | ||
window.scrollTo(0,0); | window.scrollTo(0,0); | ||
alert("【系统提示】您收到了一条新短信。"); | alert("【系统提示】您收到了一条新短信。"); | ||
| 第447行: | 第440行: | ||
} | } | ||
// | // 启动 | ||
loadCard(0); | loadCard(0); | ||
2026年2月1日 (日) 12:32的版本
这个Widget用于生成剧情向伪刮刮乐游戏。 调用方法:
刮开奖券 · 在整张刮完后交由bot扫描
刮出数字即能获得对应额度的data
当“平”“安”“喜”“乐”四个字连城一条线时,可再获得一张彩票
看不懂也没关系!bot会告诉你结果!
刮出数字即能获得对应额度的data
当“平”“安”“喜”“乐”四个字连城一条线时,可再获得一张彩票
看不懂也没关系!bot会告诉你结果!
剩余彩票:— 张
可提现 DATA:—
