Created
February 8, 2026 04:12
-
-
Save ducnh1022/1c2fae6dd64e0b66c66a73c12baa2191 to your computer and use it in GitHub Desktop.
game hanzi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>VerbVibe - Trilingual Master</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --primary-blue: #A2D2FF; | |
| --success-green: #B9FBC0; | |
| --energy-orange: #FFD6A5; | |
| --bg-color: #F8F9FA; | |
| --text-dark: #2D3436; | |
| --white: #FFFFFF; | |
| } | |
| body { | |
| font-family: 'Montserrat', sans-serif; | |
| background-color: var(--bg-color); | |
| color: var(--text-dark); | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| min-height: 100vh; | |
| margin: 0; | |
| } | |
| #game-container { | |
| background: var(--white); | |
| width: 90%; | |
| max-width: 2000px; | |
| padding: 2rem; | |
| border-radius: 25px; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.05); | |
| text-align: center; | |
| } | |
| /* Stats Bar */ | |
| .stats-bar { | |
| display: flex; | |
| justify-content: space-between; | |
| margin-bottom: 20px; | |
| font-weight: bold; | |
| font-size: 0.9rem; | |
| } | |
| .hearts { color: #ff6b6b; } | |
| .xp-text { color: #0984e3; } | |
| /* Progress Bar */ | |
| .progress-container { | |
| background: #eee; | |
| height: 10px; | |
| border-radius: 5px; | |
| margin-bottom: 30px; | |
| overflow: hidden; | |
| } | |
| #progress-fill { | |
| background: var(--success-green); | |
| width: 0%; | |
| height: 100%; | |
| transition: width 0.3s ease; | |
| } | |
| /* Question Card */ | |
| .card { | |
| background: var(--primary-white); | |
| padding: 40px 20px; | |
| border-radius: 20px; | |
| color: black; | |
| margin-bottom: 30px; | |
| box-shadow: 0 8px 15px rgba(162, 210, 255, 0.4); | |
| } | |
| .card h2 { margin: 0; font-size: 1.2rem; opacity: 0.9; } | |
| .card .main-word { font-size: 2.5rem; margin: 10px 0; } | |
| .card .sub-word { font-size: 10rem; font-style: bold; opacity: 1; } | |
| /* Options */ | |
| .options-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 15px; | |
| } | |
| .option-btn { | |
| background: white; | |
| border: 2px solid #eee; | |
| padding: 15px; | |
| border-radius: 15px; | |
| cursor: pointer; | |
| font-size: 4rem; | |
| font-weight: 700; | |
| transition: all 0.2s; | |
| } | |
| .option-btn:hover { | |
| border-color: var(--primary-blue); | |
| transform: translateY(-2px); | |
| } | |
| .correct { background-color: var(--success-green) !important; border-color: transparent !important; } | |
| .wrong { background-color: #ffcfcf !important; border-color: transparent !important; } | |
| .hidden { display: none; } | |
| button#next-btn { | |
| margin-top: 20px; | |
| background: var(--energy-orange); | |
| border: none; | |
| padding: 12px 30px; | |
| border-radius: 10px; | |
| font-weight: bold; | |
| cursor: pointer; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="game-container"> | |
| <div class="stats-bar"> | |
| <div class="xp-text">XP: <span id="xp-count">0</span></div> | |
| <div id="streak">🔥 <span id="streak-count">0</span></div> | |
| <div class="hearts">❤️ <span id="heart-count">3</span></div> | |
| </div> | |
| <div class="progress-container"> | |
| <div id="progress-fill"></div> | |
| </div> | |
| <div id="quiz-screen"> | |
| <div class="card"> | |
| <div class="main-word" id="question-word">Eat</div> | |
| <div class="sub-word" id="extra-hint">吃 (chī)</div> | |
| </div> | |
| <div class="options-grid" id="options-container"> | |
| </div> | |
| <button id="next-btn" class="hidden">Next Question →</button> | |
| </div> | |
| <div id="end-screen" class="hidden"> | |
| <h1>🎉 Level Complete!</h1> | |
| <p>You've mastered the verbs.</p> | |
| <button onclick="location.reload()" style="padding: 15px 30px; border-radius: 10px; border: none; background: var(--primary-blue); color: white; cursor: pointer;">Play Again</button> | |
| </div> | |
| </div> | |
| <script> | |
| const init_verbs = [ | |
| { en: "Eat", vn: "Ăn", cn: "吃 (chī)" }, | |
| { en: "Sleep", vn: "Ngủ", cn: "睡 (shuì)" }, | |
| { en: "Go", vn: "Đi", cn: "去 (qù)" }, | |
| { en: "Drink", vn: "Uống", cn: "喝 (hē)" }, | |
| { en: "Read", vn: "Đọc", cn: "读 (dú)" }, | |
| { en: "Write", vn: "Viết", cn: "写 (xiě)" }, | |
| { en: "Speak", vn: "Nói", cn: "说 (shuō)" }, | |
| { en: "Listen", vn: "Nghe", cn: "听 (tīng)" }, | |
| { en: "Look", vn: "Nhìn", cn: "看 (kàn)" }, | |
| { en: "Walk", vn: "Đi bộ", cn: "走 (zǒu)" }, | |
| { en: "Run", vn: "Chạy", cn: "跑 (pǎo)" }, | |
| { en: "Play", vn: "Chơi", cn: "玩 (wán)" }, | |
| { en: "Buy", vn: "Mua", cn: "买 (mǎi)" }, | |
| { en: "Sell", vn: "Bán", cn: "卖 (mài)" }, | |
| { en: "Sit", vn: "Ngồi", cn: "坐 (zuò)" }, | |
| { en: "Stand", vn: "Đứng", cn: "站 (zhàn)" }, | |
| { en: "Open", vn: "Mở", cn: "开 (kāi)" }, | |
| { en: "Close", vn: "Đóng", cn: "关 (guān)" }, | |
| { en: "Give", vn: "Cho", cn: "给 (gěi)" }, | |
| { en: "Take", vn: "Lấy", cn: "拿 (ná)" }, | |
| { en: "Come", vn: "Đến", cn: "来 (lái)" }, | |
| { en: "Leave", vn: "Rời đi", cn: "离开 (líkāi)" }, | |
| { en: "Arrive", vn: "Đến nơi", cn: "到达 (dàodá)" }, | |
| { en: "Return", vn: "Trở về", cn: "回来 (huílái)" }, | |
| { en: "Work", vn: "Làm việc", cn: "工作 (gōngzuò)" }, | |
| { en: "Study", vn: "Học", cn: "学习 (xuéxí)" }, | |
| { en: "Teach", vn: "Dạy", cn: "教 (jiāo)" }, | |
| { en: "Learn", vn: "Học", cn: "学 (xué)" }, | |
| { en: "Think", vn: "Nghĩ", cn: "想 (xiǎng)" }, | |
| { en: "Know", vn: "Biết", cn: "知道 (zhīdào)" }, | |
| { en: "Understand", vn: "Hiểu", cn: "理解 (lǐjiě)" }, | |
| { en: "Remember", vn: "Nhớ", cn: "记得 (jìde)" }, | |
| { en: "Forget", vn: "Quên", cn: "忘记 (wàngjì)" }, | |
| { en: "Meet", vn: "Gặp", cn: "见面 (jiànmiàn)" }, | |
| { en: "Call", vn: "Gọi", cn: "打电话 (dǎ diànhuà)" }, | |
| { en: "Send", vn: "Gửi", cn: "发送 (fāsòng)" }, | |
| { en: "Receive", vn: "Nhận", cn: "收到 (shōudào)" }, | |
| { en: "Help", vn: "Giúp", cn: "帮助 (bāngzhù)" }, | |
| { en: "Ask", vn: "Hỏi", cn: "问 (wèn)" }, | |
| { en: "Answer", vn: "Trả lời", cn: "回答 (huídá)" }, | |
| { en: "Wait", vn: "Chờ", cn: "等 (děng)" }, | |
| { en: "Start", vn: "Bắt đầu", cn: "开始 (kāishǐ)" }, | |
| { en: "Finish", vn: "Kết thúc", cn: "结束 (jiéshù)" }, | |
| { en: "Stop", vn: "Dừng", cn: "停止 (tíngzhǐ)" }, | |
| { en: "Continue", vn: "Tiếp tục", cn: "继续 (jìxù)" }, | |
| { en: "Change", vn: "Thay đổi", cn: "改变 (gǎibiàn)" }, | |
| { en: "Move", vn: "Di chuyển", cn: "移动 (yídòng)" }, | |
| { en: "Turn", vn: "Rẽ", cn: "转 (zhuǎn)" }, | |
| { en: "Enter", vn: "Vào", cn: "进入 (jìnrù)" }, | |
| { en: "Exit", vn: "Ra", cn: "出去 (chūqù)" }, | |
| { en: "Climb", vn: "Leo", cn: "爬 (pá)" }, | |
| { en: "Drive", vn: "Lái xe", cn: "开车 (kāichē)" }, | |
| { en: "Ride", vn: "Đi xe", cn: "骑 (qí)" }, | |
| { en: "Fly", vn: "Bay", cn: "飞 (fēi)" }, | |
| { en: "Swim", vn: "Bơi", cn: "游泳 (yóuyǒng)" }, | |
| { en: "Jump", vn: "Nhảy", cn: "跳 (tiào)" }, | |
| { en: "Dance", vn: "Nhảy múa", cn: "跳舞 (tiàowǔ)" }, | |
| { en: "Sing", vn: "Hát", cn: "唱 (chàng)" }, | |
| { en: "Cook", vn: "Nấu ăn", cn: "做饭 (zuòfàn)" }, | |
| { en: "Clean", vn: "Dọn dẹp", cn: "打扫 (dǎsǎo)" }, | |
| { en: "Wash", vn: "Rửa", cn: "洗 (xǐ)" }, | |
| { en: "Cut", vn: "Cắt", cn: "切 (qiē)" }, | |
| { en: "Build", vn: "Xây", cn: "建 (jiàn)" }, | |
| { en: "Fix", vn: "Sửa", cn: "修理 (xiūlǐ)" }, | |
| { en: "Create", vn: "Tạo", cn: "创造 (chuàngzào)" }, | |
| { en: "Make", vn: "Làm", cn: "做 (zuò)" }, | |
| { en: "Use", vn: "Dùng", cn: "用 (yòng)" }, | |
| { en: "Try", vn: "Thử", cn: "试 (shì)" }, | |
| { en: "Win", vn: "Thắng", cn: "赢 (yíng)" }, | |
| { en: "Lose", vn: "Thua", cn: "输 (shū)" }, | |
| { en: "Find", vn: "Tìm thấy", cn: "找到 (zhǎodào)" }, | |
| { en: "Search", vn: "Tìm kiếm", cn: "寻找 (xúnzhǎo)" }, | |
| { en: "Show", vn: "Cho xem", cn: "展示 (zhǎnshì)" }, | |
| { en: "Hide", vn: "Giấu", cn: "隐藏 (yǐncáng)" }, | |
| { en: "Bring", vn: "Mang", cn: "带来 (dàilái)" }, | |
| { en: "Carry", vn: "Mang theo", cn: "携带 (xiédài)" }, | |
| { en: "Hold", vn: "Cầm", cn: "握 (wò)" }, | |
| { en: "Push", vn: "Đẩy", cn: "推 (tuī)" }, | |
| { en: "Pull", vn: "Kéo", cn: "拉 (lā)" }, | |
| { en: "Throw", vn: "Ném", cn: "扔 (rēng)" }, | |
| { en: "Catch", vn: "Bắt", cn: "抓 (zhuā)" }, | |
| { en: "Break", vn: "Làm vỡ", cn: "打破 (dǎpò)" }, | |
| { en: "Repair", vn: "Sửa chữa", cn: "修复 (xiūfù)" }, | |
| { en: "Choose", vn: "Chọn", cn: "选择 (xuǎnzé)" }, | |
| { en: "Decide", vn: "Quyết định", cn: "决定 (juédìng)" }, | |
| { en: "Plan", vn: "Lên kế hoạch", cn: "计划 (jìhuà)" }, | |
| { en: "Prepare", vn: "Chuẩn bị", cn: "准备 (zhǔnbèi)" }, | |
| { en: "Organize", vn: "Tổ chức", cn: "组织 (zǔzhī)" }, | |
| { en: "Manage", vn: "Quản lý", cn: "管理 (guǎnlǐ)" }, | |
| { en: "Control", vn: "Kiểm soát", cn: "控制 (kòngzhì)" }, | |
| { en: "Grow", vn: "Phát triển", cn: "成长 (chéngzhǎng)" }, | |
| { en: "Increase", vn: "Tăng", cn: "增加 (zēngjiā)" }, | |
| { en: "Reduce", vn: "Giảm", cn: "减少 (jiǎnshǎo)" }, | |
| { en: "Improve", vn: "Cải thiện", cn: "提高 (tígāo)" }, | |
| { en: "Develop", vn: "Phát triển", cn: "发展 (fāzhǎn)" }, | |
| { en: "Design", vn: "Thiết kế", cn: "设计 (shèjì)" }, | |
| { en: "Draw", vn: "Vẽ", cn: "画 (huà)" }, | |
| { en: "Paint", vn: "Tô màu", cn: "涂 (tú)" }, | |
| { en: "Record", vn: "Ghi lại", cn: "记录 (jìlù)" }, | |
| { en: "Check", vn: "Kiểm tra", cn: "检查 (jiǎnchá)" }, | |
| { en: "Test", vn: "Kiểm tra", cn: "测试 (cèshì)" }, | |
| { en: "Compare", vn: "So sánh", cn: "比较 (bǐjiào)" }, | |
| { en: "Count", vn: "Đếm", cn: "数 (shǔ)" }, | |
| { en: "Measure", vn: "Đo", cn: "测量 (cèliáng)" }, | |
| { en: "Weigh", vn: "Cân", cn: "称 (chēng)" }, | |
| { en: "Pay", vn: "Trả tiền", cn: "支付 (zhīfù)" }, | |
| { en: "Save", vn: "Tiết kiệm", cn: "保存 (bǎocún)" }, | |
| { en: "Spend", vn: "Chi tiêu", cn: "花 (huā)" }, | |
| { en: "Earn", vn: "Kiếm", cn: "赚 (zhuàn)" }, | |
| { en: "Borrow", vn: "Mượn", cn: "借 (jiè)" }, | |
| { en: "Lend", vn: "Cho mượn", cn: "借给 (jiègěi)" }, | |
| { en: "Trade", vn: "Trao đổi", cn: "交易 (jiāoyì)" }, | |
| { en: "Travel", vn: "Du lịch", cn: "旅行 (lǚxíng)" }, | |
| { en: "Visit", vn: "Thăm", cn: "拜访 (bàifǎng)" }, | |
| { en: "Stay", vn: "Ở lại", cn: "停留 (tíngliú)" }, | |
| { en: "Live", vn: "Sống", cn: "生活 (shēnghuó)" }, | |
| { en: "Die", vn: "Chết", cn: "死 (sǐ)" }, | |
| { en: "Laugh", vn: "Cười", cn: "笑 (xiào)" }, | |
| { en: "Cry", vn: "Khóc", cn: "哭 (kū)" }, | |
| { en: "Smile", vn: "Mỉm cười", cn: "微笑 (wēixiào)" }, | |
| { en: "Love", vn: "Yêu", cn: "爱 (ài)" }, | |
| { en: "Like", vn: "Thích", cn: "喜欢 (xǐhuān)" }, | |
| { en: "Hate", vn: "Ghét", cn: "讨厌 (tǎoyàn)" }, | |
| { en: "Want", vn: "Muốn", cn: "想要 (xiǎngyào)" }, | |
| { en: "Need", vn: "Cần", cn: "需要 (xūyào)" }, | |
| { en: "Hope", vn: "Hy vọng", cn: "希望 (xīwàng)" }, | |
| { en: "Wish", vn: "Ước", cn: "愿望 (yuànwàng)" }, | |
| { en: "Believe", vn: "Tin", cn: "相信 (xiāngxìn)" }, | |
| { en: "Trust", vn: "Tin tưởng", cn: "信任 (xìnrèn)" }, | |
| { en: "Respect", vn: "Tôn trọng", cn: "尊重 (zūnzhòng)" }, | |
| { en: "Agree", vn: "Đồng ý", cn: "同意 (tóngyì)" }, | |
| { en: "Disagree", vn: "Không đồng ý", cn: "不同意 (bù tóngyì)" }, | |
| { en: "Accept", vn: "Chấp nhận", cn: "接受 (jiēshòu)" }, | |
| { en: "Refuse", vn: "Từ chối", cn: "拒绝 (jùjué)" }, | |
| { en: "Allow", vn: "Cho phép", cn: "允许 (yǔnxǔ)" }, | |
| { en: "Forbid", vn: "Cấm", cn: "禁止 (jìnzhǐ)" }, | |
| { en: "Protect", vn: "Bảo vệ", cn: "保护 (bǎohù)" }, | |
| { en: "Attack", vn: "Tấn công", cn: "攻击 (gōngjī)" }, | |
| { en: "Defend", vn: "Phòng thủ", cn: "防守 (fángshǒu)" }, | |
| { en: "Save (rescue)", vn: "Cứu", cn: "救 (jiù)" }, | |
| { en: "Share", vn: "Chia sẻ", cn: "分享 (fēnxiǎng)" }, | |
| { en: "Join", vn: "Tham gia", cn: "加入 (jiārù)" }, | |
| { en: "Leave (group)", vn: "Rời nhóm", cn: "离开 (líkāi)" }, | |
| { en: "Lead", vn: "Dẫn dắt", cn: "领导 (lǐngdǎo)" }, | |
| { en: "Follow", vn: "Theo", cn: "跟随 (gēnsuí)" }, | |
| { en: "Support", vn: "Hỗ trợ", cn: "支持 (zhīchí)" }, | |
| { en: "Serve", vn: "Phục vụ", cn: "服务 (fúwù)" }, | |
| { en: "Provide", vn: "Cung cấp", cn: "提供 (tígōng)" }, | |
| { en: "Deliver", vn: "Giao", cn: "递送 (dìsòng)" }, | |
| { en: "Collect", vn: "Thu thập", cn: "收集 (shōují)" }, | |
| { en: "Download", vn: "Tải xuống", cn: "下载 (xiàzài)" }, | |
| { en: "Upload", vn: "Tải lên", cn: "上传 (shàngchuán)" }, | |
| { en: "Click", vn: "Nhấp", cn: "点击 (diǎnjī)" }, | |
| { en: "Type", vn: "Gõ", cn: "打字 (dǎzì)" }, | |
| { en: "Print", vn: "In", cn: "打印 (dǎyìn)" }, | |
| { en: "Scan", vn: "Quét", cn: "扫描 (sǎomiáo)" }, | |
| { en: "Connect", vn: "Kết nối", cn: "连接 (liánjiē)" }, | |
| { en: "Disconnect", vn: "Ngắt kết nối", cn: "断开 (duànkāi)" }, | |
| { en: "Upload", vn: "Tải lên", cn: "上传 (shàngchuán)" }, | |
| { en: "Download", vn: "Tải xuống", cn: "下载 (xiàzài)" }, | |
| { en: "Lock", vn: "Khóa", cn: "锁 (suǒ)" }, | |
| { en: "Unlock", vn: "Mở khóa", cn: "解锁 (jiěsuǒ)" }, | |
| { en: "Turn on", vn: "Bật", cn: "打开 (dǎkāi)" }, | |
| { en: "Turn off", vn: "Tắt", cn: "关闭 (guānbì)" }, | |
| { en: "Charge", vn: "Sạc", cn: "充电 (chōngdiàn)" }, | |
| { en: "Download", vn: "Tải xuống", cn: "下载 (xiàzài)" }, | |
| { en: "Upload", vn: "Tải lên", cn: "上传 (shàngchuán)" }, | |
| { en: "Browse", vn: "Duyệt", cn: "浏览 (liúlǎn)" }, | |
| { en: "Search online", vn: "Tìm online", cn: "搜索 (sōusuǒ)" }, | |
| { en: "Stream", vn: "Xem trực tuyến", cn: "播放 (bōfàng)" } | |
| ]; | |
| const verbs = init_verbs.sort(() => Math.random() - 0.5); | |
| let currentQuestionIndex = 0; | |
| let xp = 0; | |
| let hearts = 5; | |
| let streak = 0; | |
| const questionWord = document.getElementById('question-word'); | |
| const extraHint = document.getElementById('extra-hint'); | |
| const optionsContainer = document.getElementById('options-container'); | |
| const nextBtn = document.getElementById('next-btn'); | |
| const progressFill = document.getElementById('progress-fill'); | |
| const xpDisplay = document.getElementById('xp-count'); | |
| const heartDisplay = document.getElementById('heart-count'); | |
| const streakDisplay = document.getElementById('streak-count'); | |
| function initGame() { | |
| showQuestion(); | |
| } | |
| function showQuestion() { | |
| nextBtn.classList.add('hidden'); | |
| const currentVerb = verbs[currentQuestionIndex]; | |
| questionWord.innerText = ''; | |
| extraHint.innerText = currentVerb.cn; | |
| // Generate options | |
| let options = [currentVerb.vn]; | |
| while(options.length < 4) { | |
| let randomVerb = verbs[Math.floor(Math.random() * verbs.length)].vn; | |
| if(!options.includes(randomVerb)) options.push(randomVerb); | |
| } | |
| options.sort(() => Math.random() - 0.5); | |
| optionsContainer.innerHTML = ''; | |
| options.forEach(opt => { | |
| const btn = document.createElement('button'); | |
| btn.classList.add('option-btn'); | |
| btn.innerText = opt; | |
| btn.onclick = () => checkAnswer(opt, btn, currentVerb.vn); | |
| optionsContainer.appendChild(btn); | |
| }); | |
| } | |
| function checkAnswer(selected, btn, correct) { | |
| const allBtns = document.querySelectorAll('.option-btn'); | |
| allBtns.forEach(b => b.style.pointerEvents = 'none'); | |
| if(selected === correct) { | |
| btn.classList.add('correct'); | |
| xp += 10; | |
| streak++; | |
| updateStats(); | |
| } else { | |
| btn.classList.add('wrong'); | |
| hearts--; | |
| streak = 0; | |
| updateStats(); | |
| // Show correct answer | |
| allBtns.forEach(b => { | |
| if(b.innerText === correct) b.classList.add('correct'); | |
| }); | |
| if(hearts <= 0) { | |
| alert("Game Over! Try again."); | |
| location.reload(); | |
| } | |
| } | |
| nextBtn.classList.remove('hidden'); | |
| } | |
| function updateStats() { | |
| xpDisplay.innerText = xp; | |
| heartDisplay.innerText = hearts; | |
| streakDisplay.innerText = streak; | |
| const progress = ((currentQuestionIndex + 1) / verbs.length) * 100; | |
| progressFill.style.width = progress + "%"; | |
| } | |
| nextBtn.onclick = () => { | |
| currentQuestionIndex++; | |
| if(currentQuestionIndex < verbs.length) { | |
| showQuestion(); | |
| } else { | |
| document.getElementById('quiz-screen').classList.add('hidden'); | |
| document.getElementById('end-screen').classList.remove('hidden'); | |
| } | |
| }; | |
| initGame(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment