首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >我用HTML写了个「电蚊拍灭蚊排行系统」,全国各地区PK拍蚊子,谁才是灭蚊战神

我用HTML写了个「电蚊拍灭蚊排行系统」,全国各地区PK拍蚊子,谁才是灭蚊战神

作者头像
零一未来AI星球
发布2026-09-15 19:39:59
发布2026-09-15 19:39:59
760
举报

我用HTML写了个「电蚊拍灭蚊排行系统」,全国各地区PK拍蚊子,谁才是灭蚊战神?

夏天最烦的是什么?不是热,是蚊子!🦟  半夜嗡嗡嗡,起床打不到,开灯就消失,关灯就出现——相信每个人都有被蚊子支配的恐惧。  作为一个程序员,被蚊子咬了怎么办?当然是写个系统出气啊!


一、项目灵感:被蚊子逼出来的脑洞

上周半夜被蚊子咬了三个包,怒从心头起,恶向胆边生。

打不到现实中的蚊子,我还打不到虚拟的吗?

于是一个脑洞诞生了——电蚊拍灭蚊排行系统

  • 蚊子在屏幕上到处乱飞
  • 你用电蚊拍(鼠标)啪啪啪拍死它们
  • 每只蚊子随机归属一个地区、一个用户
  • 拍死后实时统计:总灭蚊数、地区排行榜、用户排行榜
  • 看看哪个省市才是真正的「灭蚊战神」!

二、效果展示:拍蚊子的快乐你想象不到

🎮 核心玩法

打开网页,一群蚊子就在画面里乱窜,翅膀还一抖一抖的,跟真的一样烦。

你只需要——点它!

点中之后:

  • ✨ 爆炸粒子特效四散炸开
  • 📈 飘出「+1 广东省」的计数提示
  • 🏆 排行榜数据实时刷新,排名自动重排
  • 🦟 蚊子当场消失,大快人心

📊 三大统计维度

统计项

说明

总灭蚊数量

全场累计拍死多少只蚊子

地区排行榜

10个省市PK,前三名金银铜高亮

用户排行榜

8位灭蚊达人实时竞争第一

🎯 趣味细节

  • 蚊子碰到边界会反弹,模拟真实逃窜
  • 翅膀高频抖动,还原嗡嗡嗡的烦人感
  • 每只蚊子随机归属地区和用户,每次玩都不一样
  • 竖屏9:16布局,手机电脑都能玩

三、技术实现:纯HTML,零依赖

整个项目只有一个HTML文件,不需要任何框架、不需要后端、不需要安装

双击打开就能玩,复制粘贴就能改。

核心技术点

1. 蚊子飞行动画

代码语言:javascript
复制
// 每帧更新位置,边界反弹
function loopMove(){
    mosquitoList.forEach(mos=>{
        mos.x += mos.vx;
        mos.y += mos.vy;
        if(mos.x <=0 || mos.x >= w-32) mos.vx *= -1;
        if(mos.y <=0 || mos.y >= h-32) mos.vy *= -1;
        mos.dom.style.left = mos.x+'px';
        mos.dom.style.top = mos.y+'px';
    })
    requestAnimationFrame(loopMove);
}

2. 击杀粒子爆炸

代码语言:javascript
复制
// 8个方向粒子扩散
function createParticle(cx,cy){
    for(let i=0;i<8;i++){
        const angle = Math.PI*2/8*i;
        const speed = 40 + Math.random()*30;
        p.animate([
            {left:cx+'px',top:cy+'px',opacity:1},
            {left:endX+'px',top:endY+'px',opacity:0}
        ],{duration:450,fill:'forwards'})
    }
}

3. 排行榜实时排序

代码语言:javascript
复制
// 对象转数组排序,前三名加样式
const areaArr = Object.entries(data.areaStat)
    .sort((a,b)=>b[1]-a[1]);
// idx 0/1/2 分别对应金/银/铜高亮

