11.9 脚本网页 消消乐

社畜没时间,有时间弄个公共资源脚本,

  1. 记录所有游戏运行状态

  2. python脚本为所有游戏自动引入资源,例如背景妹妹图片,音效

现在是30多个游戏加起来不到1M. termux直接部署

  1. 万能轻量公共部分,搜索按钮,界面放大按钮,适配手机旋转等等 ,有时间再说

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<title>简单消消乐</title>

<style>

* {

box-sizing: border-box;

-webkit-tap-highlight-color: transparent;

}

body {

margin: 0;

padding: 10px;

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Microsoft YaHei", sans-serif;

display: flex;

justify-content: center;

align-items: center;

min-height: 100vh;

transition: background 0.5s ease;

background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

}

.game-container {

background: rgba(255, 255, 255, 0.95);

backdrop-filter: blur(10px);

border-radius: 20px;

padding: 20px;

box-shadow: 0 10px 40px rgba(0,0,0,0.2);

text-align: center;

max-width: 600px;

width: 100%;

animation: slideIn 0.5s ease;

}

@keyframes slideIn {

from {

opacity: 0;

transform: translateY(-20px);

}

to {

opacity: 1;

transform: translateY(0);

}

}

h1 {

color: #333;

margin-bottom: 15px;

font-size: clamp(24px, 5vw, 36px);

background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

-webkit-background-clip: text;

-webkit-text-fill-color: transparent;

background-clip: text;

}

.controls {

display: flex;

justify-content: center;

gap: 15px;

margin-bottom: 20px;

flex-wrap: wrap;

}

.info-container {

display: flex;

justify-content: center;

gap: 20px;

margin-bottom: 20px;

flex-wrap: wrap;

}

.info-box {

background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);

padding: 12px 20px;

border-radius: 15px;

font-size: clamp(14px, 3vw, 18px);

color: #555;

box-shadow: 0 4px 15px rgba(0,0,0,0.1);

transition: transform 0.3s ease;

}

.info-box:hover {

transform: translateY(-2px);

}

.info-box span {

font-weight: bold;

color: #333;

font-size: clamp(16px, 3.5vw, 20px);

}

#game-board {

display: grid;

grid-template-columns: repeat(8, 1fr);

grid-template-rows: repeat(8, 1fr);

gap: 4px;

margin: 0 auto 20px;

padding: 10px;

background: rgba(255, 255, 255, 0.5);

border-radius: 15px;

max-width: 500px;

aspect-ratio: 1;

}

.tile {

width: 100%;

height: 100%;

border-radius: 10px;

cursor: pointer;

display: flex;

align-items: center;

justify-content: center;

font-size: clamp(20px, 4vw, 35px);

transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);

user-select: none;

box-shadow: 0 2px 8px rgba(0,0,0,0.15);

position: relative;

overflow: hidden;

}

.tile::before {

content: '';

position: absolute;

top: 0;

left: 0;

right: 0;

bottom: 0;

background: linear-gradient(135deg, rgba(255,255,255,0.3) 0%, rgba(255,255,255,0) 100%);

opacity: 0;

transition: opacity 0.3s ease;

}

.tile:hover::before {

opacity: 1;

}

.tile:hover {

transform: scale(1.08) rotate(2deg);

box-shadow: 0 6px 20px rgba(0,0,0,0.25);

z-index: 10;

}

.tile.selected {

border: 3px solid #4CAF50;

transform: scale(1.12);

box-shadow: 0 0 20px rgba(76, 175, 80, 0.6);

animation: pulse 0.6s infinite;

}

@keyframes pulse {

0%, 100% {

transform: scale(1.12);

}

50% {

transform: scale(1.15);

}

}

.tile.matched {

animation: disappear 0.6s ease-out forwards;

}

@keyframes disappear {

0% {

transform: scale(1) rotate(0deg);

opacity: 1;

}

50% {

transform: scale(1.2) rotate(180deg);

}

100% {

transform: scale(0) rotate(360deg);

opacity: 0;

}

}

.button-group {

display: flex;

justify-content: center;

gap: 15px;

flex-wrap: wrap;

}

