

已经为你创建了一个炫酷的汉字打字游戏HTML文件!
游戏特点:
核心玩法:
-
汉字从顶部掉落,需要输入对应的汉字来消除
-
100个常用汉字库,涵盖自然、颜色、方位等多个类别
-
60秒倒计时挑战
计分系统:
-
基础分:每个汉字10分
-
连击加成:连击越高,分数越高(10 × 连击数)
-
实时显示分数、连击数、正确率
难度提升:
-
每15秒难度自动增加
-
汉字下落速度加快,生成频率提高
炫酷特效:
-
渐变紫色背景 + 浮动粒子效果
-
毛玻璃质感的UI设计
-
消除汉字时的爆炸动画
-
5连击以上显示大字连击提示
-
进度条显示剩余时间
游戏结算:
-
显示最终得分、总击中数、最高连击、正确率
-
可以重新开始游戏
控制功能:
-
暂停/继续按钮
-
重新开始按钮
现在你可以直接在浏览器中打开 E:\source\m-apps\codex\typing-game.html
文件开始游戏了!在输入框输入汉字即可开始挑战。
html
<!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', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
overflow: hidden;
height: 100vh;
}
/* 粒子背景 */
.particles {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 0;
}
.particle {
position: absolute;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
animation: float linear infinite;
}
@keyframes float {
0% {
transform: translateY(100vh) rotate(0deg);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateY(-100px) rotate(360deg);
opacity: 0;
}
}
.container {
position: relative;
z-index: 1;
height: 100vh;
display: flex;
flex-direction: column;
}
/* 头部信息栏 */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 40px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-bottom: 2px solid rgba(255, 255, 255, 0.2);
}
.title {
font-size: 32px;
font-weight: bold;
color: white;
text-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
}
.stats {
display: flex;
gap: 30px;
}
.stat-item {
text-align: center;
color: white;
}
.stat-label {
font-size: 14px;
opacity: 0.8;
margin-bottom: 5px;
}
.stat-value {
font-size: 28px;
font-weight: bold;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}
/* 游戏区域 */
.game-area {
position: relative;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
/* 掉落的汉字 */
.falling-char {
position: absolute;
font-size: 36px;
font-weight: bold;
color: white;
text-shadow: 0 0 20px rgba(255, 255, 255, 0.8),
0 0 40px rgba(255, 255, 255, 0.5);
cursor: pointer;
transition: all 0.3s;
padding: 10px 15px;
background: rgba(255, 255, 255, 0.2);
border-radius: 10px;
backdrop-filter: blur(5px);
border: 2px solid rgba(255, 255, 255, 0.3);
}
.falling-char:hover {
transform: scale(1.1);
box-shadow: 0 0 30px rgba(255, 255, 255, 0.8);
}
.falling-char.matched {
animation: explode 0.5s ease-out forwards;
}
@keyframes explode {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(2);
opacity: 0;
}
}
/* 输入区域 */
.input-area {
padding: 30px 40px;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-top: 2px solid rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
gap: 20px;
}
.input-box {
flex: 1;
padding: 15px 25px;
font-size: 24px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-radius: 15px;
background: rgba(255, 255, 255, 0.2);
color: white;
outline: none;
backdrop-filter: blur(10px);
transition: all 0.3s;
}
.input-box:focus {
border-color: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 30px rgba(255, 255, 255, 0.5);
transform: scale(1.02);
}
.input-box::placeholder {
color: rgba(255, 255, 255, 0.6);
}
/* 按钮 */
.btn {
padding: 15px 30px;
font-size: 18px;
font-weight: bold;
color: white;
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.4);
border-radius: 15px;
cursor: pointer;
transition: all 0.3s;
backdrop-filter: blur(10px);
}
.btn:hover {
background: rgba(255, 255, 255, 0.3);
box-shadow: 0 0 20px rgba(255, 255, 255, 0.6);
transform: translateY(-2px);
}
.btn:active {
transform: translateY(0);
}
/* 游戏结束界面 */
.game-over {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 255, 255, 0.95);
padding: 50px 80px;
border-radius: 20px;
text-align: center;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
display: none;
z-index: 100;
}
.game-over.show {
display: block;
animation: popIn 0.5s ease-out;
}
@keyframes popIn {
0% {
transform: translate(-50%, -50%) scale(0.5);
opacity: 0;
}
100% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
}
.game-over h2 {
font-size: 48px;
color: #667eea;
margin-bottom: 20px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.final-score {
font-size: 36px;
color: #764ba2;
margin: 20px 0;
font-weight: bold;
}
.game-over-stats {
margin: 30px 0;
display: flex;
gap: 40px;
justify-content: center;
}
.game-over-stat {
text-align: center;
}
.game-over-stat-label {
font-size: 16px;
color: #666;
margin-bottom: 8px;
}
.game-over-stat-value {
font-size: 28px;
color: #667eea;
font-weight: bold;
}
.restart-btn {
padding: 15px 50px;
font-size: 20px;
font-weight: bold;
color: white;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 15px;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
.restart-btn:hover {
transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.6);
}
/* 连击提示 */
.combo-display {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 72px;
font-weight: bold;
color: #ffd700;
text-shadow: 0 0 30px rgba(255, 215, 0, 0.8);
pointer-events: none;
opacity: 0;
z-index: 50;
}
.combo-display.show {
animation: comboAnim 1s ease-out;
}
@keyframes comboAnim {
0% {
transform: translate(-50%, -50%) scale(0.5);
opacity: 0;
}
50% {
transform: translate(-50%, -50%) scale(1.2);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) scale(1);
opacity: 0;
}
}
/* 进度条 */
.progress-bar {
position: absolute;
bottom: 0;
left: 0;
height: 5px;
background: rgba(255, 215, 0, 0.8);
transition: width 0.1s linear;
box-shadow: 0 0 10px rgba(255, 215, 0, 0.8);
}
/* 难度指示器 */
.difficulty {
position: absolute;
top: 20px;
right: 40px;
padding: 10px 20px;
background: rgba(255, 255, 255, 0.2);
border-radius: 10px;
color: white;
font-weight: bold;
backdrop-filter: blur(10px);
}
</style>
</head>
<body>
<div class="particles" id="particles"></div>
<div class="container">
<div class="header">
<div class="title">汉字打字挑战</div>
<div class="stats">
<div class="stat-item">
<div class="stat-label">分数</div>
<div class="stat-value" id="score">0</div>
</div>
<div class="stat-item">
<div class="stat-label">连击</div>
<div class="stat-value" id="combo">0</div>
</div>
<div class="stat-item">
<div class="stat-label">正确率</div>
<div class="stat-value" id="accuracy">100%</div>
</div>
<div class="stat-item">
<div class="stat-label">时间</div>
<div class="stat-value" id="timer">60</div>
</div>
</div>
</div>
<div class="game-area" id="gameArea">
<div class="combo-display" id="comboDisplay"></div>
</div>
<div class="input-area">
<input type="text"
class="input-box"
id="inputBox"
placeholder="输入汉字开始游戏..."
autocomplete="off">
<button class="btn" id="pauseBtn">暂停</button>
<button class="btn" id="restartBtn">重新开始</button>
</div>
<div class="progress-bar" id="progressBar"></div>
</div>
<div class="game-over" id="gameOver">
<h2>游戏结束!</h2>
<div class="final-score">最终得分: <span id="finalScore">0</span></div>
<div class="game-over-stats">
<div class="game-over-stat">
<div class="game-over-stat-label">总击中</div>
<div class="game-over-stat-value" id="finalHits">0</div>
</div>
<div class="game-over-stat">
<div class="game-over-stat-label">最高连击</div>
<div class="game-over-stat-value" id="finalCombo">0</div>
</div>
<div class="game-over-stat">
<div class="game-over-stat-label">正确率</div>
<div class="game-over-stat-value" id="finalAccuracy">0%</div>
</div>
</div>
<button class="restart-btn" onclick="restartGame()">再玩一次</button>
</div>
<script>
// 汉字库
const characters = [
'春', '夏', '秋', '冬', '天', '地', '日', '月', '星', '云',
'风', '雨', '雪', '花', '草', '树', '山', '水', '火', '土',
'金', '木', '石', '光', '明', '暗', '红', '黄', '蓝', '绿',
'爱', '和', '平', '福', '喜', '乐', '美', '好', '善', '真',
'心', '情', '意', '志', '梦', '想', '望', '念', '思', '忆',
'人', '民', '国', '家', '天', '下', '世', '界', '宇', '宙',
'东', '西', '南', '北', '中', '央', '左', '右', '上', '下',
'大', '小', '多', '少', '高', '低', '长', '短', '新', '旧',
'快', '慢', '强', '弱', '明', '亮', '清', '白', '黑', '灰'
];
// 游戏状态
let score = 0;
let combo = 0;
let maxCombo = 0;
let hits = 0;
let misses = 0;
let timeLeft = 60;
let isPaused = false;
let isGameOver = false;
let fallingChars = [];
let spawnInterval;
let timerInterval;
let difficultyLevel = 1;
// DOM元素
const gameArea = document.getElementById('gameArea');
const inputBox = document.getElementById('inputBox');
const scoreDisplay = document.getElementById('score');
const comboDisplay = document.getElementById('combo');
const accuracyDisplay = document.getElementById('accuracy');
const timerDisplay = document.getElementById('timer');
const comboAnim = document.getElementById('comboDisplay');
const gameOverScreen = document.getElementById('gameOver');
const progressBar = document.getElementById('progressBar');
const pauseBtn = document.getElementById('pauseBtn');
const restartBtn = document.getElementById('restartBtn');
// 创建粒子背景
function createParticles() {
const particlesContainer = document.getElementById('particles');
for (let i = 0; i < 50; i++) {
const particle = document.createElement('div');
particle.className = 'particle';
particle.style.width = Math.random() * 10 + 5 + 'px';
particle.style.height = particle.style.width;
particle.style.left = Math.random() * 100 + '%';
particle.style.animationDuration = Math.random() * 10 + 10 + 's';
particle.style.animationDelay = Math.random() * 5 + 's';
particlesContainer.appendChild(particle);
}
}
// 创建掉落的汉字
function createFallingChar() {
if (isPaused || isGameOver) return;
const char = document.createElement('div');
char.className = 'falling-char';
char.textContent = characters[Math.floor(Math.random() * characters.length)];
char.style.left = Math.random() * (gameArea.offsetWidth - 60) + 'px';
char.style.top = '0px';
const charData = {
element: char,
speed: 1 + (difficultyLevel * 0.5),
text: char.textContent
};
fallingChars.push(charData);
gameArea.appendChild(char);
}
// 更新掉落的汉字位置
function updateFallingChars() {
if (isPaused || isGameOver) return;
fallingChars = fallingChars.filter(charData => {
const currentTop = parseFloat(charData.element.style.top);
const newTop = currentTop + charData.speed;
if (newTop > gameArea.offsetHeight - 100) {
charData.element.remove();
misses++;
combo = 0;
updateAccuracy();
return false;
}
charData.element.style.top = newTop + 'px';
return true;
});
requestAnimationFrame(updateFallingChars);
}
// 处理输入
inputBox.addEventListener('input', (e) => {
if (isGameOver) return;
const input = e.target.value.trim();
if (!input) return;
// 开始游戏
if (timeLeft === 60 && !timerInterval) {
startTimer();
startSpawning();
}
// 查找匹配的汉字
let matched = false;
for (let i = 0; i < fallingChars.length; i++) {
if (fallingChars[i].text === input) {
matched = true;
const charData = fallingChars[i];
// 播放消失动画
charData.element.classList.add('matched');
setTimeout(() => charData.element.remove(), 500);
// 更新分数和连击
combo++;
maxCombo = Math.max(maxCombo, combo);
const points = 10 * combo;
score += points;
hits++;
// 显示连击动画
if (combo >= 5) {
showComboAnimation(combo);
}
// 更新显示
updateScore();
updateAccuracy();
// 移除这个汉字
fallingChars.splice(i, 1);
break;
}
}
if (!matched) {
combo = 0;
misses++;
updateAccuracy();
}
e.target.value = '';
});
// 显示连击动画
function showComboAnimation(comboCount) {
comboAnim.textContent = `${comboCount} 连击!`;
comboAnim.classList.add('show');
setTimeout(() => {
comboAnim.classList.remove('show');
}, 1000);
}
// 更新分数
function updateScore() {
scoreDisplay.textContent = score;
comboDisplay.textContent = combo;
}
// 更新正确率
function updateAccuracy() {
const total = hits + misses;
const accuracy = total === 0 ? 100 : Math.round((hits / total) * 100);
accuracyDisplay.textContent = accuracy + '%';
}
// 开始计时
function startTimer() {
timerInterval = setInterval(() => {
if (isPaused) return;
timeLeft--;
timerDisplay.textContent = timeLeft;
// 更新进度条
progressBar.style.width = (timeLeft / 60) * 100 + '%';
// 增加难度
if (timeLeft % 15 === 0 && timeLeft > 0) {
difficultyLevel++;
}
if (timeLeft <= 0) {
endGame();
}
}, 1000);
}
// 开始生成汉字
function startSpawning() {
spawnInterval = setInterval(() => {
if (!isPaused && !isGameOver) {
createFallingChar();
}
}, Math.max(800 - (difficultyLevel * 100), 300));
}
// 暂停/继续
pauseBtn.addEventListener('click', () => {
isPaused = !isPaused;
pauseBtn.textContent = isPaused ? '继续' : '暂停';
});
// 重新开始
restartBtn.addEventListener('click', () => {
restartGame();
});
// 结束游戏
function endGame() {
isGameOver = true;
clearInterval(timerInterval);
clearInterval(spawnInterval);
// 显示结算界面
document.getElementById('finalScore').textContent = score;
document.getElementById('finalHits').textContent = hits;
document.getElementById('finalCombo').textContent = maxCombo;
const finalAccuracy = hits + misses === 0 ? 100 : Math.round((hits / (hits + misses)) * 100);
document.getElementById('finalAccuracy').textContent = finalAccuracy + '%';
gameOverScreen.classList.add('show');
}
// 重新开始游戏
function restartGame() {
// 重置状态
score = 0;
combo = 0;
maxCombo = 0;
hits = 0;
misses = 0;
timeLeft = 60;
isPaused = false;
isGameOver = false;
difficultyLevel = 1;
// 清理掉落的汉字
fallingChars.forEach(charData => charData.element.remove());
fallingChars = [];
// 重置显示
updateScore();
updateAccuracy();
timerDisplay.textContent = timeLeft;
progressBar.style.width = '100%';
pauseBtn.textContent = '暂停';
gameOverScreen.classList.remove('show');
inputBox.value = '';
inputBox.focus();
// 清除定时器
clearInterval(timerInterval);
clearInterval(spawnInterval);
timerInterval = null;
spawnInterval = null;
}
// 初始化
createParticles();
updateFallingChars();
inputBox.focus();
// 阻止空格键滚动页面
window.addEventListener('keydown', (e) => {
if (e.code === 'Space' && e.target === inputBox) {
e.preventDefault();
}
});
</script>
</body>
</html>