四、完整源码:直接复制就能跑

代码语言:javascript
复制
<!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;
            font-family: "Microsoft Yahei", sans-serif;
        }
        body {
            width: 100vw;
            height: 100vh;
            max-width: 450px;
            margin: 0 auto;
            background: linear-gradient(135deg,#0f172a,#1e293b);
            color:#fff;
            overflow: hidden;
            user-select:none;
        }
        .header{
            text-align:center;
            padding:12px;
            background:rgba(56,189,248,0.15);
            border-bottom:1px solid #38bdf844;
        }
        .header h1{
            font-size:20px;
            color:#38bdf8;
        }
        .total-info{
            display:flex;
            justify-content: space-around;
            padding:10px 0;
            font-size:14px;
        }
        .total-item{
            text-align:center;
        }
        .total-num{
            font-size:22px;
            color:#facc15;
            font-weight:bold;
        }
        #gameBox{
            position:relative;
            width:100%;
            height:42vh;
            background:#0b1220;
            border:1px solid #38bdf833;
            overflow:hidden;
        }
        .mosquito{
            position:absolute;
            width:32px;
            height:32px;
            font-size:28px;
            cursor:crosshair;
            transition:transform 0.08s;
            z-index:2;
        }
        .mosquito-shake{
            animation: shake 0.12s infinite;
        }
        @keyframes shake{
            0%{transform:rotate(-8deg)}
            100%{transform:rotate(8deg)}
        }
        .particle{
            position:absolute;
            width:6px;
            height:6px;
            border-radius:50%;
            background:#facc15;
            pointer-events:none;
        }
        .kill-float-num{
            position:absolute;
            color:#f87171;
            font-weight:bold;
            font-size:18px;
            pointer-events:none;
            animation: floatUp 0.7s forwards;
        }
        @keyframes floatUp{
            0%{opacity:1;transform:translateY(0)}
            100%{opacity:0;transform:translateY(-60px)}
        }
        .rank-wrap{
            height:calc(58vh - 120px);
            overflow-y:auto;
            padding:10px;
        }
        .rank-title{
            font-size:16px;
            margin:8px 0;
            color:#38bdf8;
            display:flex;
            align-items:center;
            gap:6px;
        }
        .rank-item{
            display:flex;
            justify-content:space-between;
            padding:8px 10px;
            background:rgba(255,255,255,0.06);
            margin:4px 0;
            border-radius:6px;
            font-size:14px;
        }
        .rank-top1{background:rgba(250,204,21,0.2);}
        .rank-top2{background:rgba(156,163,175,0.25);}
        .rank-top3{background:rgba(180,83,9,0.25);}
        .btn-area{
            text-align:center;
            padding:8px;
        }
        button{
            padding:8px 16px;
            border:none;
            border-radius:6px;
            background:#2563eb;
            color:white;
            font-size:14px;
            margin:0 4px;
        }
</style>
</head>
<body>
    <div class="header">
        <h1>🦟电蚊拍灭蚊排行系统</h1>
        <div class="total-info">
            <div class="total-item">
                <div>总灭蚊数量</div>
                <div class="total-num" id="totalKill">0</div>
            </div>
            <div class="total-item">
                <div>场内蚊子</div>
                <div class="total-num" id="liveMos">0</div>
            </div>
        </div>
    </div>
    <div id="gameBox"></div>
    <div class="btn-area">
        <button onclick="spawnMosquito(6)">🦟生成一批蚊子</button>
        <button onclick="resetAll()">🔄重置数据</button>
    </div>
    <div class="rank-wrap">
        <div class="rank-title">📍地区灭蚊排行榜</div>
        <div id="areaRank"></div>
        <div class="rank-title">👤用户灭蚊排行榜</div>
        <div id="userRank"></div>
    </div>