.game-button {

background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

color: white;

border: none;

padding: 12px 25px;

font-size: clamp(14px, 3vw, 18px);

border-radius: 25px;

cursor: pointer;

transition: all 0.3s ease;

box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);

position: relative;

overflow: hidden;

}

.game-button::before {

content: '';

position: absolute;

top: 50%;

left: 50%;

width: 0;

height: 0;

border-radius: 50%;

background: rgba(255, 255, 255, 0.3);

transform: translate(-50%, -50%);

transition: width 0.6s, height 0.6s;

}

.game-button:hover::before {

width: 300px;

height: 300px;

}

.game-button:hover {

transform: translateY(-3px);

box-shadow: 0 6px 20px rgba(102, 126, 234, 0.5);

}

.game-button:active {

transform: translateY(-1px);

}

.theme-button {

background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);

box-shadow: 0 4px 15px rgba(240, 147, 251, 0.4);

}

.theme-button:hover {

box-shadow: 0 6px 20px rgba(240, 147, 251, 0.5);

}

/* 水果颜色主题 */

.fruit-1 {

background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%);

}

.fruit-2 {

background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);

}

.fruit-3 {

background: linear-gradient(135deg, #d299c2 0%, #fef9d7 100%);

}

.fruit-4 {

background: linear-gradient(135deg, #89f7fe 0%, #66a6ff 100%);

}

.fruit-5 {

background: linear-gradient(135deg, #fddb92 0%, #d1fdff 100%);

}

/* 响应式设计 */

@media (max-width: 600px) {

body {

padding: 5px;

}

.game-container {

padding: 15px;

border-radius: 15px;

}

#game-board {

gap: 3px;

padding: 8px;

}

.tile {

border-radius: 8px;

}

}

@media (max-width: 400px) {

#game-board {

gap: 2px;

padding: 5px;

}

}

/* 特效动画 */

.score-animation {

position: fixed;

font-size: 24px;

font-weight: bold;

color: #4CAF50;

pointer-events: none;

animation: scoreFloat 1s ease-out forwards;

z-index: 1000;

}

@keyframes scoreFloat {

0% {

opacity: 1;

transform: translateY(0);

}

100% {

opacity: 0;

transform: translateY(-50px);

}

}

</style>

</head>

<body>

<div class="game-container">

<h1>🎮 简单消消乐 🎮</h1>

<div class="controls">

<button class="game-button theme-button" onclick="changeTheme()">

🎨 切换主题

</button>

</div>

<div class="info-container">

<div class="info-box">

🏆 得分: <span id="score">0</span>

</div>

<div class="info-box">

🎯 移动次数: <span id="moves">0</span>

</div>

</div>

<div id="game-board"></div>

<div class="button-group">

<button class="game-button" onclick="resetGame()">

🔄 重新开始

</button>

<button class="game-button" onclick="showHint()">

💡 提示

</button>

</div>

</div>

<script>

const BOARD_SIZE = 8;

const FRUIT_TYPES = 5;

const FRUITS = ['🍎', '🍊', '🍇', '🍓', '🍑'];

// 背景主题

const THEMES = [

'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',

'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',

'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',

'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',

'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',

'linear-gradient(135deg, #30cfd0 0%, #330867 100%)',

'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)',

'linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)',

'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',

'linear-gradient(135deg, #ff6e7f 0%, #bfe9ff 100%)',

'linear-gradient(135deg, #e0c3fc 0%, #8ec5fc 100%)',

'linear-gradient(135deg, #f8b195 0%, #c06c84 100%)',

'linear-gradient(135deg, #bdc3c7 0%, #2c3e50 100%)',

'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',

'linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)'

];

let currentThemeIndex = 0;

let board = [];

let score = 0;

let moves = 0;

let selectedTile = null;

let isProcessing = false;

function initBoard() {

board = [];

for (let i = 0; i < BOARD_SIZE; i++) {

board[i] = [];

for (let j = 0; j < BOARD_SIZE; j++) {

board[i][j] = Math.floor(Math.random() * FRUIT_TYPES);

}

}

// 确保初始棋盘没有已经匹配的

while (checkMatches().length > 0) {

removeMatches();

fillBoard();

}

}

function renderBoard() {

const gameBoard = document.getElementById('game-board');

gameBoard.innerHTML = '';

for (let i = 0; i < BOARD_SIZE; i++) {

for (let j = 0; j < BOARD_SIZE; j++) {

const tile = document.createElement('div');

tile.className = `tile fruit-${board[i][j] + 1}`;

tile.textContent = FRUITS[board[i][j]];

tile.dataset.row = i;

tile.dataset.col = j;

tile.onclick = () => handleTileClick(i, j);

gameBoard.appendChild(tile);

}

}

}

function handleTileClick(row, col) {

if (isProcessing) return;

const clickedTile = document.querySelector(`[data-row="{row}"\]\[data-col="{col}"]`);

if (!selectedTile) {

selectedTile = { row, col, element: clickedTile };

clickedTile.classList.add('selected');

} else {

const prevRow = selectedTile.row;

const prevCol = selectedTile.col;

// 检查是否相邻

if (isAdjacent(prevRow, prevCol, row, col)) {

isProcessing = true;

swapTiles(prevRow, prevCol, row, col);

moves++;

document.getElementById('moves').textContent = moves;

setTimeout(() => {

const matches = checkMatches();

if (matches.length > 0) {

handleMatches();

} else {

// 如果没有匹配,交换回来

swapTiles(prevRow, prevCol, row, col);

isProcessing = false;

}

}, 300);

} else {

// 如果不相邻,选择新的方块

selectedTile.element.classList.remove('selected');

selectedTile = { row, col, element: clickedTile };

clickedTile.classList.add('selected');

}

}

}

function isAdjacent(row1, col1, row2, col2) {

return (Math.abs(row1 - row2) === 1 && col1 === col2) ||

(Math.abs(col1 - col2) === 1 && row1 === row2);

}

function swapTiles(row1, col1, row2, col2) {

const temp = board[row1][col1];

board[row1][col1] = board[row2][col2];

board[row2][col2] = temp;

renderBoard();

}

function checkMatches() {

const matches = [];

// 检查横向匹配

for (let i = 0; i < BOARD_SIZE; i++) {

for (let j = 0; j < BOARD_SIZE - 2; j++) {

if (board[i][j] !== -1 &&

board[i][j] === board[i][j + 1] &&

board[i][j] === board[i][j + 2]) {

let matchLength = 3;

while (j + matchLength < BOARD_SIZE && board[i][j] === board[i][j + matchLength]) {

matchLength++;

}

for (let k = 0; k < matchLength; k++) {

matches.push([i, j + k]);

}

}

}

}

// 检查纵向匹配

for (let i = 0; i < BOARD_SIZE - 2; i++) {

for (let j = 0; j < BOARD_SIZE; j++) {

if (board[i][j] !== -1 &&

board[i][j] === board[i + 1][j] &&

board[i][j] === board[i + 2][j]) {

let matchLength = 3;

while (i + matchLength < BOARD_SIZE && board[i][j] === board[i + matchLength][j]) {

matchLength++;

}

for (let k = 0; k < matchLength; k++) {

matches.push([i + k, j]);

}

}

}

}

// 去重

return [...new Set(matches.map(m => m.join(',')))].map(m => m.split(',').map(Number));

}

function handleMatches() {

const matches = checkMatches();

if (matches.length > 0) {

const points = matches.length * 10;

score += points;

document.getElementById('score').textContent = score;

// 显示得分动画

showScoreAnimation(points);

// 标记匹配的方块

matches.forEach(([row, col]) => {

const tile = document.querySelector(`[data-row="{row}"\]\[data-col="{col}"]`);

if (tile) tile.classList.add('matched');

});

setTimeout(() => {

removeMatches();

fillBoard();

renderBoard();

// 继续检查新的匹配

setTimeout(() => {

if (checkMatches().length > 0) {

handleMatches();

} else {

isProcessing = false;

}

}, 300);

}, 600);

} else {

isProcessing = false;

}

}

function showScoreAnimation(points) {

const scoreEl = document.createElement('div');

scoreEl.className = 'score-animation';

scoreEl.textContent = `+${points}`;

scoreEl.style.left = '50%';

scoreEl.style.top = '50%';

document.body.appendChild(scoreEl);

setTimeout(() => {

scoreEl.remove();

}, 1000);

}

function removeMatches() {

const matches = checkMatches();

matches.forEach(([row, col]) => {

board[row][col] = -1;

});

}

function fillBoard() {

// 方块下落

for (let j = 0; j < BOARD_SIZE; j++) {

let emptyRow = BOARD_SIZE - 1;

for (let i = BOARD_SIZE - 1; i >= 0; i--) {

if (board[i][j] !== -1) {

if (i !== emptyRow) {

board[emptyRow][j] = board[i][j];

board[i][j] = -1;

}

emptyRow--;

}

}

}

// 填充新方块

for (let i = 0; i < BOARD_SIZE; i++) {

for (let j = 0; j < BOARD_SIZE; j++) {

if (board[i][j] === -1) {

board[i][j] = Math.floor(Math.random() * FRUIT_TYPES);

}

}

}

}

function resetGame() {

score = 0;

moves = 0;

selectedTile = null;

isProcessing = false;

document.getElementById('score').textContent = score;

document.getElementById('moves').textContent = moves;

initBoard();

renderBoard();

}

function changeTheme() {

currentThemeIndex = (currentThemeIndex + 1) % THEMES.length;

document.body.style.background = THEMES[currentThemeIndex];

}

function showHint() {

// 查找可能的移动

for (let i = 0; i < BOARD_SIZE; i++) {

for (let j = 0; j < BOARD_SIZE; j++) {

// 检查右边交换

if (j < BOARD_SIZE - 1) {

swapTiles(i, j, i, j + 1);

if (checkMatches().length > 0) {

swapTiles(i, j, i, j + 1);

renderBoard();

// 高亮提示

const tile1 = document.querySelector(`[data-row="{i}"\]\[data-col="{j}"]`);

const tile2 = document.querySelector(`[data-row="{i}"\]\[data-col="{j + 1}"]`);

if (tile1 && tile2) {

tile1.style.animation = 'pulse 1s ease 2';

tile2.style.animation = 'pulse 1s ease 2';

setTimeout(() => {

tile1.style.animation = '';

tile2.style.animation = '';

}, 2000);

}

return;

}

swapTiles(i, j, i, j + 1);

}

// 检查下边交换

if (i < BOARD_SIZE - 1) {

swapTiles(i, j, i + 1, j);

if (checkMatches().length > 0) {

swapTiles(i, j, i + 1, j);

renderBoard();

// 高亮提示

const tile1 = document.querySelector(`[data-row="{i}"\]\[data-col="{j}"]`);

const tile2 = document.querySelector(`[data-row="{i + 1}"\]\[data-col="{j}"]`);

if (tile1 && tile2) {

tile1.style.animation = 'pulse 1s ease 2';

tile2.style.animation = 'pulse 1s ease 2';

setTimeout(() => {

tile1.style.animation = '';

tile2.style.animation = '';

}, 2000);

}

return;

}

swapTiles(i, j, i + 1, j);

}

}

}

}

// 初始化游戏

initBoard();

renderBoard();

// 防止双击缩放

let lastTouchEnd = 0;

document.addEventListener('touchend', function (event) {

const now = (new Date()).getTime();

if (now - lastTouchEnd <= 300) {

event.preventDefault();

}

lastTouchEnd = now;

}, false);

</script>

</body>

</html>

相关推荐
宋哈哈2 小时前
页面水印sdk源码
java·前端·javascript
Kikyo--2 小时前
前端基础面试题(Css,Html,Js,Ts)
前端·javascript·css·typescript·html
火车叼位3 小时前
处理volta切换node版本之后pnpm没有识别的问题
前端·javascript
七号练习生.c3 小时前
JQuery&Ajax
前端·ajax·jquery
FinClip3 小时前
AI时代,金融科技如何落地“对话就能办业务”?
前端
七号练习生.c3 小时前
结合Html、Javascript、Jquery做个简易的时间显示器
javascript·html·jquery
YianNib3 小时前
状态机是什么?
javascript
数学分析分析什么?3 小时前
微前端之qiankun+vue3简易示例
前端·微前端·qiankun
西洼工作室3 小时前
前端项目目录结构全解析
前端·vue.js