<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>新年模式大闯关</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}
body {
font-family: "Microsoft YaHei", sans-serif;
background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
min-height: 100vh;
overflow: hidden;
}
.game-container {
width: 100vw;
height: 100vh;
max-width: 500px;
margin: 0 auto;
position: relative;
overflow: hidden;
}
.intro-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%);
z-index: 100;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px;
transition: opacity 1s, transform 1s;
}
.intro-screen.hidden {
opacity: 0;
pointer-events: none;
}
.intro-title {
font-size: 2.4rem;
color: #d62828;
margin-bottom: 20px;
text-shadow: 3px 3px 0 #ffde59;
animation: bounce 2s infinite;
}
.intro-subtitle {
font-size: 1.2rem;
color: #333;
margin-bottom: 30px;
max-width: 90%;
}
.family-scene {
width: 90%;
height: 180px;
background-color: #f8f4e3;
border-radius: 20px;
position: relative;
margin-bottom: 30px;
border: 5px solid #ffb4a2;
overflow: hidden;
}
.family-character {
position: absolute;
width: 70px;
height: 110px;
bottom: 0;
border-radius: 12px 12px 0 0;
}
.dad {
left: 15%;
background-color: #8ecae6;
}
.mom {
left: 38%;
background-color: #ffafcc;
}
.child {
left: 62%;
background-color: #ffc300;
}
.speech-bubble {
position: absolute;
background-color: #fff;
border-radius: 20px;
padding: 12px;
font-size: 1rem;
max-width: 65%;
box-shadow: 2px 2px 4px rgba(0,0,0,0.1);
}
.dad-speech {
top: 10px;
left: 8%;
}
.child-speech {
top: 50px;
right: 8%;
}
.start-button {
background: linear-gradient(to right, #ff416c, #ff4b2b);
color: white;
border: none;
padding: 14px 36px;
font-size: 1.4rem;
border-radius: 50px;
cursor: pointer;
box-shadow: 0 8px 16px rgba(255, 65, 108, 0.3);
transition: all 0.25s;
font-weight: bold;
}
.start-button:active {
transform: scale(0.94);
}
.game-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
flex-direction: column;
}
.game-screen.active {
display: flex;
}
.header {
background-color: #d62828;
color: #fff;
padding:14px;
display:flex;
justify-content:space-between;
align-items:center;
box-shadow:0 4px 8px rgba(0,0,0,0.12);
z-index:10;
}
.level-title {
font-size:1.3rem;
font-weight:bold;
}
.level-indicator {
font-size:1.1rem;
background:rgba(255,255,255,0.22);
padding:4px 12px;
border-radius:18px;
}
.game-area {
flex:1;
padding:16px;
overflow:hidden;
position:relative;
}
.instructions {
background:rgba(255,255,255,0.9);
border-radius:18px;
padding:14px;
margin-bottom:16px;
font-size:1.1rem;
line-height:1.4;
text-align:center;
box-shadow:0 4px 12px rgba(0,0,0,0.1);
border:3px dashed #ffb703;
}
.pattern-area {
background:rgba(255,255,255,0.72);
border-radius:18px;
padding:18px;
margin-bottom:16px;
min-height:140px;
display:flex;
align-items:center;
justify-content:center;
box-shadow:0 4px 12px rgba(0,0,0,0.1);
border:3px solid #219ebc;
}
.pattern-example {
display:flex;
justify-content:center;
align-items:center;
flex-wrap:wrap;
gap:10px;
}
.pattern-item {
width:76px;
height:76px;
border-radius:14px;
display:flex;
justify-content:center;
align-items:center;
font-size:2rem;
box-shadow:0 4px 10px rgba(0,0,0,0.1);
cursor:pointer;
transition:all 0.25s;
position:relative;
}
.pattern-item:active {
transform:scale(0.92);
}
.pattern-item.highlight {
animation:pulse 1s infinite;
}
.pattern-item.completed {
opacity:1;
}
.pattern-item.empty {
background:rgba(255,255,255,0.5);
border:3px dashed #888;
}
.selection-area {
background:rgba(255,255,255,0.72);
border-radius:18px;
padding:18px;
display:flex;
justify-content:center;
align-items:center;
flex-wrap:wrap;
gap:14px;
box-shadow:0 4px 12px rgba(0,0,0,0.1);
border:3px solid #fb8500;
}
.selection-item {
width:84px;
height:84px;
border-radius:18px;
display:flex;
justify-content:center;
align-items:center;
font-size:2.3rem;
box-shadow:0 6px 12px rgba(0,0,0,0.1);
cursor:pointer;
transition:all 0.25s;
}
.selection-item:active {
transform:scale(0.92);
}
.control-area {
padding:14px;
display:flex;
justify-content:space-between;
}
.control-button {
color:#fff;
border:none;
padding:11px 20px;
font-size:1.1rem;
border-radius:14px;
cursor:pointer;
box-shadow:0 4px 8px rgba(0,0,0,0.2);
transition:all 0.25s;
}
.control-button:active {
transform:scale(0.94);
}
.hint {
background:linear-gradient(to right,#ffb703,#fb8500);
}
.reset {
background:linear-gradient(to right,#8ecae6,#219ebc);
}
.next {
background:linear-gradient(to right,#9ef01a,#38b000);
}
.next:disabled {
background:#aaa;
cursor:not-allowed;
}
.feedback {
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
background:rgba(255,255,255,0.96);
padding:26px;
border-radius:20px;
text-align:center;
z-index:50;
display:none;
box-shadow:0 12px 24px rgba(0,0,0,0.2);
border:5px solid #ffb703;
width:82%;
}
.feedback.show {
display:block;
animation:popIn 0.5s;
}
.feedback-icon {
font-size:3.6rem;
margin-bottom:16px;
}
.feedback-text {
font-size:1.4rem;
margin-bottom:18px;
}
.feedback-close {
background:linear-gradient(to right,#ff416c,#ff4b2b);
color:#fff;
border:none;
padding:11px 26px;
font-size:1.2rem;
border-radius:14px;
cursor:pointer;
}
.celebration {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:40;
display:none;
pointer-events:none;
}
.celebration.active {
display:block;
}
.confetti {
position:absolute;
width:14px;
height:14px;
top:-20px;
border-radius:50%;
}
@keyframes bounce {
0%,100%{transform:translateY(0);}
50%{transform:translateY(-18px);}
}
@keyframes pulse {
0%{transform:scale(1);box-shadow:0 4px 10px rgba(0,0,0,0.1);}
50%{transform:scale(1.1);box-shadow:0 8px 18px rgba(0,0,0,0.2);}
100%{transform:scale(1);box-shadow:0 4px 10px rgba(0,0,0,0.1);}
}
@keyframes popIn {
0%{transform:translate(-50%,-50%) scale(0.5);opacity:0;}
100%{transform:translate(-50%,-50%) scale(1);opacity:1;}
}
@media (max-height:680px) {
.pattern-item,.selection-item {
width:64px;height:64px;
}
.instructions {
font-size:1rem;padding:10px;
}
}
@media (max-width:380px) {
.pattern-item,.selection-item {
width:58px;height:58px;
}
.control-button {
padding:9px 12px;font-size:0.95rem;
}
}
</style>
</head>
<body>
<div class="game-container">
<div class="intro-screen" id="introScreen">
<h1 class="intro-title">新年模式大闯关</h1>
<p class="intro-subtitle">小小设计师,快来帮忙布置客厅,找出装饰品排队的小秘密!</p>
<div class="family-scene">
<div class="family-character dad"></div>
<div class="family-character mom"></div>
<div class="family-character child"></div>
<div class="speech-bubble dad-speech">新年到,我们需要一位小小设计师!</div>
<div class="speech-bubble child-speech">我来!我能发现排列的小秘密!</div>
</div>
<button class="start-button" id="startButton">开始游戏</button>
</div>
<div class="game-screen" id="gameScreen">
<div class="header">
<div class="level-title" id="levelTitle"></div>
<div class="level-indicator" id="levelIndicator"></div>
</div>
<div class="game-area">
<div class="instructions" id="instructions"></div>
<div class="pattern-area">
<div class="pattern-example" id="patternExample"></div>
</div>
<div class="selection-area" id="selectionArea"></div>
<div class="control-area">
<button class="control-button hint" id="hintButton">提示</button>
<button class="control-button reset" id="resetButton">重试</button>
<button class="control-button next" id="nextButton" disabled>下一关</button>
</div>
</div>
</div>
<div class="feedback" id="feedback">
<div class="feedback-icon" id="feedbackIcon">🎉</div>
<div class="feedback-text" id="feedbackText"></div>
<button class="feedback-close" id="feedbackClose">继续</button>
</div>
<div class="celebration" id="celebration"></div>
</div>
<script>
const gameState = {
currentLevel: 0,
totalLevels: 5,
selectedItem: null,
levels: [
{
title: "热身关 - 规律初体验",
pattern: ["福", "灯笼", "福", "灯笼", "福", "灯笼"],
answer: [],
options: [],
instruction: "点击图案,看一看它们排队的小秘密!"
},
{
title: "挂灯笼",
pattern: ["红圆灯笼", "金方灯笼", "红圆灯笼", "金方灯笼", "", ""],
answer: ["红圆灯笼", "金方灯笼"],
options: ["红圆灯笼", "金方灯笼", "蓝圆灯笼"],
instruction: "按照前面的规律,把空缺的灯笼补充完整。"
},
{
title: "摆果盘",
pattern: ["苹果", "橘子", "苹果", "橘子", "苹果", ""],
answer: ["橘子"],
options: ["苹果", "橘子", "香蕉"],
instruction: "观察水果规律,选出正确水果放到空格。"
},
{
title: "贴福字",
pattern: ["大福", "大福", "小福", "", "", ""],
answer: ["大福", "大福", "小福"],
options: ["大福", "小福"],
instruction: "按照AAB规律,把福字贴到空白位置。"
},
{
title: "设计鞭炮串",
pattern: ["", "", "", "", "", ""],
answer: [],
options: ["红鞭炮", "黄鞭炮"],
instruction: "自由摆放鞭炮,创造属于你的排列规律!"
}
]
};
const iconMap = {
"福": "🪔",
"灯笼": "🏮",
"红圆灯笼": "🔴",
"金方灯笼": "🟨",
"蓝圆灯笼": "🔵",
"大福": "🪔",
"小福": "🧧",
"苹果": "🍎",
"橘子": "🍊",
"香蕉": "🍌",
"红鞭炮": "🧨",
"黄鞭炮": "🎇"
};
const colorMap = {
"福": "#d62828",
"灯笼": "#ff9e00",
"红圆灯笼": "#e63946",
"金方灯笼": "#ffd166",
"蓝圆灯笼": "#457b9d",
"大福": "#d62828",
"小福": "#f77f00",
"苹果": "#e63946",
"橘子": "#f4a261",
"香蕉": "#ffd166",
"红鞭炮": "#e63946",
"黄鞭炮": "#ffd166"
};
const introScreen = document.getElementById("introScreen");
const gameScreen = document.getElementById("gameScreen");
const startButton = document.getElementById("startButton");
const patternExample = document.getElementById("patternExample");
const selectionArea = document.getElementById("selectionArea");
const instructions = document.getElementById("instructions");
const hintButton = document.getElementById("hintButton");
const resetButton = document.getElementById("resetButton");
const nextButton = document.getElementById("nextButton");
const feedback = document.getElementById("feedback");
const feedbackIcon = document.getElementById("feedbackIcon");
const feedbackText = document.getElementById("feedbackText");
const feedbackClose = document.getElementById("feedbackClose");
const celebration = document.getElementById("celebration");
const levelTitle = document.getElementById("levelTitle");
const levelIndicator = document.getElementById("levelIndicator");
document.addEventListener("DOMContentLoaded", init);
function init(){
startButton.addEventListener("click",startGame);
hintButton.addEventListener("click",showHint);
resetButton.addEventListener("click",()=>loadLevel(gameState.currentLevel));
nextButton.addEventListener("click",nextLevel);
feedbackClose.addEventListener("click",()=>feedback.classList.remove("show"));
loadLevel(0);
}
function startGame(){
introScreen.classList.add("hidden");
setTimeout(()=>{
gameScreen.classList.add("active");
showFeedback("欢迎小小设计师!","👋","找出装饰品排队的秘密吧!");
},800);
}
function loadLevel(levelIdx){
gameState.currentLevel = levelIdx;
gameState.selectedItem = null;
const lv = gameState.levels[levelIdx];
levelTitle.innerText = lv.title;
levelIndicator.innerText = `关卡 ${levelIdx+1}/${gameState.totalLevels}`;
instructions.innerText = lv.instruction;
patternExample.innerHTML = "";
selectionArea.innerHTML = "";
nextButton.disabled = true;
lv.pattern.forEach((item,idx)=>{
const div = document.createElement("div");
div.className = "pattern-item";
if(item){
div.innerText = iconMap[item];
div.style.backgroundColor = colorMap[item];
if(levelIdx === 0){
div.onclick = ()=>{
div.style.transform = "scale(1.3)";
setTimeout(()=>div.style.transform="scale(1)",500);
if(idx === lv.pattern.length-1){
setTimeout(()=>completeLevel(),700);
}
}
}
}else{
div.classList.add("empty");
const ansIndex = idx - (lv.pattern.length - lv.answer.length);
if(ansIndex >=0 && ansIndex < lv.answer.length){
div.dataset.expect = lv.answer[ansIndex];
}
div.onclick = function(){
if(!gameState.selectedItem){
showFeedback("提示","💡","先在下方选一个物品哦!");
return;
}
const val = gameState.selectedItem;
if(gameState.currentLevel === 4){
div.classList.remove("empty");
div.innerText = iconMap[val];
div.style.backgroundColor = colorMap[val];
gameState.selectedItem = null;
checkComplete();
}else{
const expect = this.dataset.expect;
if(expect === val){
this.classList.remove("empty");
this.innerText = iconMap[val];
this.style.backgroundColor = colorMap[val];
gameState.selectedItem = null;
checkComplete();
}else{
showFeedback("再试一试🤔","❌","观察前面的排列规律");
gameState.selectedItem = null;
}
}
}
}
patternExample.appendChild(div);
});
if(lv.options && lv.options.length>0){
lv.options.forEach(opt=>{
const div = document.createElement("div");
div.className = "selection-item";
div.innerText = iconMap[opt];
div.style.backgroundColor = colorMap[opt];
div.onclick = ()=>{
gameState.selectedItem = opt;
showFeedback("选好了!","👆","点击上方空白格子放进去");
};
selectionArea.appendChild(div);
})
}
}
function checkComplete(){
const empty = patternExample.querySelectorAll(".pattern-item.empty");
if(empty.length === 0){
completeLevel();
}
}
function completeLevel(){
createConfetti();
let msg = "";
if(gameState.currentLevel === gameState.totalLevels -1){
msg = "恭喜你!你已经完成所有关卡,成为规律小专家!";
}else{
msg = "你真是聪明的小小设计师!";
}
showFeedback("恭喜过关!","🌟",msg);
nextButton.disabled = false;
}
function nextLevel(){
if(gameState.currentLevel < gameState.totalLevels -1){
loadLevel(gameState.currentLevel + 1);
}else{
showFeedback("全部通关!","🏆","太棒啦!你掌握了排列规律!");
}
}
function showHint(){
const emptyItems = patternExample.querySelectorAll(".pattern-item.empty");
if(emptyItems.length === 0) return;
emptyItems[0].classList.add("highlight");
setTimeout(()=>emptyItems[0].classList.remove("highlight"),1500);
if(gameState.currentLevel ===0){
showFeedback("提示","💡","观察福和灯笼,轮流出现!");
}else{
const exp = emptyItems[0].dataset.expect;
if(exp){
showFeedback("提示","💡","这里应该放:"+iconMap[exp]);
}
}
}
function showFeedback(title,icon,text){
feedbackIcon.innerText = icon;
feedbackText.innerHTML = `<strong>${title}</strong><br>${text}`;
feedback.classList.add("show");
}
function createConfetti(){
celebration.classList.add("active");
celebration.innerHTML = "";
const colors = ["#e63946","#f4a261","#2a9d8f","#ffd166"];
for(let i=0;i<50;i++){
const c = document.createElement("div");
c.className = "confetti";
c.style.left = Math.random()*100 +"%";
c.style.backgroundColor = colors[Math.floor(Math.random()*colors.length)];
celebration.appendChild(c);
const fall = setInterval(()=>{
let top = parseFloat(c.style.top||0);
top += 3;
c.style.top = top +"px";
if(top>window.innerHeight){
clearInterval(fall);
c.remove();
}
},30);
}
setTimeout(()=>celebration.classList.remove("active"),3000);
}
</script>
</body>
</html>