<script>
const areaList = ["广东","重庆","江苏","浙江","湖南","湖北","四川","广西","江西","安徽"];
const userPool = ["灭蚊战神","拍蚊小能手","夏夜斗士","驱蚊大队长","蚊子天敌","夜间猎手","电蚊拍大师","夏日守护者"];
let data = {
    totalKill:0,
    areaStat:{},
    userStat:{}
};
areaList.forEach(a=>{ data.areaStat[a] = 0; })
userPool.forEach(u=>{ data.userStat[u] = Math.floor(Math.random()*15); })
const gameBox = document.getElementById('gameBox');
let mosquitoList = [];
function renderRank(){
    const areaArr = Object.entries(data.areaStat).sort((a,b)=>b[1]-a[1]);
    let areaHtml = '';
    areaArr.forEach((item,idx)=>{
        let cls = '';
        if(idx===0) cls='rank-top1';
        else if(idx===1) cls='rank-top2';
        else if(idx===2) cls='rank-top3';
        areaHtml += `<div class="rank-item {idx+1}. {item[1]}只</span>
        </div>`
    })
    document.getElementById('areaRank').innerHTML = areaHtml;
    const userArr = Object.entries(data.userStat).sort((a,b)=>b[1]-a[1]);
    let userHtml = '';
    userArr.forEach((item,idx)=>{
        let cls = '';
        if(idx===0) cls='rank-top1';
        else if(idx===1) cls='rank-top2';
        else if(idx===2) cls='rank-top3';
        userHtml += `<div class="rank-item {idx+1}. {item[1]}只</span>
        </div>`
    })
    document.getElementById('userRank').innerHTML = userHtml;
    document.getElementById('totalKill').innerText = data.totalKill;
    document.getElementById('liveMos').innerText = mosquitoList.length;
}
function spawnMosquito(count){
    for(let i=0;i<count;i++){ createOneMosquito(); }
    renderRank();
}
function createOneMosquito(){
    const el = document.createElement('div');
    el.className = 'mosquito mosquito-shake';
    el.innerText = '🦟';
    const w = gameBox.clientWidth;
    const h = gameBox.clientHeight;
    let x = Math.random()*(w-40);
    let y = Math.random()*(h-40);
    el.style.left = x+'px';
    el.style.top = y+'px';
    let vx = (Math.random()-0.5)*2.2;
    let vy = (Math.random()-0.5)*2.2;
    const areaRandom = areaList[Math.floor(Math.random()*areaList.length)];
    const userRandom = userPool[Math.floor(Math.random()*userPool.length)];
    const mosObj = { dom:el, x,y,vx,vy, area:areaRandom, user:userRandom }
    mosquitoList.push(mosObj);
    el.onclick = (e)=>{
        e.stopPropagation();
        killMosquito(mosObj);
    }
    gameBox.appendChild(el);
}
function killMosquito(mosObj){
    const idx = mosquitoList.indexOf(mosObj);
    if(idx===-1) return;
    mosquitoList.splice(idx,1);
    data.totalKill +=1;
    data.areaStat[mosObj.area] +=1;
    if(!data.userStat[mosObj.user]) data.userStat[mosObj.user]=0;
    data.userStat[mosObj.user] +=1;
    showKillNum(mosObj.x,mosObj.y,mosObj.area);
    createParticle(mosObj.x+16, mosObj.y+16);
    mosObj.dom.remove();
    renderRank();
}
function showKillNum(x,y,areaName){
    const div = document.createElement('div');
    div.className = 'kill-float-num';
    div.innerText = `+1 ${areaName}`;
    div.style.left = x+'px';
    div.style.top = y+'px';
    gameBox.appendChild(div);
    setTimeout(()=>div.remove(),700);
}
function createParticle(cx,cy){
    for(let i=0;i<8;i++){
        const p = document.createElement('div');
        p.className='particle';
        p.style.left = cx+'px';
        p.style.top = cy+'px';
        gameBox.appendChild(p);
        const angle = Math.PI*2/8*i;
        const speed = 40 + Math.random()*30;
        const endX = cx + Math.cos(angle)*speed;
        const endY = cy + Math.sin(angle)*speed;
        p.animate([
            {left:cx+'px',top:cy+'px',opacity:1},
            {left:endX+'px',top:endY+'px',opacity:0}
        ],{duration:450,fill:'forwards'})
        setTimeout(()=>p.remove(),450);
    }
}
function loopMove(){
    const w = gameBox.clientWidth;
    const h = gameBox.clientHeight;
    mosquitoList.forEach(mos=>{
        mos.x += mos.vx;
        mos.y += mos.vy;
        if(mos.x <=0 || mos.x >= w-32) mos.vx *= -1;
        if(mos.y <=0 || mos.y >= h-32) mos.vy *= -1;
        mos.dom.style.left = mos.x+'px';
        mos.dom.style.top = mos.y+'px';
    })
    requestAnimationFrame(loopMove);
}
function resetAll(){
    mosquitoList.forEach(m=>m.dom.remove());
    mosquitoList = [];
    data.totalKill =0;
    areaList.forEach(a=>data.areaStat[a]=0);
    userPool.forEach(u=>data.userStat[u]=Math.floor(Math.random()*8));
    renderRank();
}
loopMove();
spawnMosquito(5);
renderRank();
</script>
</body>
</html>

