A fast, fun, progressively evolving Match‑3 puzzle made with vanilla JavaScript and juicy fruit emoji
Match 3 or more identical fruits to score, trigger cascades, overcome spreading obstacles, and climb through infinite levels!

Classic grid-based match‑3 with evolving obstacles

Tap, swap & crush – fully responsive
EmojiCrush is a lightweight Match‑3 puzzle focused on progression and emergent challenge. Each level introduces or scales mechanics: ice tiles, chocolate spread, timed modes, extra fruit variants, and destructible / spreading obstacles like trash, ice bombs, and chocolate generators.
Built with:
- HTML + CSS + Vanilla JavaScript
- No frameworks / build step
- All assets are Unicode emoji → instant load
- 🧠 Clean modular game logic (swap → validate → resolve cascades)
- 🍉 Emoji fruit tiles (no sprite downloads)
- 🧊 Progressive mechanics (ice, chocolate, timers, special obstacles)
- 🏭 Spreading / spawning hazards (bombs & generators)
- 📈 Infinite leveling with dynamic objectives & scaling
- ✨ Combo & cascade scoring foundation (easy to extend)
- 📱 Responsive & touch friendly
- ⚙️ Config‑driven design (edit
public/js/config.jsto tweak modes)
EmojiCrush ships with two predefined modes. Each mode governs grid size, base emoji selection, objective density, movement/time allowances, and per‑board limits for special obstacles.
| Mode | Grid (W×H) | Base Emojis | Extra Emojis (unlocked later) | Max Simultaneous Objectives | Base Objective Count | Base Moves | Base Timer (s) | Special Obstacle Limits (trash / iceBomb / chocolateSpawner) |
|---|---|---|---|---|---|---|---|---|
| easy | 8×8 | 🍑 🍇 🍋 🍓 | 🍊 🍎 | 7 | 14 | 30 | 75 | 1 / 1 / 1 |
| hard | 10×10 | 🍉 🥝 🥥 🥭 🥑 | 🍒 🍍 🍑 | 9 | 20 | 40 | 90 | 2 / 2 / 2 |
Notes:
- EXTRA_EMOJIS begin appearing at higher progression (see Level Milestones).
- Objective counts, moves, and timers can be combined with scaling rules in your game logic (not all scaling is inside
config.js; some may live ingame.js).
Defined in specialObstaclesConfig:
| Obstacle | Appears From Level | Health (Hits) | Emoji | Behavior |
|---|---|---|---|---|
| trash | 8 | 2 | 🗑️ | Static blocker until cleared by power actions / matches adjacent |
| iceBomb | 12 | 2 | ❄️ | Chance each turn to spread to adjacent (spreadRate 30%) |
| chocolateSpawner | 16 | 2 | 🏭 | Periodically creates chocolate (spreadRate 35%) |
Obstacle limits per board are enforced by the active game mode (SPECIAL_OBSTACLES_LIMIT).
Global progression constants (from config.js):
| Mechanic | Start Level | Description |
|---|---|---|
| ICE_START_LEVEL | 5 | Ice tiles appear and require matches to clear (up to MAX_ICE) |
| CHOCOLATE_START_LEVEL | 10 | Chocolate begins to spread (up to MAX_CHOCOLATE) |
| TIMER_START_LEVEL | 15 | Timed objectives replace or augment move-based ones |
| EXTRA_EMOJI_START_LEVEL | 20 | Additional emoji types added, increasing complexity |
| MAX_ICE | 12 | Cap of simultaneous ice pieces |
| MAX_CHOCOLATE | 12 | Cap of simultaneous chocolate tiles |
| Level Range | Newly Introduced / Activated Elements |
|---|---|
| 1–4 | Core fruits, basic matching |
| 5–7 | Ice tiles begin (manage freezing risk) |
| 8–11 | Trash obstacles can spawn |
| 10–11 | Chocolate spreading begins |
| 12–15 | Ice bombs begin (spreading hazard escalation) |
| 15–19 | Timed mode enabled / hybrid challenges |
| 16–19 | Chocolate Spawners appear |
| 20+ | Extra emojis added (higher color variance) |
| 20+ | All hazards interplay → strategic clearing priority |
Adjust this table if game logic refines spawn sequencing beyond
config.js.
- Player selects two adjacent tiles (horizontal / vertical)
- Tentative swap performed
- Match detection scan
- If no match → revert
- If match → clear matched tiles
- Resolve special obstacle damage/interactions
- Apply scoring & combo multiplier
- Gravity collapse (tiles fall)
- Refill empty spaces (may introduce new emoji types after unlock level)
- Cascade repetition while new matches form
- Spawn / spread hazards (trash, chocolate, ice bomb spread, generator expansion)
- Check objectives & level completion conditions
| Element | Suggested Base |
|---|---|
| Per fruit in match | 10 pts |
| 4 in a row bonus | +10 |
| 5+ (straight/T/L) | +25 |
| Cascade multiplier | +0.5× per additional cascade |
| Hazard cleared | +variable (e.g., +15 per obstacle health depleted) |
(Adjust inside scoring functions; tune for player engagement.)
- Prioritize clearing spawning sources (🏭) before they saturate the board
- Manage space around ice bombs (❄️) to prevent large frozen zones
- Delay completing final objectives if lining up a larger combo chain
- Save easy matches to pop obstacles adjacent with minimal move waste
- Adapt when EXTRA_EMOJIS increase tile diversity (harder matches)
- Click → Click adjacent to attempt swap
- (Optional future) Keyboard navigation
- R: Restart (if implemented)
- H: Toggle hints (planned)
- Tap first tile → tap adjacent tile
- Long press (future idea): highlight potential matches
| File | Responsibility |
|---|---|
public/js/config.js |
Game mode + obstacle + level constants (progression knobs) |
public/js/state.js |
Central runtime state container |
public/js/utils.js |
Helpers (random, array ops, board utilities) |
public/js/game.js |
Core game logic: generation, matching, cascades, spawning |
public/js/ui.js |
Rendering & HUD updates |
public/js/dom.js |
Element creation / DOM references |
public/js/events.js |
Input binding, event orchestration |
public/js/audio.js |
Sound effects handling (if enabled) |
public/js/main.js |
Bootstrapping / initialization flow |
(Adjust description if internal structure changes.)
Open: https://emoji-crush-infinity.web.app/
git clone https://github.com/danuaemx/emojicrush.git
cd emojicrush
# Open directly
open public/index.html # macOS
start public/index.html # Windows
# Or serve
python -m http.server 8000
# Visit http://localhost:8000/publicdocker build -t emojicrush .
docker run -p 8080:80 emojicrush
# Visit http://localhost:8080| Goal | Where to Tweak |
|---|---|
| Add new mode | gameModes in config.js |
| Change start level for hazards | Global constants in config.js |
| Adjust spawning rates | Add / modify logic in game.js (spread handling) |
| Add new obstacle | Extend specialObstaclesConfig + integrate in spawn & resolution code |
| Limit counts per board | Update SPECIAL_OBSTACLES_LIMIT per mode |
- Add entry to
specialObstaclesConfig:
magmaVent: { startLevel: 25, health: 3, emoji: '🌋', spreadRate: 20 }- Integrate spawn condition in generation phase.
- Implement spread/damage resolution in cascading loop.
- Add clearing logic + scoring.
| Case | Status | Notes |
|---|---|---|
| Invalid swap revert | ✅ | No match → revert |
| Multiple simultaneous matches | ✅ | Consolidated before collapse |
| Cascading chain detection | ✅ | Loop until stable |
| Obstacle health tracking | ✅ | Health decrements via interactions |
| Spread probability per turn | ✅ | spreadRate in config |
| Board saturation limits | ✅ | MAX_ICE, MAX_CHOCOLATE, per‑mode obstacle caps |
| Dead board (no moves) | ⏳ Planned | Potential reshuffle |
| Timed mode transition | ✅ (based on level constant) | Starts at level 15 |
| Extra emojis introduction | ✅ | Starts at level 20 |
| Performance batching | Potential future optimization |
| Category | Idea |
|---|---|
| UX | Animated score popups & chain indicators |
| Mechanics | Power tiles from 4/5 matches (row clear, bomb, color clear) |
| Accessibility | Keyboard navigation & ARIA live region for score |
| Persistence | LocalStorage high scores & session resume |
| Modes | Daily Challenge / Endless Marathon |
| Social | Share final board as emoji grid |
| Analytics | Lightweight event tracking (optional / privacy-first) |
Include:
- Browser & device
- Steps to reproduce
- Expected vs actual
- Console output (if any)
- Screenshot / short clip (if helpful)
Provide:
- Problem / opportunity
- Proposed mechanic or UX pattern
- Balancing or difficulty considerations
git fork
git clone <your-fork>
git checkout -b feature/add-new-obstacle
# Implement & test
git commit -m "Add: magmaVent obstacle"
git push origin feature/add-new-obstacle
# Open Pull Request- Keep functions focused (single responsibility)
- Favor clarity over micro-optimizations
- Align new features with config-driven architecture
- Document new constants in README progression tables
- Test progression (level transitions, obstacle caps)
Licensed under the Apache License 2.0 – see LICENSE.
Summary (not legal advice):
- ✔ Use, modify, distribute
- ✔ Commercial use allowed
- ✔ Must include license & notices
- ✖ No warranty
- Unicode Consortium (emoji set)
- Classic Match‑3 design lineage
- Hosting: Firebase
- Inspiration: Progressive puzzle escalation patterns
| Level | New / Active |
|---|---|
| 5 | Ice begins |
| 8 | Trash appears |
| 10 | Chocolate spreading |
| 12 | Ice bombs |
| 15 | Timed mode activation |
| 16 | Chocolate spawners |
| 20 | Extra emojis introduced |
Developer: @danuaemx
Repository • Live Demo • Issues
⭐ Enjoying EmojiCrush? Star the repo to support development!
Made with 🍒🍇🍋 & lots of ☕ by @danuaemx
Match on! 🍎🍉🍓