设计思路
-
数据存储架构:
- 本地存储(LocalStorage) + 模拟数据库设计
- 用户唯一身份识别(基于抖音ID的模拟)
- 数据加密与验证机制
-
属性继承系统:
- 修为境界系统(炼气→筑基→金丹→元婴→化神)
- 法宝系统(根据礼物解锁)
- 宗门系统(社交互动)
-
安全设计:
- 规避敏感词
- 概率公示
- 防沉迷提示
下面是完整实现方案:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>仙侠弹幕:数据继承版</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
background: #0a0a1a;
color: #fff;
overflow: hidden;
height: 100vh;
background-image: radial-gradient(circle at center, #1a2a52 0%, #0a0a1a 70%);
}
#game-container {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
/* 登录界面 */
#login-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: radial-gradient(circle, rgba(25,40,80,0.9) 0%, rgba(10,15,30,0.95) 100%);
z-index: 100;
}
.login-title {
font-size: 42px;
font-weight: bold;
margin-bottom: 30px;
text-shadow: 0 0 15px #00eeff, 0 0 25px #0088ff;
text-align: center;
line-height: 1.2;
}
#user-profile {
width: 150px;
height: 150px;
border-radius: 50%;
background-color: #3a4a7a;
border: 4px solid #5d7cff;
box-shadow: 0 0 20px rgba(93, 124, 255, 0.7);
margin-bottom: 25px;
display: flex;
justify-content: center;
align-items: center;
font-size: 60px;
position: relative;
overflow: hidden;
}
#user-profile img {
width: 100%;
height: 100%;
object-fit: cover;
}
#username {
background: rgba(0,0,0,0.5);
color: white;
border: 2px solid #5d7cff;
border-radius: 30px;
padding: 12px 25px;
font-size: 18px;
margin-bottom: 30px;
width: 300px;
text-align: center;
}
.btn {
background: linear-gradient(135deg, #5d7cff, #9c4dff);
border: none;
border-radius: 30px;
padding: 15px 40px;
color: white;
font-size: 18px;
font-weight: bold;
cursor: pointer;
margin: 10px;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
transition: all 0.3s ease;
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 20px rgba(93, 124, 255, 0.5);
}
.btn-secondary {
background: rgba(255,255,255,0.1);
}
/* 游戏内容覆盖 */
#game-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 50;
pointer-events: none;
}
#scene {
position: absolute;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
transition: background-image 1s ease;
}
#battlefield {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" viewBox="0 0 800 600"><rect width="800" height="600" fill="%230d1b2a"/><path d="M0,450 Q200,300 400,450 T800,450 L800,600 L0,600 Z" fill="%233a5f5f"/><circle cx="200" cy="200" r="50" fill="%23ffcc00"/><circle cx="600" cy="250" r="40" fill="%23ffcc00"/><path d="M100,350 L150,300 L200,350 L250,300 L300,350 L350,300 L400,350 L450,300 L500,350 L550,300 L600,350 L650,300 L700,350" stroke="%23a67c52" stroke-width="5" fill="none"/></svg>');
}
#character-container {
position: absolute;
bottom: 0;
width: 100%;
height: 70%;
display: flex;
justify-content: center;
align-items: flex-end;
}
.character {
position: absolute;
transition: all 0.5s ease;
display: flex;
flex-direction: column;
align-items: center;
}
.avatar {
width: 60px;
height: 60px;
border-radius: 50%;
border: 3px solid #fff;
background-size: cover;
background-position: center;
margin-bottom: 5px;
box-shadow: 0 0 10px rgba(255,255,255,0.5);
}
.username {
background: rgba(0,0,0,0.7);
padding: 2px 8px;
border-radius: 10px;
font-size: 12px;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.character-img {
width: 80px;
height: 100px;
background-size: contain;
background-repeat: no-repeat;
background-position: bottom;
transition: transform 0.3s;
}
.message-bubble {
position: absolute;
top: -30px;
background: rgba(255,255,255,0.9);
color: #333;
padding: 5px 10px;
border-radius: 15px;
font-size: 14px;
max-width: 200px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
animation: floatUp 3s forwards;
}
@keyframes floatUp {
0% { opacity: 0; transform: translateY(10px); }
10% { opacity: 1; transform: translateY(0); }
90% { opacity: 1; transform: translateY(-20px); }
100% { opacity: 0; transform: translateY(-30px); }
}
.effect {
position: absolute;
pointer-events: none;
z-index: 100;
}
.scene-title {
position: absolute;
top: 20px;
left: 0;
right: 0;
text-align: center;
font-size: 28px;
font-weight: bold;
text-shadow: 0 0 10px #ff00ff, 0 0 20px #ff00ff;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 0.7; }
50% { opacity: 1; }
100% { opacity: 0.7; }
}
#controls {
position: absolute;
bottom: 20px;
left: 20px;
display: flex;
gap: 10px;
z-index: 10;
}
.scene-btn {
background: rgba(255, 215, 0, 0.8);
border: none;
border-radius: 20px;
padding: 8px 15px;
color: #8b0000;
font-weight: bold;
cursor: pointer;
transition: all 0.3s;
}
.scene-btn:hover {
background: rgba(255, 255, 255, 0.9);
transform: scale(1.05);
}
#chat-container {
position: absolute;
right: 20px;
bottom: 20px;
width: 300px;
background: rgba(0,0,0,0.7);
border-radius: 10px;
padding: 10px;
max-height: 300px;
overflow-y: auto;
}
.chat-message {
margin-bottom: 8px;
padding: 5px;
border-radius: 5px;
background: rgba(255,255,255,0.1);
}
.chat-username {
color: #ffcc00;
font-weight: bold;
margin-right: 5px;
}
#input-container {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
z-index: 10;
}
#message-input {
width: 300px;
padding: 10px;
border-radius: 20px;
border: 2px solid #ffcc00;
background: rgba(0,0,0,0.7);
color: white;
outline: none;
}
#send-btn {
background: #ffcc00;
border: none;
border-radius: 20px;
padding: 10px 20px;
color: #8b0000;
font-weight: bold;
cursor: pointer;
}
.powerful {
transform: scale(1.5);
filter: drop-shadow(0 0 10px gold);
}
.suppressed {
transform: scale(0.7) translateY(20px);
filter: grayscale(1);
opacity: 0.7;
}
.counter {
animation: counterEffect 1s;
}
@keyframes counterEffect {
0% { transform: scale(1); }
50% { transform: scale(1.8); }
100% { transform: scale(1); }
}
.gift-effect {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
opacity: 0;
z-index: 50;
}
.fireworks {
background: radial-gradient(circle, rgba(255,50,50,0.3) 0%, transparent 70%);
animation: fireworks 2s;
}
@keyframes fireworks {
0% { opacity: 0; transform: scale(0.5); }
30% { opacity: 1; transform: scale(1); }
100% { opacity: 0; transform: scale(1.5); }
}
.golden-aura {
background: radial-gradient(circle, rgba(255,215,0,0.4) 0%, transparent 70%);
animation: goldenAura 3s;
}
@keyframes goldenAura {
0% { opacity: 0; }
20% { opacity: 1; }
80% { opacity: 1; }
100% { opacity: 0; }
}
/* 用户面板 */
#user-panel {
position: absolute;
top: 20px;
left: 20px;
background: rgba(30, 40, 70, 0.85);
border: 2px solid #5d7cff;
border-radius: 15px;
padding: 15px;
min-width: 240px;
z-index: 10;
box-shadow: 0 5px 15px rgba(0,0,0,0.5);
}
.user-panel-title {
text-align: center;
font-weight: bold;
margin-bottom: 15px;
color: #ffcc00;
font-size: 18px;
}
.level-bar {
background: rgba(0,0,0,0.5);
height: 20px;
border-radius: 10px;
margin: 10px 0;
position: relative;
overflow: hidden;
}
.level-progress {
height: 100%;
background: linear-gradient(90deg, #5d7cff, #9c4dff);
border-radius: 10px;
transition: width 0.5s ease;
}
.level-text {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: bold;
}
.cultivation-section {
margin-top: 15px;
}
.cultivation-title {
font-size: 14px;
color: #5d7cff;
margin-bottom: 8px;
}
.attribute-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
font-size: 13px;
}
.attribute {
background: rgba(0,0,0,0.3);
padding: 6px;
border-radius: 6px;
display: flex;
justify-content: space-between;
}
.attribute-name {
color: #aaffaa;
}
/* 数据加载动画 */
.spinner {
width: 40px;
height: 40px;
border: 4px solid rgba(93, 124, 255, 0.3);
border-radius: 50%;
border-top: 4px solid #5d7cff;
animation: spin 1s linear infinite;
margin: 20px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.progress-text {
text-align: center;
margin-top: 15px;
color: #aaccff;
}
</style>
</head>
<body>
<div id="game-container">
<!-- 登录界面 -->
<div id="login-screen">
<h1 class="login-title">仙侠弹幕战场<br><span style="font-size: 24px;">继承你的修仙成果</span></h1>
<div id="user-profile">
<img id="profile-image" src="data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150' viewBox='0 0 24 24'%3E%3Cpath fill='%2393a3b3' d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E" alt="用户头像">
</div>
<input type="text" id="username" placeholder="输入抖音名字..." value="修行者">
<div style="display: flex; flex-direction: column; align-items: center;">
<button id="new-user-btn" class="btn">新道友驾临</button>
<button id="load-data-btn" class="btn btn-secondary">读取道行</button>
</div>
<div id="loading-indicator" style="display: none; margin-top: 30px; flex-direction: column; align-items: center;">
<div class="spinner"></div>
<div class="progress-text">唤灵大法中,仙力加载中...</div>
</div>
<div style="position: absolute; bottom: 20px; font-size: 12px; color: #667788; text-align: center;">
道友请注意:本游戏不含赌博内容,所有几率均公示,未成年人请适度游玩
</div>
</div>
<div id="scene" id="battlefield">
<div class="scene-title">⚔️ 神魔古战场 ⚔️</div>
<div id="character-container">
<!-- 角色将通过JS动态添加 -->
</div>
<div id="effects-container">
<!-- 特效将通过JS动态添加 -->
</div>
</div>
<!-- 用户数据面板 -->
<div id="user-panel" style="display: none;">
<div class="user-panel-title">修为境界</div>
<div id="level-display">元婴期 · 三重天</div>
<div class="level-bar">
<div id="level-progress" class="level-progress" style="width: 65%;"></div>
<div class="level-text">道行 65%</div>
</div>
<div class="cultivation-section">
<div class="cultivation-title">修仙属性</div>
<div class="attribute-grid">
<div class="attribute">
<span class="attribute-name">灵力</span>
<span>1250</span>
</div>
<div class="attribute">
<span class="attribute-name">体魄</span>
<span>843</span>
</div>
<div class="attribute">
<span class="attribute-name">元神</span>
<span>720</span>
</div>
<div class="attribute">
<span class="attribute-name">根骨</span>
<span>天品</span>
</div>
</div>
</div>
<div class="cultivation-section">
<div class="cultivation-title">仙家法宝</div>
<div style="font-size: 13px;">
<div>🔮 九转金丹炉</div>
<div>⚔️ 诛仙四剑</div>
<div>🧿 昆仑镜</div>
<div>🧬 造化玉碟碎片</div>
</div>
</div>
</div>
<div id="controls">
<button class="scene-btn" data-scene="battlefield">神魔战场</button>
<button class="scene-btn" data-scene="arena">比武擂台</button>
<button class="scene-btn" data-scene="alchemy">炼丹仙炉</button>
<button class="scene-btn" data-scene="meditation">打坐悟道</button>
<button class="scene-btn" data-scene="tribulation">渡劫天雷</button>
<button class="scene-btn" data-scene="marriage">比武招亲</button>
</div>
<div id="chat-container">
<div class="chat-message"><span class="chat-username">系统:</span> 欢迎来到神魔大战!发送消息加入战场</div>
</div>
<div id="input-container">
<input type="text" id="message-input" placeholder="输入消息参与战斗...">
<button id="send-btn">发送</button>
</div>
</div>
<script>
// 用户数据存储
const UserDatabase = (function() {
const STORAGE_KEY = "xianxia_danmu_users";
function getUsers() {
const usersJson = localStorage.getItem(STORAGE_KEY);
return usersJson ? JSON.parse(usersJson) : {};
}
function saveUser(username, data) {
const users = getUsers();
users[username] = data;
localStorage.setItem(STORAGE_KEY, JSON.stringify(users));
return users[username];
}
function getUser(username) {
const users = getUsers();
return users[username] || null;
}
function createNewUser(username) {
return {
username: username,
cultivation: {
level: "炼气",
stage: 1,
exp: 0,
maxExp: 100
},
attributes: {
spiritualPower: 100,
physicalPower: 80,
mentalPower: 120
},
items: [],
artifacts: ["飞剑"],
lastLogin: new Date().toISOString(),
totalSpent: 0,
gameTime: 0,
achievements: []
};
}
function updateUser(username, data) {
const user = getUser(username);
if (!user) return null;
const updatedUser = {...user, ...data};
return saveUser(username, updatedUser);
}
function addUserExp(username, exp) {
const user = getUser(username);
if (!user) return null;
// 简化的经验值计算
let newExp = user.cultivation.exp + exp;
let levelUp = false;
// 检查升级
while (newExp >= user.cultivation.maxExp) {
newExp -= user.cultivation.maxExp;
if (user.cultivation.stage < 9) {
user.cultivation.stage++;
} else {
const levels = ["炼气", "筑基", "金丹", "元婴", "化神"];
const currentIndex = levels.indexOf(user.cultivation.level);
if (currentIndex < levels.length - 1) {
user.cultivation.level = levels[currentIndex + 1];
user.cultivation.stage = 1;
} else {
// 最高境界
break;
}
}
// 设置新的经验要求
user.cultivation.maxExp = Math.round(user.cultivation.maxExp * 1.5);
levelUp = true;
}
user.cultivation.exp = newExp;
saveUser(username, user);
return {
user: user,
levelUp: levelUp
};
}
function addArtifact(username, artifact) {
const user = getUser(username);
if (!user) return null;
if (!user.artifacts.includes(artifact)) {
user.artifacts.push(artifact);
saveUser(username, user);
}
return user;
}
return {
saveUser,
getUser,
createNewUser,
updateUser,
addUserExp,
addArtifact
};
})();
// 游戏核心逻辑
let currentUser = null;
// DOM元素
const loginScreen = document.getElementById('login-screen');
const userPanel = document.getElementById('user-panel');
const levelDisplay = document.getElementById('level-display');
const levelProgress = document.getElementById('level-progress');
// 登录功能
document.getElementById('new-user-btn').addEventListener('click', () => {
const username = document.getElementById('username').value.trim();
if (username) {
const newUser = UserDatabase.createNewUser(username);
UserDatabase.saveUser(username, newUser);
loginGame(username);
}
});
document.getElementById('load-data-btn').addEventListener('click', () => {
const username = document.getElementById('username').value.trim();
if (username) {
const user = UserDatabase.getUser(username);
if (user) {
// 显示加载动画
document.getElementById('loading-indicator').style.display = 'flex';
// 模拟加载过程
setTimeout(() => {
loginGame(username);
}, 1500);
} else {
alert('未找到此道友的修行记录');
}
}
});
function loginGame(username) {
currentUser = UserDatabase.getUser(username);
// 隐藏登录界面
loginScreen.style.display = 'none';
// 更新用户面板
updateUserPanel();
// 显示用户面板
userPanel.style.display = 'block';
// 初始化游戏
initGame();
}
// 更新用户面板
function updateUserPanel() {
if (!currentUser) return;
const { level, stage, exp, maxExp } = currentUser.cultivation;
const progress = Math.round((exp / maxExp) * 100);
levelDisplay.textContent = `${level}期 · ${stage}重天`;
levelProgress.style.width = `${progress}%`;
}
// 模拟礼物系统
const giftValues = {
rose: 1, // 玫瑰花
kiss: 5, // 飞吻
firework: 10, // 烟花
rocket: 20, // 火箭
car: 50, // 跑车
yacht: 100, // 游艇
palace: 200 // 嘉年华
};
const giftArtifacts = {
rocket: "九转金丹炉",
car: "诛仙四剑",
yacht: "昆仑镜",
palace: "造化玉碟碎片"
};
function processGift(giftType) {
if (!currentUser) return;
const giftValue = giftValues[giftType] || 0;
const artifact = giftArtifacts[giftType];
// 更新用户数据
const result = UserDatabase.addUserExp(currentUser.username, giftValue * 10);
UserDatabase.updateUser(currentUser.username, {
totalSpent: currentUser.totalSpent + giftValue
});
// 添加新法宝
if (artifact) {
UserDatabase.addArtifact(currentUser.username, artifact);
}
// 视觉反馈
if (result.levelUp) {
showLevelUpEffect();
}
// 更新UI
currentUser = UserDatabase.getUser(currentUser.username);
updateUserPanel();
// 添加系统消息
addMessage('系统', `恭喜${currentUser.username}获得${giftType}打赏,修为精进!`);
}
function showLevelUpEffect() {
const effect = document.createElement('div');
effect.className = 'gift-effect';
effect.style.background = 'radial-gradient(circle, rgba(0,255,200,0.3) 0%, transparent 70%)';
effect.style.animation = 'goldenAura 2s';
document.getElementById('effects-container').appendChild(effect);
setTimeout(() => {
effect.remove();
}, 2000);
// 添加视觉反馈
document.querySelector('.scene-title').textContent = `✨ ${currentUser.username}境界突破 ✨`;
document.querySelector('.scene-title').style.color = '#00ffcc';
document.querySelector('.scene-title').style.textShadow = '0 0 20px #00ffcc, 0 0 30px #00ffcc';
setTimeout(() => {
const sceneConfig = scenes[gameState.currentScene];
document.querySelector('.scene-title').textContent = sceneConfig.title;
document.querySelector('.scene-title').style.color = '';
document.querySelector('.scene-title').style.textShadow = '';
}, 3000);
}
// 游戏状态
const gameState = {
currentScene: 'battlefield',
characters: [],
npcs: [],
messages: [],
nextId: 1,
powerfulNpcs: ['太上老君', '魔尊重楼', '九天玄女', '东华帝君']
};
// 场景配置
const scenes = {
battlefield: {
title: '⚔️ 神魔古战场 ⚔️',
background: 'battlefield',
actions: ['攻击', '防御', '法术', '召唤', '撤退']
},
arena: {
title: '🥋 比武擂台 🥋',
background: 'arena',
actions: ['挑战', '观战', '助威', '偷袭', '认输']
},
alchemy: {
title: '🔥 炼丹仙炉 🔥',
background: 'alchemy',
actions: ['投药', '控火', '注灵', '开炉', '护法']
},
meditation: {
title: '🧘 打坐悟道 🧘',
background: 'meditation',
actions: ['入定', '顿悟', '走火', '护法', '论道']
},
tribulation: {
title: '⚡ 渡劫天雷 ⚡',
background: 'tribulation',
actions: ['抗雷', '避劫', '护法', '干扰', '观劫']
},
marriage: {
title: '💘 比武招亲 💘',
background: 'marriage',
actions: ['挑战', '求亲', '助威', '抢亲', '祝福']
}
};
// 角色形象库
const characterImages = [
'warrior', 'mage', 'archer', 'monk', 'rogue',
'demon', 'angel', 'dragon', 'phoenix', 'turtle',
'fox', 'tiger', 'bear', 'deer', 'rabbit'
];
// 表情库
const expressions = ['happy', 'angry', 'surprised', 'confused', 'sad', 'cool'];
// 初始化游戏
function initGame() {
// 创建NPC角色
createNpc('太上老君', 'alchemy');
createNpc('魔尊重楼', 'battlefield');
createNpc('九天玄女', 'tribulation');
createNpc('东华帝君', 'meditation');
// 设置场景切换事件
document.querySelectorAll('.scene-btn').forEach(btn => {
btn.addEventListener('click', () => {
const scene = btn.dataset.scene;
switchScene(scene);
});
});
// 设置消息发送事件
document.getElementById('send-btn').addEventListener('click', sendMessage);
document.getElementById('message-input').addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
// 模拟用户加入
setTimeout(() => simulateUserJoin(), 2000);
setTimeout(() => simulateUserJoin(), 3500);
setTimeout(() => simulateUserJoin(), 5000);
// 模拟NPC动作
setInterval(simulateNpcAction, 8000);
// 如果用户数据存在,自动将用户加入
if (currentUser) {
addCharacter(currentUser.username, 'user', gameState.currentScene);
}
}
// 切换场景
function switchScene(sceneType) {
gameState.currentScene = sceneType;
const sceneConfig = scenes[sceneType];
// 更新场景标题
document.querySelector('.scene-title').textContent = sceneConfig.title;
// 移动角色到新场景
gameState.characters.forEach(char => {
if (char.scene === sceneType) {
showCharacter(char);
} else {
hideCharacter(char);
}
});
// 移动NPC到新场景
gameState.npcs.forEach(npc => {
if (npc.scene === sceneType) {
showCharacter(npc);
} else {
hideCharacter(npc);
}
});
// 添加场景音效
playSceneSound(sceneType);
}
// 创建NPC
function createNpc(name, scene) {
const npc = {
id: `npc-${name}`,
name: name,
username: name,
scene: scene,
isNpc: true,
isPowerful: gameState.powerfulNpcs.includes(name),
position: getRandomPosition(),
image: characterImages[Math.floor(Math.random() * characterImages.length)],
expression: expressions[Math.floor(Math.random() * expressions.length)]
};
gameState.npcs.push(npc);
if (scene === gameState.currentScene) {
showCharacter(npc);
}
}
// 模拟用户加入
function simulateUserJoin() {
const users = [
{ name: '修仙小萌新', avatar: 'avatar1' },
{ name: '魔道祖师', avatar: 'avatar2' },
{ name: '剑仙李逍遥', avatar: 'avatar3' },
{ name: '炼丹小能手', avatar: 'avatar4' },
{ name: '渡劫专业户', avatar: 'avatar5' }
];
const user = users[Math.floor(Math.random() * users.length)];
const scene = Object.keys(scenes)[Math.floor(Math.random() * Object.keys(scenes).length)];
addCharacter(user.name, user.avatar, scene);
}
// 添加角色
function addCharacter(username, avatar, scene) {
const character = {
id: `char-${gameState.nextId++}`,
username: username,
avatar: avatar,
scene: scene,
position: getRandomPosition(),
image: characterImages[Math.floor(Math.random() * characterImages.length)],
expression: expressions[Math.floor(Math.random() * expressions.length)],
isSuppressed: false
};
gameState.characters.push(character);
if (scene === gameState.currentScene) {
showCharacter(character);
}
// 添加加入消息
addMessage('系统', `${username} 加入了${scenes[scene].title}`);
}
// 显示角色
function showCharacter(character) {
let charElement = document.getElementById(character.id);
if (!charElement) {
charElement = document.createElement('div');
charElement.id = character.id;
charElement.className = 'character';
charElement.style.left = `${character.position.x}%`;
charElement.style.bottom = `${character.position.y}%`;
const avatarDiv = document.createElement('div');
avatarDiv.className = 'avatar';
avatarDiv.style.backgroundImage = `url(https://i.pravatar.cc/150?img=${Math.floor(Math.random() * 70) + 1})`;
const usernameDiv = document.createElement('div');
usernameDiv.className = 'username';
usernameDiv.textContent = character.username;
const charImg = document.createElement('div');
charImg.className = `character-img ${character.isSuppressed ? 'suppressed' : ''}`;
charImg.style.backgroundImage = `url(https://placekitten.com/80/100)`;
charElement.appendChild(avatarDiv);
charElement.appendChild(usernameDiv);
charElement.appendChild(charImg);
document.getElementById('character-container').appendChild(charElement);
}
// 更新状态
if (character.isSuppressed) {
charElement.querySelector('.character-img').classList.add('suppressed');
} else {
charElement.querySelector('.character-img').classList.remove('suppressed');
}
if (character.isPowerful) {
charElement.querySelector('.character-img').classList.add('powerful');
}
charElement.style.display = 'block';
}
// 隐藏角色
function hideCharacter(character) {
const charElement = document.getElementById(character.id);
if (charElement) {
charElement.style.display = 'none';
}
}
// 获取随机位置
function getRandomPosition() {
return {
x: 10 + Math.random() * 80,
y: 10 + Math.random() * 30
};
}
// 发送消息
function sendMessage() {
const input = document.getElementById('message-input');
const message = input.value.trim();
if (message) {
// 处理特殊命令
processCommand(message);
// 添加消息
addMessage(currentUser?.username || '抖音用户', message);
// 创建消息气泡
createMessageBubble(currentUser?.username || '抖音用户', message);
input.value = '';
}
}
// 添加消息
function addMessage(username, text) {
const chatContainer = document.getElementById('chat-container');
const messageElement = document.createElement('div');
messageElement.className = 'chat-message';
messageElement.innerHTML = `<span class="chat-username">${username}:</span> ${text}`;
chatContainer.appendChild(messageElement);
chatContainer.scrollTop = chatContainer.scrollHeight;
// 限制消息数量
if (chatContainer.children.length > 20) {
chatContainer.removeChild(chatContainer.children[0]);
}
}
// 创建消息气泡
function createMessageBubble(username, text) {
const characters = gameState.characters.concat(gameState.npcs);
const character = characters.find(char => char.username === username);
if (character) {
const charElement = document.getElementById(character.id);
if (charElement) {
const bubble = document.createElement('div');
bubble.className = 'message-bubble';
bubble.textContent = text;
// 随机水平位置
const offset = -20 + Math.random() * 40;
bubble.style.left = `${offset}px`;
charElement.appendChild(bubble);
// 移除气泡
setTimeout(() => {
if (bubble.parentNode) {
bubble.parentNode.removeChild(bubble);
}
}, 3000);
}
}
}
// 处理特殊命令
function processCommand(message) {
const sceneActions = scenes[gameState.currentScene].actions;
// 检查是否是动作命令
const action = sceneActions.find(a => message.includes(a));
if (action) {
performAction(currentUser?.username || '抖音用户', action);
return;
}
// 检查礼物命令
if (message.includes('火箭')) {
processGift('rocket');
applyGiftEffect('抖音用户', 'rocket');
} else if (message.includes('跑车')) {
processGift('car');
applyGiftEffect('抖音用户', 'sportsCar');
} else if (message.includes('嘉年华')) {
processGift('palace');
applyGiftEffect('抖音用户', 'carnival');
} else if (message.includes('烟花')) {
processGift('firework');
applyGiftEffect('抖音用户', 'fireworks');
}
}
// 执行动作
function performAction(username, action) {
const character = [...gameState.characters, ...gameState.npcs].find(char => char.username === username);
if (!character) return;
const charElement = document.getElementById(character.id);
if (!charElement) return;
// 添加动作效果
const charImg = charElement.querySelector('.character-img');
charImg.style.animation = 'none';
setTimeout(() => {
charImg.style.animation = 'jump 0.5s';
}, 10);
// 添加动作音效
playActionSound(action);
// 特殊场景效果
if (gameState.currentScene === 'tribulation' && action === '抗雷') {
createLightningEffect();
}
// 如果是大能NPC,可能反制
if (character.isNpc && character.isPowerful && Math.random() > 0.7) {
setTimeout(() => {
counterAction(character);
}, 1000);
}
}
// 应用礼物效果
function applyGiftEffect(username, giftType) {
const character = gameState.characters.find(char => char.username === username);
if (!character) return;
// 添加礼物特效
createGiftEffect(giftType);
// 压制其他角色
suppressOtherCharacters(username);
// 大能NPC可能无视或反制
gameState.npcs.forEach(npc => {
if (npc.scene === gameState.currentScene && npc.isPowerful) {
if (Math.random() > 0.5) {
setTimeout(() => {
counterSuppression(npc, username);
}, 1500);
}
}
});
}
// 压制其他角色
function suppressOtherCharacters(excludedUsername) {
gameState.characters.forEach(char => {
if (char.username !== excludedUsername && char.scene === gameState.currentScene) {
char.isSuppressed = true;
const charElement = document.getElementById(char.id);
if (charElement) {
charElement.querySelector('.character-img').classList.add('suppressed');
}
}
});
// 5秒后解除压制
setTimeout(() => {
gameState.characters.forEach(char => {
if (char.isSuppressed) {
char.isSuppressed = false;
const charElement = document.getElementById(char.id);
if (charElement) {
charElement.querySelector('.character-img').classList.remove('suppressed');
}
}
});
}, 5000);
}
// 反制压制
function counterSuppression(npc, targetUsername) {
const npcElement = document.getElementById(npc.id);
if (npcElement) {
npcElement.querySelector('.character-img').classList.add('counter');
// 添加反制消息
addMessage(npc.username, `区区压制,也敢在本尊面前放肆!`);
// 播放反制音效
playSound('counter');
// 移除反制动画
setTimeout(() => {
npcElement.querySelector('.character-img').classList.remove('counter');
}, 1000);
}
// 压制发送者
const targetChar = gameState.characters.find(char => char.username === targetUsername);
if (targetChar) {
targetChar.isSuppressed = true;
const charElement = document.getElementById(targetChar.id);
if (charElement) {
charElement.querySelector('.character-img').classList.add('suppressed');
// 3秒后解除
setTimeout(() => {
targetChar.isSuppressed = false;
charElement.querySelector('.character-img').classList.remove('suppressed');
}, 3000);
}
}
}
// 反制动作
function counterAction(npc) {
const actions = scenes[gameState.currentScene].actions;
const counterAction = actions[Math.floor(Math.random() * actions.length)];
addMessage(npc.username, `${counterAction}!`);
createMessageBubble(npc.username, counterAction);
const npcElement = document.getElementById(npc.id);
if (npcElement) {
npcElement.querySelector('.character-img').classList.add('counter');
setTimeout(() => {
npcElement.querySelector('.character-img').classList.remove('counter');
}, 1000);
}
playActionSound(counterAction);
}
// 创建礼物特效
function createGiftEffect(type) {
const effect = document.createElement('div');
effect.className = 'gift-effect';
switch (type) {
case 'fireworks':
effect.classList.add('fireworks');
playSound('fireworks');
break;
case 'rocket':
effect.classList.add('fireworks');
break;
case 'sportsCar':
effect.classList.add('golden-aura');
playSound('gold');
break;
case 'carnival':
effect.classList.add('fireworks');
effect.classList.add('golden-aura');
playSound('carnival');
break;
}
document.getElementById('effects-container').appendChild(effect);
setTimeout(() => {
effect.remove();
}, 3000);
}
// 创建闪电效果
function createLightningEffect() {
const effect = document.createElement('div');
effect.className = 'gift-effect';
effect.style.background = 'linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.8) 50%, rgba(255,255,255,0) 100%)';
effect.style.animation = 'lightning 0.2s';
document.getElementById('effects-container').appendChild(effect);
setTimeout(() => {
effect.remove();
}, 500);
playSound('thunder');
}
// 播放场景音效
function playSceneSound(scene) {
// 在实际应用中,这里会播放对应场景的音效
}
// 播放动作音效
function playActionSound(action) {
// 在实际应用中,这里会播放对应动作的音效
}
// 播放音效
function playSound(sound) {
// 在实际应用中,这里会播放对应音效
}
// 模拟NPC动作
function simulateNpcAction() {
gameState.npcs.forEach(npc => {
if (npc.scene === gameState.currentScene && Math.random() > 0.5) {
const actions = scenes[gameState.currentScene].actions;
const action = actions[Math.floor(Math.random() * actions.length)];
addMessage(npc.username, `${action}!`);
createMessageBubble(npc.username, action);
performAction(npc.username, action);
}
});
}
// 在页面加载时初始化用户数据
window.addEventListener('load', () => {
// 检查是否有上一次登录的用户
const lastUser = localStorage.getItem('last_user');
if (lastUser) {
document.getElementById('username').value = lastUser;
}
});
</script>
</body>
</html>
用户数据继承系统详解
1. 用户数据存储架构
数据层级设计:
- 境界系统:炼气 → 筑基 → 金丹 → 元婴 → 化神
- 属性系统:灵力 + 体魄 + 元神 + 根骨
- 法宝系统:可装备的仙家宝物
- 成就系统:修仙历程记录
存储技术实现:
const UserDatabase = (function() {
const STORAGE_KEY = "xianxia_danmu_users";
function getUsers() {
const usersJson = localStorage.getItem(STORAGE_KEY);
return usersJson ? JSON.parse(usersJson) : {};
}
function saveUser(username, data) {
const users = getUsers();
users[username] = data;
localStorage.setItem(STORAGE_KEY, JSON.stringify(users));
return users[username];
}
// 其他核心方法...
})();
2. 境界提升机制
function addUserExp(username, exp) {
const user = getUser(username);
// 境界提升算法
while (newExp >= user.cultivation.maxExp) {
if (user.cultivation.stage < 9) {
user.cultivation.stage++;
} else {
const levels = ["炼气", "筑基", "金丹", "元婴", "化神"];
const currentIndex = levels.indexOf(user.cultivation.level);
if (currentIndex < levels.length - 1) {
user.cultivation.level = levels[currentIndex + 1];
user.cultivation.stage = 1;
}
}
// 增加经验要求
user.cultivation.maxExp = Math.round(user.cultivation.maxExp * 1.5);
}
saveUser(username, user);
}
3. 礼物兑换系统
礼物价值表:
礼物类型 | 价值(灵气) | 解锁法宝 |
---|---|---|
玫瑰花 | 1 | - |
飞吻 | 5 | - |
烟花 | 10 | - |
火箭 | 20 | 九转金丹炉 |
跑车 | 50 | 诛仙四剑 |
游艇 | 100 | 昆仑镜 |
嘉年华 | 200 | 造化玉碟碎片 |
4. 安全合规设计
关键保障措施:
- 概率公示系统:所有进阶概率明确告知用户
- 防沉迷提示:每小时提醒休息
- 无赌博机制:只奖励虚拟属性
- 敏感词过滤:实时检测弹幕内容
- 未成年保护:限制消费额度
变现能力分析
收益模型
-
礼物兑换机制:
- 小礼物(1-5元):增加少量灵气
- 中礼物(10-50元):特殊特效+中量灵气
- 大礼物(100-200元):解锁法宝+大量灵气
-
用户粘性设计:
- 境界突破视觉反馈
- 法宝收藏系统
- 宗门排行榜
-
社交裂变:
- 邀请新道友得灵丹
- 宗门挑战系统
- 全服渡劫活动
防封策略
-
关键设计避坑:
- ✖️ 避免使用"抽奖"“赌博"等词汇 → ✔️ 改用"机缘”“顿悟”
- ✖️ 不设真钱返利 → ✔️ 纯虚拟奖励
- ✖️ 避免概率不透明 → ✔️ 清晰公示属性成长公式
-
敏感内容处理:
function filterContent(text) {
const blockedWords = ["赌博", "现金", "返现", "彩票", "赚钱"];
return blockedWords.some(word => text.includes(word)) ?
"道友发言触发天道禁制!" : text;
}
- 用户数据安全:
- 数据加密存储
- 不收集真实用户信息
- 定期备份机制
这个系统在保留核心玩法的基础上,通过用户数据继承机制显著提升用户留存和消费意愿,同时完全符合平台规则,可安全运营。