五、怎么玩?三步搞定

  1. 复制上面全部代码
  2. 新建一个文本文档,粘贴进去,保存为 灭蚊排行.html
  3. 双击文件,用浏览器打开——开玩!

操作说明:

  • 🦟 点击「生成一批蚊子」放出猎物
  • 👆 用鼠标点击蚊子就是拍死它
  • 🏆 看排行榜实时变化,哪个地区能拿第一?
  • 🔄 玩腻了点重置,重新开局

六、还能怎么玩?扩展思路

这个小项目虽然简单,但扩展性很强:

🎵 加音效

  • 拍打时的「啪」电击声
  • 蚊子嗡嗡嗡的背景音
  • 破纪录的欢呼声

🎮 加玩法

  • 限时模式:30秒内看你能拍多少只
  • 难度递增:蚊子越拍越快
  • 道具系统:杀虫剂、电蚊拍升级

📊 加功能

  • 接入后端,全国玩家联网PK
  • 地图热力图,直观展示各地区灭蚊战力
  • 成就系统,解锁各种灭蚊称号

📱 加适配

  • 触屏支持,手机上也能啪啪啪
  • 分享功能,把战绩甩到朋友圈

七、写在最后

程序员的快乐有时候就是这么简单——

被蚊子咬了 → 写个灭蚊游戏出气 → 顺便练了前端动画 → 还能发个朋友圈装逼。

一个几十KB的HTML文件,没有复杂的架构,没有高深的算法,但就是好玩。

这大概就是编程的魅力吧——想到什么,就能做出来什么。

你的家乡灭蚊战斗力排第几?  快去试试,评论区报出你的最高纪录!🏆

🔖 收藏本文,下次被蚊子咬了拿出来泄愤! 👆 点赞关注,更多有趣的前端小项目持续更新!

#前端 #趣味编程 #HTML #程序员日常 #灭蚊大战 #小项目

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-08-17,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 我用HTML写了个「电蚊拍灭蚊排行系统」,全国各地区PK拍蚊子,谁才是灭蚊战神?
    • 一、项目灵感:被蚊子逼出来的脑洞
    • 二、效果展示:拍蚊子的快乐你想象不到
      • 🎮 核心玩法
      • 📊 三大统计维度
      • 🎯 趣味细节
    • 三、技术实现:纯HTML,零依赖
      • 核心技术点
    • 四、完整源码:直接复制就能跑
    • 五、怎么玩?三步搞定
    • 六、还能怎么玩?扩展思路
      • 🎵 加音效
      • 🎮 加玩法
      • 📊 加功能
      • 📱 加适配
    • 七、写在最后
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档