wancheng
|
Before Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 55 KiB |
BIN
images/egos/don_quixote_ego.png
Normal file
|
After Width: | Height: | Size: 3.0 MiB |
BIN
images/egos/faust_ego.png
Normal file
|
After Width: | Height: | Size: 344 KiB |
BIN
images/egos/gregor_ego.png
Normal file
|
After Width: | Height: | Size: 3.2 MiB |
BIN
images/egos/heathcliff_ego.png
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
images/egos/honglu_ego.png
Normal file
|
After Width: | Height: | Size: 3.4 MiB |
BIN
images/egos/ishmael_ego.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
images/egos/meursault_ego.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
images/egos/outis_ego.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
images/egos/rodya_ego.png
Normal file
|
After Width: | Height: | Size: 3.8 MiB |
BIN
images/egos/sinclair_ego.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
BIN
images/egos/yoshihide_ego.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
images/sinners/dante.png
Normal file
|
After Width: | Height: | Size: 916 KiB |
BIN
images/sinners/don_quixote.png
Normal file
|
After Width: | Height: | Size: 774 KiB |
BIN
images/sinners/faust.png
Normal file
|
After Width: | Height: | Size: 673 KiB |
BIN
images/sinners/gregor.png
Normal file
|
After Width: | Height: | Size: 786 KiB |
BIN
images/sinners/heathcliff.png
Normal file
|
After Width: | Height: | Size: 682 KiB |
BIN
images/sinners/honglu.png
Normal file
|
After Width: | Height: | Size: 940 KiB |
BIN
images/sinners/ishmael.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
images/sinners/meursault.png
Normal file
|
After Width: | Height: | Size: 527 KiB |
BIN
images/sinners/outis.png
Normal file
|
After Width: | Height: | Size: 546 KiB |
BIN
images/sinners/rodya.png
Normal file
|
After Width: | Height: | Size: 860 KiB |
BIN
images/sinners/sinclair.png
Normal file
|
After Width: | Height: | Size: 758 KiB |
BIN
images/sinners/sinners.png
Normal file
|
After Width: | Height: | Size: 860 KiB |
BIN
images/sinners/yisang.png
Normal file
|
After Width: | Height: | Size: 559 KiB |
BIN
images/sinners/yoshihide.png
Normal file
|
After Width: | Height: | Size: 642 KiB |
@@ -190,9 +190,10 @@
|
||||
<button class="menu-btn" onclick="window.location.href='matching-game.html'">
|
||||
<i class="fas fa-link"></i> 罪人与原著
|
||||
</button>
|
||||
<button class="menu-btn" onclick="alert('即将进入:罪人立绘排列 (排序)')">
|
||||
<button class="menu-btn" onclick="window.location.href='sinner-gallery.html'">
|
||||
<i class="fas fa-sort-numeric-down"></i> 罪人立绘排列
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
background-color: rgba(42, 42, 42, 0.8);
|
||||
border: 2px solid var(--secondary-color);
|
||||
border-radius: 10px;
|
||||
max-width: 500px;
|
||||
max-width: 1000px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
@@ -110,8 +110,8 @@
|
||||
|
||||
.sinner-image-wrapper {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
width: 400px;
|
||||
height: 600px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 215, 0, 0.3);
|
||||
@@ -127,19 +127,19 @@
|
||||
.sinner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.ego-image-wrapper {
|
||||
position: relative;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
width: 400px;
|
||||
height: 600px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 215, 0, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
opacity: 0.5;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.ego-image-wrapper:hover {
|
||||
@@ -450,19 +450,19 @@
|
||||
|
||||
<script>
|
||||
// 游戏数据
|
||||
const gameData = [
|
||||
{ id: 1, sinner: "浮士德", source: "《浮士德》" },
|
||||
{ id: 2, sinner: "但丁", source: "《神曲》" },
|
||||
{ id: 3, sinner: "良秀", source: "《地狱变》" },
|
||||
{ id: 4, sinner: "默尔索", source: "《局外人》" },
|
||||
{ id: 5, sinner: "鸿璐", source: "《红楼梦》" },
|
||||
{ id: 6, sinner: "希斯克利夫", source: "《呼啸山庄》" },
|
||||
{ id: 7, sinner: "以实玛利", source: "《白鲸》" },
|
||||
{ id: 8, sinner: "罗佳", source: "《罪与罚》" },
|
||||
{ id: 9, sinner: "辛克莱", source: "《德米安》" },
|
||||
{ id: 10, sinner: "奥提斯", source: "《奥提斯》" },
|
||||
{ id: 11, sinner: "格里高尔", source: "《变形记》" },
|
||||
{ id: 12, sinner: "堂吉诃德", source: "《堂吉诃德》" }
|
||||
const gameData = [
|
||||
{ id: 2, sinner: "浮士德", source: "《浮士德》", imgName: "faust", egoImgName: "faust_ego" },
|
||||
{ id: 3, sinner: "堂吉诃德", source: "《堂吉诃德》", imgName: "don_quixote", egoImgName: "don_quixote_ego" },
|
||||
{ id: 4, sinner: "良秀", source: "《地狱变》", imgName: "yoshihide", egoImgName: "yoshihide_ego" },
|
||||
{ id: 5, sinner: "默尔索", source: "《局外人》", imgName: "meursault", egoImgName: "meursault_ego" },
|
||||
{ id: 6, sinner: "鸿璐", source: "《红楼梦》", imgName: "honglu", egoImgName: "honglu_ego" },
|
||||
{ id: 7, sinner: "希斯克利夫", source: "《呼啸山庄》", imgName: "heathcliff", egoImgName: "heathcliff_ego" },
|
||||
{ id: 8, sinner: "以实玛利", source: "《白鲸》", imgName: "ishmael", egoImgName: "ishmael_ego" },
|
||||
{ id: 9, sinner: "罗佳", source: "《罪与罚》", imgName: "rodya", egoImgName: "rodya_ego" },
|
||||
{ id: 10, sinner: "但丁", source: "《神曲》", imgName: "dante", egoImgName: "dante_ego" },
|
||||
{ id: 11, sinner: "辛克莱", source: "《德米安》", imgName: "sinclair", egoImgName: "sinclair_ego" },
|
||||
{ id: 12, sinner: "奥提斯", source: "《奥德修斯》", imgName: "outis", egoImgName: "outis_ego" },
|
||||
{ id: 13, sinner: "格里高尔", source: "《变形记》", imgName: "gregor", egoImgName: "gregor_ego" },
|
||||
];
|
||||
|
||||
// 游戏状态
|
||||
@@ -502,13 +502,13 @@
|
||||
|
||||
// 根据罪人名字构建图片路径,假设图片在images目录下
|
||||
// 使用罪人名字作为文件名,支持常见图片格式
|
||||
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
|
||||
const imageExtensions = ['.png'];
|
||||
let sinnerImageLoaded = false;
|
||||
let egoImageLoaded = false;
|
||||
|
||||
// 尝试加载罪人立绘
|
||||
for (const ext of imageExtensions) {
|
||||
const imagePath = `images/sinners/${sinner.sinner}${ext}`;
|
||||
const imagePath = `images/sinners/${sinner.imgName}${ext}`;
|
||||
sinnerImage.src = imagePath;
|
||||
|
||||
// 检查图片是否可以加载
|
||||
@@ -533,7 +533,7 @@
|
||||
|
||||
// 尝试加载Ego立绘
|
||||
for (const ext of imageExtensions) {
|
||||
const egoPath = `images/egos/${sinner.sinner}${ext}`;
|
||||
const egoPath = `images/egos/${sinner.egoImgName}${ext}`;
|
||||
egoImage.src = egoPath;
|
||||
|
||||
// 检查图片是否可以加载
|
||||
@@ -557,11 +557,11 @@
|
||||
}
|
||||
|
||||
// 重置Ego图片的透明度
|
||||
egoImageWrapper.style.opacity = '0.5';
|
||||
egoImageWrapper.style.opacity = '0';
|
||||
|
||||
// 添加点击事件显示Ego立绘
|
||||
egoImageWrapper.onclick = function() {
|
||||
egoImageWrapper.style.opacity = egoImageWrapper.style.opacity === '0.5' ? '1' : '0.5';
|
||||
egoImageWrapper.style.opacity = egoImageWrapper.style.opacity === '0' ? '1' : '0';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -631,6 +631,8 @@
|
||||
if (currentSinnerIndex < shuffledSinners.length) {
|
||||
displaySinner();
|
||||
document.getElementById('next-btn').disabled = true;
|
||||
|
||||
document.querySelector('.ego-image-wrapper').style.opacity = '0';
|
||||
} else {
|
||||
// 所有罪人已匹配完成,显示结果
|
||||
showResults();
|
||||
@@ -666,7 +668,7 @@
|
||||
resultImages.className = 'result-images';
|
||||
|
||||
// 尝试加载罪人立绘
|
||||
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
|
||||
const imageExtensions = ['.png'];
|
||||
let sinnerImageFound = false;
|
||||
|
||||
for (const ext of imageExtensions) {
|
||||
|
||||
593
sinner-gallery.html
Normal file
@@ -0,0 +1,593 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>罪人立绘排列</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
|
||||
<style>
|
||||
/* 继承index.html的样式并添加展示页面特定样式 */
|
||||
:root {
|
||||
--primary-color: #ff4d4d;
|
||||
--secondary-color: #ffd700;
|
||||
--bg-color: #121212;
|
||||
--text-color: #e0e0e0;
|
||||
--panel-bg: #1e1e1e;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-x: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: rgba(30, 30, 30, 0.8);
|
||||
border-bottom: 1px solid var(--secondary-color);
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 1.8rem;
|
||||
color: var(--secondary-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
|
||||
border: 2px solid var(--secondary-color);
|
||||
color: var(--secondary-color);
|
||||
padding: 0.5rem 1.5rem;
|
||||
font-family: 'Noto Serif SC', serif;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
clip-path: polygon(10% 0, 100% 0, 100% 90%, 90% 100%, 0 100%, 0 10%);
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: var(--secondary-color);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.gallery-container {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sinner-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.sinner-card {
|
||||
background-color: rgba(30, 30, 30, 0.8);
|
||||
border: 2px solid rgba(255, 215, 0, 0.3);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sinner-card:hover {
|
||||
transform: translateY(-5px);
|
||||
border-color: var(--secondary-color);
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.sinner-card-img {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
object-fit: contain;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.sinner-card-info {
|
||||
padding: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sinner-name {
|
||||
font-size: 1.2rem;
|
||||
color: var(--secondary-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sinner-source {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-color);
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/* 罪人立绘排序界面 */
|
||||
.sorting-container {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.sorting-container.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.sorting-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.sorting-title {
|
||||
font-size: 1.5rem;
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
|
||||
.sorting-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
gap: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sorting-left {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sorting-right {
|
||||
flex: 1;
|
||||
background-color: rgba(30, 30, 30, 0.8);
|
||||
border: 2px solid rgba(255, 215, 0, 0.3);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sorting-right-header {
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid rgba(255, 215, 0, 0.3);
|
||||
text-align: center;
|
||||
color: var(--secondary-color);
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.sorting-right-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sorting-right-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.sorting-categories {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.sorting-category {
|
||||
background-color: rgba(30, 30, 30, 0.8);
|
||||
border: 2px solid rgba(255, 215, 0, 0.3);
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
min-height: 150px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.sorting-category.drag-over {
|
||||
border-color: var(--secondary-color);
|
||||
background-color: rgba(255, 215, 0, 0.1);
|
||||
}
|
||||
|
||||
.sorting-category-title {
|
||||
font-size: 1.2rem;
|
||||
color: var(--secondary-color);
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sorting-category-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.sorting-images {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
padding: 15px;
|
||||
background-color: rgba(30, 30, 30, 0.5);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.sorting-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
object-fit: cover;
|
||||
border: 2px solid rgba(255, 215, 0, 0.3);
|
||||
border-radius: 5px;
|
||||
cursor: grab;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.sorting-image:hover {
|
||||
border-color: var(--secondary-color);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.sorting-image:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.sorting-image.dragging {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.sorting-image-small {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
object-fit: cover;
|
||||
border: 2px solid rgba(255, 215, 0, 0.3);
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.sorting-image-small:hover {
|
||||
border-color: var(--secondary-color);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.sinner-cards {
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
}
|
||||
|
||||
.sinner-card-img {
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.sorting-content {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sorting-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sorting-right {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">罪人立绘排列</h1>
|
||||
<button class="back-btn" onclick="window.location.href='index.html'">
|
||||
<i class="fas fa-arrow-left"></i> 返回
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="gallery-container">
|
||||
<div class="sinner-cards" id="sinner-cards">
|
||||
<!-- 罪人卡片将通过JavaScript动态生成 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 罪人立绘排序界面 -->
|
||||
<div class="sorting-container" id="sorting-container">
|
||||
<div class="sorting-header">
|
||||
<h2 class="sorting-title" id="sorting-title">罪人立绘排序</h2>
|
||||
<button class="back-btn" onclick="closeSorting()">
|
||||
<i class="fas fa-arrow-left"></i> 返回
|
||||
</button>
|
||||
</div>
|
||||
<div class="sorting-content">
|
||||
<div class="sorting-left">
|
||||
<div class="sorting-categories">
|
||||
<div class="sorting-category" data-category="夯">
|
||||
<div class="sorting-category-title">夯</div>
|
||||
<div class="sorting-category-content"></div>
|
||||
</div>
|
||||
<div class="sorting-category" data-category="顶级">
|
||||
<div class="sorting-category-title">顶级</div>
|
||||
<div class="sorting-category-content"></div>
|
||||
</div>
|
||||
<div class="sorting-category" data-category="人上人">
|
||||
<div class="sorting-category-title">人上人</div>
|
||||
<div class="sorting-category-content"></div>
|
||||
</div>
|
||||
<div class="sorting-category" data-category="npc">
|
||||
<div class="sorting-category-title">NPC</div>
|
||||
<div class="sorting-category-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sorting-images" id="sorting-images">
|
||||
<!-- 罪人立绘将通过JavaScript动态生成 -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="sorting-right">
|
||||
<div class="sorting-right-header">立绘预览</div>
|
||||
<div class="sorting-right-content">
|
||||
<img src="" alt="" class="sorting-right-image" id="sorting-right-image">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 罪人数据,与matching-game.html保持一致
|
||||
const gameData = [
|
||||
{ id: 1, sinner: "李箱", source: "《李箱》", imgName: "yisang", egoImgName: "yi_sang_ego" },
|
||||
{ id: 2, sinner: "浮士德", source: "《浮士德》", imgName: "faust", egoImgName: "faust_ego" },
|
||||
{ id: 3, sinner: "堂吉诃德", source: "《堂吉诃德》", imgName: "don_quixote", egoImgName: "don_quixote_ego" },
|
||||
{ id: 4, sinner: "良秀", source: "《地狱变》", imgName: "yoshihide", egoImgName: "yoshihide_ego" },
|
||||
{ id: 5, sinner: "默尔索", source: "《局外人》", imgName: "meursault", egoImgName: "meursault_ego" },
|
||||
{ id: 6, sinner: "鸿璐", source: "《红楼梦》", imgName: "honglu", egoImgName: "honglu_ego" },
|
||||
{ id: 7, sinner: "希斯克利夫", source: "《呼啸山庄》", imgName: "heathcliff", egoImgName: "heathcliff_ego" },
|
||||
{ id: 8, sinner: "以实玛利", source: "《白鲸》", imgName: "ishmael", egoImgName: "ishmael_ego" },
|
||||
{ id: 9, sinner: "罗佳", source: "《罪与罚》", imgName: "rodya", egoImgName: "rodya_ego" },
|
||||
{ id: 11, sinner: "辛克莱", source: "《德米安》", imgName: "sinclair", egoImgName: "sinclair_ego" },
|
||||
{ id: 12, sinner: "奥提斯", source: "《奥德修斯》", imgName: "outis", egoImgName: "outis_ego" },
|
||||
{ id: 13, sinner: "格里高尔", source: "《变形记》", imgName: "gregor", egoImgName: "gregor_ego" },
|
||||
];
|
||||
|
||||
// 初始化页面
|
||||
function initPage() {
|
||||
// 生成罪人卡片
|
||||
generateSinnerCards();
|
||||
}
|
||||
|
||||
// 生成罪人卡片
|
||||
function generateSinnerCards() {
|
||||
const sinnerCards = document.getElementById('sinner-cards');
|
||||
sinnerCards.innerHTML = '';
|
||||
|
||||
gameData.forEach(sinner => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'sinner-card';
|
||||
card.dataset.id = sinner.id;
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = `images/sinners/${sinner.imgName}.png`;
|
||||
img.alt = sinner.sinner;
|
||||
img.className = 'sinner-card-img';
|
||||
|
||||
// 如果图片加载失败,显示默认图标
|
||||
img.onerror = function() {
|
||||
this.style.display = 'none';
|
||||
const icon = document.createElement('i');
|
||||
icon.className = 'fas fa-user';
|
||||
icon.style.fontSize = '100px';
|
||||
icon.style.color = 'var(--secondary-color)';
|
||||
this.parentNode.insertBefore(icon, this);
|
||||
};
|
||||
|
||||
const info = document.createElement('div');
|
||||
info.className = 'sinner-card-info';
|
||||
|
||||
const name = document.createElement('h3');
|
||||
name.className = 'sinner-name';
|
||||
name.textContent = sinner.sinner;
|
||||
|
||||
const source = document.createElement('div');
|
||||
source.className = 'sinner-source';
|
||||
source.textContent = sinner.source;
|
||||
|
||||
info.appendChild(name);
|
||||
info.appendChild(source);
|
||||
|
||||
card.appendChild(img);
|
||||
card.appendChild(info);
|
||||
|
||||
// 添加点击事件,打开立绘排序界面
|
||||
card.addEventListener('click', () => openSorting(sinner));
|
||||
|
||||
sinnerCards.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
// 打开立绘排序界面
|
||||
function openSorting(sinner) {
|
||||
const sortingContainer = document.getElementById('sorting-container');
|
||||
const sortingTitle = document.getElementById('sorting-title');
|
||||
const sortingImages = document.getElementById('sorting-images');
|
||||
|
||||
// 隐藏罪人卡片,显示排序界面
|
||||
document.querySelector('.gallery-container').style.display = 'none';
|
||||
sortingContainer.classList.add('active');
|
||||
|
||||
// 设置标题
|
||||
sortingTitle.textContent = `${sinner.sinner} 立绘排序`;
|
||||
|
||||
// 清空之前的立绘
|
||||
sortingImages.innerHTML = '';
|
||||
|
||||
// 清空分类中的立绘
|
||||
document.querySelectorAll('.sorting-category-content').forEach(content => {
|
||||
content.innerHTML = '';
|
||||
});
|
||||
|
||||
// 加载罪人的所有人格立绘
|
||||
loadSinnerPersonalities(sinner);
|
||||
}
|
||||
|
||||
// 加载罪人的所有人格立绘
|
||||
async function loadSinnerPersonalities(sinner) {
|
||||
const sortingImages = document.getElementById('sorting-images');
|
||||
|
||||
try {
|
||||
// 加载 JSON 索引文件
|
||||
const response = await fetch('images/sinner_images.json');
|
||||
const sinnerData = await response.json();
|
||||
|
||||
// 查找当前罪人的图片数据
|
||||
const currentSinner = sinnerData.find(item => item.name === sinner.imgName);
|
||||
|
||||
if (currentSinner && currentSinner.images && currentSinner.images.length > 0) {
|
||||
// 为每个人格立绘创建可拖动的图片元素
|
||||
currentSinner.images.forEach((personality, index) => {
|
||||
const img = document.createElement('img');
|
||||
img.src = personality.path;
|
||||
img.alt = personality.name;
|
||||
img.className = 'sorting-image';
|
||||
img.dataset.id = index + 1;
|
||||
img.dataset.name = personality.name;
|
||||
img.draggable = true;
|
||||
|
||||
// 如果图片加载失败,显示默认图标
|
||||
img.onerror = function() {
|
||||
this.style.display = 'none';
|
||||
const icon = document.createElement('i');
|
||||
icon.className = 'fas fa-user';
|
||||
icon.style.fontSize = '80px';
|
||||
icon.style.color = 'var(--secondary-color)';
|
||||
this.parentNode.insertBefore(icon, this);
|
||||
};
|
||||
|
||||
// 添加拖动事件
|
||||
img.addEventListener('dragstart', handleDragStart);
|
||||
img.addEventListener('dragend', handleDragEnd);
|
||||
|
||||
// 添加点击事件,在右侧显示完整图片
|
||||
img.addEventListener('click', () => showFullImage(personality.path));
|
||||
|
||||
sortingImages.appendChild(img);
|
||||
});
|
||||
} else {
|
||||
// 如果没有找到图片,显示提示信息
|
||||
const errorMsg = document.createElement('div');
|
||||
errorMsg.className = 'error-message';
|
||||
errorMsg.textContent = `未找到 ${sinner.sinner} 的立绘图片`;
|
||||
sortingImages.appendChild(errorMsg);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载立绘失败:', error);
|
||||
// 显示错误提示
|
||||
const errorMsg = document.createElement('div');
|
||||
errorMsg.className = 'error-message';
|
||||
errorMsg.textContent = '无法加载立绘,请检查图片路径';
|
||||
sortingImages.appendChild(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 显示完整图片
|
||||
function showFullImage(imgSrc) {
|
||||
const fullImage = document.getElementById('sorting-right-image');
|
||||
fullImage.src = imgSrc;
|
||||
}
|
||||
|
||||
// 处理拖动开始
|
||||
function handleDragStart(e) {
|
||||
this.classList.add('dragging');
|
||||
e.dataTransfer.setData('text/plain', this.dataset.id);
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
}
|
||||
|
||||
// 处理拖动结束
|
||||
function handleDragEnd(e) {
|
||||
this.classList.remove('dragging');
|
||||
}
|
||||
|
||||
// 为分类区域添加拖放事件
|
||||
document.querySelectorAll('.sorting-category').forEach(category => {
|
||||
category.addEventListener('dragover', handleDragOver);
|
||||
category.addEventListener('dragleave', handleDragLeave);
|
||||
category.addEventListener('drop', handleDrop);
|
||||
});
|
||||
|
||||
// 处理拖动悬停
|
||||
function handleDragOver(e) {
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'move';
|
||||
this.classList.add('drag-over');
|
||||
}
|
||||
|
||||
// 处理拖动离开
|
||||
function handleDragLeave(e) {
|
||||
this.classList.remove('drag-over');
|
||||
}
|
||||
|
||||
// 处理放置
|
||||
function handleDrop(e) {
|
||||
e.preventDefault();
|
||||
this.classList.remove('drag-over');
|
||||
|
||||
const id = e.dataTransfer.getData('text/plain');
|
||||
const draggedElement = document.querySelector(`.sorting-image[data-id="${id}"]`);
|
||||
|
||||
if (draggedElement) {
|
||||
// 将图片从原位置移动到新位置
|
||||
const categoryContent = this.querySelector('.sorting-category-content');
|
||||
|
||||
// 创建一个新图片元素
|
||||
const newImg = document.createElement('img');
|
||||
newImg.src = draggedElement.src;
|
||||
newImg.alt = draggedElement.alt;
|
||||
newImg.className = 'sorting-image-small';
|
||||
newImg.dataset.id = draggedElement.dataset.id;
|
||||
newImg.dataset.name = draggedElement.dataset.name;
|
||||
|
||||
// 添加点击事件,在右侧显示完整图片
|
||||
newImg.addEventListener('click', () => showFullImage(draggedElement.src));
|
||||
|
||||
// 将新图片添加到分类中
|
||||
categoryContent.appendChild(newImg);
|
||||
|
||||
// 从原位置移除图片
|
||||
draggedElement.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭排序界面
|
||||
function closeSorting() {
|
||||
const sortingContainer = document.getElementById('sorting-container');
|
||||
|
||||
// 显示罪人卡片,隐藏排序界面
|
||||
document.querySelector('.gallery-container').style.display = 'flex';
|
||||
sortingContainer.classList.remove('active');
|
||||
}
|
||||
|
||||
// 初始化页面
|
||||
initPage();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
58
test.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import json
|
||||
|
||||
# 设置基础路径 - 根据你的实际路径修改
|
||||
base_path = "D:/progarm/python/084PlayHtml/images"
|
||||
|
||||
# 定义罪人数据 - 从你的gameData中提取的imgName
|
||||
sinners = [
|
||||
"yisang",
|
||||
"faust",
|
||||
"don_quixote",
|
||||
"yoshihide",
|
||||
"meursault",
|
||||
"honglu",
|
||||
"heathcliff",
|
||||
"ishmael",
|
||||
"rodya",
|
||||
"dante",
|
||||
"sinclair",
|
||||
"outis",
|
||||
"gregor"
|
||||
]
|
||||
|
||||
# 初始化结果列表
|
||||
result = []
|
||||
|
||||
# 遍历每个罪人
|
||||
for sinner in sinners:
|
||||
dir_path = os.path.join(base_path, sinner)
|
||||
|
||||
# 检查目录是否存在
|
||||
if os.path.isdir(dir_path):
|
||||
# 获取目录中的所有PNG图片
|
||||
images = []
|
||||
for file_name in os.listdir(dir_path):
|
||||
if file_name.endswith('.webp'): # 如果不是PNG,修改这里
|
||||
# 计算相对路径
|
||||
relative_path = f"images/{sinner}/{file_name}"
|
||||
|
||||
images.append({
|
||||
"name": os.path.splitext(file_name)[0],
|
||||
"path": relative_path
|
||||
})
|
||||
|
||||
# 添加到结果列表
|
||||
result.append({
|
||||
"name": sinner,
|
||||
"images": images
|
||||
})
|
||||
else:
|
||||
print(f"警告: 目录不存在: {dir_path}")
|
||||
|
||||
# 保存为JSON文件
|
||||
json_path = os.path.join(base_path, "sinner_images.json")
|
||||
with open(json_path, "w", encoding="utf-8") as f:
|
||||
json.dump(result, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"JSON文件已生成: {json_path}")
|
||||