![]()
🎭 角色简介
“`yaml
黄兆宇:
Chinese name: 黄兆宇
English name: Zayn Wong
Nickname: 阿宇(家里人)/Zayn(朋友)
age: 24
gender: male
height: 188cm
identity:
…
💬 开场白
“`html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sweet & Nasty</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@400;500;700&display=swap" rel="stylesheet">
<style>
:root {
–pink: #ffc2d1;
–light-pink: #fde2e8;
–blue: #a3d5ff;
–light-blue: #e0f0ff;
–text-color: #583d72;
–white: #ffffff;
–shadow: rgba(0, 0, 0, 0.08);
–dark-purple: #8c75a3;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'M PLUS Rounded 1c', sans-serif;
background: linear-gradient(135deg, var(–light-pink), var(–light-blue));
display: flex; justify-content: center; align-items: flex-start;
min-height: 100vh; padding: 20px; color: var(–text-color);
}
.main-container {
width: 100%; max-width: 500px; background: var(–white);
border-radius: 24px; box-shadow: 0 8px 32px var(–shadow);
padding: 20px; border: 2px solid var(–white);
opacity: 0; transform: translateY(20px);
animation: fadeIn 0.8s ease-out forwards;
}
@keyframes fadeIn { to { opacity: 1; transform: translateY(0); } }
.music-player {
background: linear-gradient(135deg, var(–light-blue), var(–pink));
border-radius: 16px; padding: 15px; display: flex; flex-direction: column;
box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.5); margin-bottom: 20px;
}
.player-core { display: flex; align-items: center; }
.album-art {
width: 60px; height: 60px; background-color: var(–white);
border-radius: 12px; margin-right: 15px; display: flex;
justify-content: center; align-items: center; font-size: 30px;
color: var(–pink); animation: bounce 2s infinite alternate;
}
@keyframes bounce { from { transform: translateY(0); } to { transform: translateY(-5px); } }
.song-info { flex-grow: 1; }
.song-title { font-weight: 700; font-size: 16px; }
.song-artist { font-size: 12px; opacity: 0.8; }
.controls button { background: none; border: none; font-size: 24px; color: var(–white); cursor: pointer; transition: transform 0.2s; }
.controls button:hover { transform: scale(1.1); }
#playlist-toggle { font-size: 20px; margin-left: 10px; }
#playlist { max-height: 0; overflow: hidden; transition: max-height 0.5s ease-in-out; margin-top: 0; }
#playlist.show { max-height: 200px; margin-top: 10px; }
#playlist ul { list-style: none; padding: 10px; background: rgba(255, 255, 255, 0.5); border-radius: 10px; }
#playlist li { padding: 5px 10px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; border-radius: 6px; transition: background 0.2s; }
#playlist li:hover { background: rgba(255, 255, 255, 0.8); }
#playlist li.playing { font-weight: 700; color: var(–pink); }
#playlist li::before { content: '♪'; margin-right: 8px; opacity: 0.7; }
.squad-info {
background-color: var(–light-pink); border-radius: 16px; padding: 15px;
text-align: center; margin-bottom: 20px; position: relative;
border: 2px dashed var(–pink);
}
.squad-info::before {
content: "MEMBERS ONLY"; position: absolute; top: -12px; left: 50%;
transform: translateX(-50%) rotate(-5deg); background: var(–pink);
color: var(–white); padding: 3px 10px; border-radius: 8px;
font-size: 12px; font-weight: 700; letter-spacing: 1px;
}
.squad-title { font-weight: 700; margin-bottom: 10px; font-size: 18px; position: relative; }
.squad-title::before, .squad-title::after { content: '✨'; margin: 0 5px; font-size: 14px; }
.circle { position: relative; display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.member { background: var(–white); padding: 8px; border-radius: 10px; box-shadow: 0 2px 4px var(–shadow); font-weight: 500; transition: all 0.2s; cursor: pointer; user-select: none; }
.member:hover { transform: scale(1.05); background: var(–light-blue); }
.member:active { transform: scale(0.98); }
.twin-bond { grid-column: 1 / -1; background: var(–light-blue); border: 2px solid var(–blue); color: #3a5c7e; }
.scene-section .section-title { font-size: 18px; font-weight: 700; text-align: center; margin: 20px 0 15px; color: var(–blue); position: relative; }
.scene-section .section-title::before, .scene-section .section-title::after { content: '♡'; color: var(–pink); margin: 0 8px; }
.scene-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
.scene-btn { background-color: var(–white); border: 2px solid var(–pink); border-radius: 12px; padding: 12px 15px; font-family: inherit; font-size: 16px; font-weight: 500; color: var(–text-color); cursor: pointer; text-align: left; width: 100%; transition: all 0.3s ease; box-shadow: 0 4px 6px var(–shadow); }
.scene-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 12px var(–shadow); border-color: var(–blue); }
.twin-section .section-title { color: #c786a2; }
.twin-section .scene-btn { border-color: #c7a7d4; }
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(4px); opacity: 0; visibility: hidden; transition: opacity 0.3s, visibility 0.3s; z-index: 1000; }
.modal-overlay.visible { opacity: 1; visibility: visible; }
.modal-window { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.9); background: var(–white); border-radius: 20px; width: 90%; max-width: 380px; box-shadow: 0 10px 40px rgba(0,0,0,0.15); opacity: 0; visibility: hidden; transition: all 0.3s ease-out; z-index: 1001; padding: 20px; border: 3px solid var(–pink); }
.modal-window.visible { opacity: 1; visibility: visible; transform: translate(-50%, -50%) scale(1); }
.modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; }
.modal-title { font-weight: 700; font-size: 20px; color: var(–dark-purple); }
.modal-close-btn { background: var(–light-pink); border: 2px solid var(–pink); color: var(–pink); width: 30px; height: 30px; border-radius: 50%; cursor: pointer; font-size: 16px; display: flex; justify-content: center; align-items: center; font-weight: bold; transition: all 0.2s; }
.modal-close-btn:hover { background: var(–pink); color: var(–white); transform: rotate(90deg); }
.modal-content { font-size: 15px; line-height: 1.6; color: var(–text-color); }
.modal-content strong { color: var(–dark-purple); }
</style>
</head>
<body>
<div class="main-container">
<div class="music-player">
<div class="player-core">
<div class="album-art">♪</div>
<div class="song-info">
<div id="song-title-display" class="song-title">Song Title</div>
<div id="song-artist-display" class="song-artist">Artist</div>
</div>
<div class="controls">
<button id="play-pause-btn">▶</button>
<button id="playlist-toggle">☰</button>
</div>
</div>
<div id="playlist"><ul></ul></div>
<audio id="audio-player" autoplay loop></audio>
</div>
<div class="squad-info">
<div class="squad-title">The Inner Circle</div>
<div class="circle">
<div class="member twin-bond" onclick="showMemberInfo('user')">{{user}}</div>
<div class="member" onclick="showMemberInfo('zayn')">黄兆宇</div>
<div class="member" onclick="showMemberInfo('ryan')">叶家希</div>
<div class="member" onclick="showMemberInfo('chloe')">方咏欣</div>
<div class="member" onclick="showMemberInfo('ian')">周逸朗</div>
<div class="member" onclick="showMemberInfo('jason')">陈俊杰</div>
<div class="member" onclick="showMemberInfo('kelvin')">许嘉铭</div>
</div>
</div>
<div class="scene-section">
<div class="section-title">CHOOSE A SCENE</div>
<div class="scene-grid">
<button class="scene-btn" onclick="switchToOpening(1)">恶臭小团体排外现场</button>
<button class="scene-btn" onclick="switchToOpening(2)">妹妹你好兜风吗你可以倾听我的原生家庭,对了可以操吗?</button>
<button class="scene-btn" onclick="switchToOpening(3)">大家出来玩,最重要的是开心,讲感情就伤钱了</button>
<button class="scene-btn" onclick="switchToOpening(4)">离间这个恶臭小团体就靠你了</button>
<button class="scene-btn" onclick="switchToOpening(5)">暴风雪山庄膝枕(?</button>
</div>
</div>
<div class="scene-section twin-section">
<div class="section-title">TWIN STORIES</div>
<div class="scene-grid">
<button class="scene-btn" onclick="switchToOpening(6)">在家里互道晚安后夜店相遇</button>
<button class="scene-btn" onclick="switchToOpening(7)">双子就是冷战也要回家吃饭</button>
<button class="scene-btn" onclick="switchToOpening(8)">又冷战?</button>
<button class="scene-btn" onclick="switchToOpening(9)">和哥哥睡觉</button>
</div>
</div>
</div>
<div id="modal-overlay" class="modal-overlay"></div>
<div id="member-modal" class="modal-window">
<div class="modal-header">
<div id="modal-title" class="modal-title"></div>
<button id="modal-close-btn" class="modal-close-btn">X</button>
</div>
<div id="modal-content" class="modal-content"></div>
</div><script>
const memberDescriptions = {
user: { name: "{{user}}", desc: "<strong>团体地位:</strong>暂不可知<br><strong>锐评:</strong>你是闯入者,是炸弹,是被观察的新玩具。他们所有人都在看,看你是会乖乖被同化,还是把这个密不透风的圈子炸个稀巴烂。" },
zayn: { name: "黄兆宇 (Zayn)", desc: "<strong>团体地位:</strong>暴躁核心,人形ATM。<br><strong>锐评:</strong>一个专业摆烂并引以为傲的草包。主业是花钱,副业是对你发脾气。把你的痛苦当成他被爱的证明,属于脑干缺失的顶级混蛋。好消息是脸还不错。" },
ryan: { name: "叶家希 (Ryan)", desc: "<strong>团体地位:</strong>首席拱火官,惹祸搭子。<br><strong>锐评:</strong>和黄兆宇共享一个脑细胞,且该细胞常年休眠。黄兆宇是油,他就是火。唯一的人生信条是让事情变得更糟,然后一起挨骂,主打一个陪伴。" },
chloe: { name: "方咏欣 (Chloe)", desc: "<strong>团体地位:</strong>团宠。<br><strong>锐评:</strong>“只要我不开心,你们谁都别想开心”政策的终身践行者。爱好看人下菜碟,专业是阴阳怪气,尤其擅长对付外来的漂亮女孩。想动她?先问问她的专属保姆周逸朗同不同意。" },
ian: { name: "周逸朗 (Ian)", desc: "<strong>团体地位:</strong>团宠的专属人形支架。<br><strong>锐评:</strong>方咏欣的忠犬男友兼摄影师兼情绪垃圾桶。他看起来对谁都温和礼貌,潜台词其实是“除了Chloe我谁都不在乎”。一个行走的“与我无关”,耳聋眼瞎第一名。" },
jason: { name: "陈俊杰 (Jason)", desc: "<strong>团体地位:</strong>气氛组组长,+1复读机。<br><strong>锐评:</strong>人生信条是‘宇哥说得对’和‘希哥牛逼’。墙头草的顶级形态,哪边风大往哪边倒,取决于黄兆宇和叶家希谁的声音更大。一个没有脊椎但有很多漂亮衣服的男人,存在的唯一价值就是无条件吹捧和处理琐事。" },
kelvin: { name: "许嘉铭 (Kelvin)", desc: "<strong>团体地位:</strong>斯文败类,资源掌控者。<br><strong>锐评:</strong>团队里最会玩也最危险的那个。负责提供场地、酒水和“乐子”(指各种女孩)。他将感情视为一场游戏,而你最好别成为他的下一个游戏对象,因为他从不让猎物完整离开。" }
};
const modalOverlay = document.getElementById('modal-overlay');
const memberModal = document.getElementById('member-modal');
const modalTitle = document.getElementById('modal-title');
const modalContent = document.getElementById('modal-content');
const modalCloseBtn = document.getElementById('modal-close-btn');
function showMemberInfo(memberId) {
const memberData = memberDescriptions[memberId];
if (memberData) {
modalTitle.textContent = memberData.name;
modalContent.innerHTML = memberData.desc;
modalOverlay.classList.add('visible');
memberModal.classList.add('visible');
}
}
function hideMemberInfo() {
modalOverlay.classList.remove('visible');
memberModal.classList.remove('visible');
}
modalCloseBtn.addEventListener('click', hideMemberInfo);
modalOverlay.addEventListener('click', hideMemberInfo);const audioPlayer = document.getElementById('audio-player');
const playPauseBtn = document.getElementById('play-pause-btn');
const playlistToggle = document.getElementById('playlist-toggle');
const playlistEl = document.getElementById('playlist');
const songTitleDisplay = document.getElementById('song-title-display');
const songArtistDisplay = document.getElementById('song-artist-display');
const playlistUl = playlistEl.querySelector('ul');
const playlistData = [
{ title: "一格格", artist: "卫兰", url: "https://files.catbox.moe/nqt4zb.flac" },
{ title: "你瞒我瞒", artist: "张柏宇", url: "https://files.catbox.moe/pjldj5.flac" },
{ title: "钟无艳", artist: "谢安琪", url: "https://files.catbox.moe/pqdkox.flac" }
];
let currentSongIndex = 0;
function loadSong(index) {
const song = playlistData[index];
audioPlayer.src = song.url;
songTitleDisplay.textContent = song.title;
songArtistDisplay.textContent = song.artist;
updatePlaylistUI();
}
function updatePlaylistUI() {
playlistUl.innerHTML = '';
playlistData.forEach((song, index) => {
const li = document.createElement('li');
li.textContent = `${song.title} – ${song.artist}`;
if (index === currentSongIndex) li.classList.add('playing');
li.addEventListener('click', () => { currentSongIndex = index; loadSong(currentSongIndex); audioPlayer.play(); });
playlistUl.appendChild(li);
});
}
playPauseBtn.addEventListener('click', () => { audioPlayer.paused ? audioPlayer.play() : audioPlayer.pause(); });
audioPlayer.addEventListener('play', () => { playPauseBtn.textContent = '❚❚'; });
audioPlayer.addEventListener('pause', () => { playPauseBtn.textContent = '▶'; });
playlistToggle.addEventListener('click', () => { playlistEl.classList.toggle('show'); });
document.addEventListener('DOMContentLoaded', () => { loadSong(currentSongIndex); });async function switchToOpening(openingId) {
try {
if (typeof getChatMessages === 'function' && typeof setChatMessage === 'function') {
const messages = await getChatMessages(0, { include_swipe: true });
if (messages && messages.length > 0 && messages[0].swipes && messages[0].swipes.length >= openingId) {
const content = messages[0].swipes[openingId – 1];
setChatMessage(content, 0, { swipe_id: openingId – 1, refresh: 'display_and_render_current' });
console.log(`Switched to opening ${openingId}`);
} else {
console.error(`Error: Opening with ID ${openingId} not found.`);
}
} else {
console.log(`Simulating switch to opening ${openingId}. (SillyTavern API not found)`);
}
} catch (error) {
console.error('Error switching opening:', error);
}
}
</script>
</body>
</html>
“`