ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

纯前端水果消除游戏完整源码(HTML + Canvas,复制即跑)

纯前端水果消除游戏完整源码(HTML + Canvas,复制即跑) 系列第 4 篇(源码篇)。前 3 篇讲了设计思路和用 WorkBuddy 做游戏的过程,这篇把完整可运行源码贴出来。整个游戏是单个 HTML 文件,不依赖任何库,双击用浏览器打开就能玩。怎么用复制下面代码块里的全部内容新建一个fruit-game.html文件,粘贴保存双击用浏览器打开(手机竖屏效果最佳)点顶部「第 X 关」可切换关卡关于换肤图片:第 2 关(三国)、第 3 关(蜡笔小新)依赖图片资源。本文只提供代码、不提供图片,下面的「图片规格与获取」章节告诉你怎么自己准备(不准备也能跑,会自动回退普通水果)。图片规格与获取(作者不提供图片,需自行准备)1. 不准备图片能跑吗?能。源码换肤分支有「加载失败自动回退」逻辑:图片没加载出来时,游戏照常画普通水果,玩法完全不受影响。所以不准备图片也能完整玩通。2. 图片规格项目要求尺寸1024 × 1024(正方形,越大越清晰)格式PNG背景透明(重要,否则头像外会露方块)构图居中头像、正面朝前、圆形或方图均可(代码会圆形裁剪)数量每个皮肤 10 张(对应 10 种类型)命名hero0.png`hero9.png`(三国)、`shin0.png`shin9.png(小新)目录与 html 同级的heroes/和shinchan/3. 目录结构fruit-game.html heroes/ hero0.png ... hero9.png shinchan/ shin0.png ... shin9.png4. 怎么获取图片方式 A:用 AI 生图(推荐)。给 AI 画图工具写提示词,例如:Q版卡通头像贴纸:一个5岁调皮小男孩,圆脑袋粗眉毛,红色短袖,正面朝前居中,日式动画风格,粗黑线条描边,透明背景,无文字无边框把"小男孩"换成你要的角色(刘备/关羽…或蜡笔小新/广志…),生成 10 张,按命名规则存好即可。方式 B:任意 Q 版头像替代。网上找或自己画 10 张透明底头像,按命名放进去就行,不限于三国/小新。5. 换成你自己的皮肤只需两步:① 准备 10 张图放新目录;② 在drawFruit()里加一个if (当前关 == X)分支画你的图。皮肤只改"画什么",不改逻辑。完整源码!DOCTYPEhtmlhtmllang="zh"headmetacharset="UTF-8"metaname="viewport"content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"title水果消消乐 - 物理掉落/titlestyle*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}html, body{margin:0;padding:0;width:100%;height:100%;overflow:hidden;background:#222;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;display:flex;justify-content:center;align-items:center;}#gameWrap{position:relative;width:100%;max-width:480px;height:100%;max-height:960px;background:linear-gradient(180deg,#7bcff7 0%,#a6dff9 35%,#d2efff 70%,#e8f7ff 100%);overflow:hidden;}canvas{display:block;touch-action:none;}#topHud{position:absolute;top:0;left:0;width:100%;height:8%;pointer-events:none;display:flex;justify-content:center;align-items:center;}#levelBadge{background:linear-gradient(180deg,#e040fb 0%,#9c27b0 100%);color:#fff;font-weight:900;font-size:18px;padding:5px 18px;border-radius:20px;border:2px solid #fff;box-shadow:0 3px 8pxrgba(0,0,0,.2);display:flex;align-items:center;gap:4px;}#levelBadge::before{content:'🍓';font-size:14px;}#levelBadge{pointer-events:auto;cursor:pointer;}#levelPicker{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.65);display:none;flex-direction:column;justify-content:center;align-items:center;z-index:20;}#levelPicker h2{color:#fff;font-size:22px;margin-bottom:18px;text-shadow:0 2px 6pxrgba(0,0,0,.4);}.level-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;max-width:320px;}.level-card{pointer-events:auto;cursor:pointer;width:86px;height:86px;border-radius:18px;border:3px solid #fff;background:linear-gradient(180deg,#ffcc80 0%,#ff9800 100%);color:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:13px;font-weight:800;box-shadow:0 5px 0 #e65100,0 7px 12pxrgba(0,0,0,.25);user-select:none;}.level-card:active{transform:translateY(3px);box-shadow:0 2px 0 #e65100;}.level-card.current{background:linear-gradient(180deg,#81d4fa 0%,#0288d1 100%);box-shadow:0 5px 0 #01579b;}.level-card span:first-child{font-size:24px;line-height:1;margin-bottom:4px;}#levelPicker .close-x{pointer-events:auto;cursor:pointer;margin-top:22px;width:48px;height:48px;border-radius:50%;border:3px solid #fff;background:linear-gradient(180deg,#ef9a9a 0%,#e53935 100%);color:#fff;font-size:26px;font-weight:900;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 0 #b71c1c;user-select:none;}#levelPicker .close-x:active{transform:translateY(3px);box-shadow:0 1px 0 #b71c1c;}#propBox{position:absolute;bottom:12px;left:0;width:100%;display:flex;justify-content:space-between;padding:0 18px;pointer-events:none;}.prop-btn{pointer-events:auto;width:68px;height:68px;border-radius:50%;border:3px solid #fff;box-shadow:0 5px 0 #2e7d32,0 7px 10pxrgba(0,0,0,.2);background:linear-gradient(180deg,#8ee06d 0%,#5bc85e 100%);color:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:13px;font-weight:800;cursor:pointer;user-select:none;}.prop-btn:active{transform:translateY(3px);box-shadow:0 2px 0 #2e7d32;}.prop-icon{font-size:24px;line-height:1;}#overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.55);display:none;flex-direction:column;justify-content:center;align-items:center;z-index:10;}#ovTitle{color:#fff;font-size:30px;font-weight:900;margin-bottom:8px;text-shadow:0 2px 6pxrgba(0,0,0,.4);}#ovMsg{color:#ffd;font-size:15px;margin-bottom:24px;}#overlay .ov-btns{display:flex;gap:16px;}.ov-btn{pointer-events:auto;cursor:pointer;border:none;border-radius:24px;padding:12px 26px;font-size:16px;font-weight:800;color:#fff;box-shadow:0 4px 0rgba(0,0,0,.25);}.ov-btn:active{transform:translateY(3px);box-shadow:0 1px 0rgba(0,0,0,.25);}.ov-btn.primary{background:linear-gradient(180deg,#ff8a65,#f4511e);}.ov-btn.ghost{background:linear-gradient(180deg,#90a4ae,#607d8b);}/style/headbodydivid="gameWrap"canvasid="cv"/canvasdivid="topHud"divid="levelBadge"第1关/div/divdivid="propBox"divclass="prop-btn"id="removeBtn"spanclass="prop-icon"💡/spanspan消除/span/divdivclass="prop-btn"id="shuffleBtn"spanclass="prop-icon"🔄/spanspan打乱/span/div/divdivid="overlay"divid="ovTitle"游戏失败/divdivid="ovMsg"篮子里出现了 3 种不同水果/divdivclass="ov-btns"buttonclass="ov-btn primary"id="ovPrimary"重试本关/buttonbuttonclass="ov-btn ghost"id="ovGhost"重新开始/button/div/divdivid="levelPicker"h2选择关卡/h2divclass="level-grid"id="levelGrid"/divdivclass="close-x"id="closeLevelPicker"×/div/div/divscriptconstWRAP=document.getElementById('gameWrap');constcv=document.getElementById('cv'),ctx=cv.getContext('2d');// ===== 布局百分比 =====constLAYOUT={fruitTop:0.045,fruitBottom:0.70,roofOuterY:0.70,roofInnerY:0.80,wallTop:0.80,houseWidth:0.425,gapWidth:0.15,basketTop:0.92,basketBottom:0.995,};// ===== 游戏规则 =====constRULES={baseTypes:10,maxTypes:12,baseCount:6,failureColors:3,elimRule:'topTwo',};functionlevelRules(lv){consttypes=Math.min(RULES.baseTypes+Math.floor((lv-1)/2),RULES.maxTypes);constcountPerType=Math.min(RULES.baseCount+2*(lv-1),12);constclusterProb=Math.max(0.55-(lv-1)*0.05,0.30);constvariance=Math.min(0.20+(lv-1)*0.08,0.65);return{types,countPerType,clusterProb,failureColors:RULES.failureColors,variance};}letW,H,CX,R,BASKET_TOP;letfruits=[];letshaft=[];letfruitQueue=[];leteliminated=0,totalFruits=0;letcurrentLevel=1,seed=1;letgameOver=false,gameWon=false,overlayShown=false;// 第二关三国人物图片资源constHERO_NAMES=['刘备','关羽','张飞','赵云','诸葛亮','马超','黄忠','孙权','周瑜','曹操'];constHERO_IMAGES=[];letheroesLoaded=false;// 第三关蜡笔小新人物图片资源constSHIN_NAMES=['小新','广志','美冴','小葵','小白','风间','妮妮','正男','阿呆','吉永老师'];constSHIN_IMAGES=[];letshinLoaded=false;functionmulberry32(a){returnfunction(){a|=0;a=a+0x6D2B79F5|0;lett=Math.imul(a^a15,1|a);t=t+Math.imul(t^t7,61|t)^t;return((t^t14)0)/4294967296;}}functionloadHeroImages(){if(HERO_IMAGES.length)return;letloaded=0;for(leti=0;iHERO_NAMES.length;i++){constimg=newImage();img.onload=img.onerror=()={loaded++;if(loaded===HERO_NAMES.length)heroesLoaded=true;};img.src=`heroes/hero${i}.png`;HERO_IMAGES.push(img);}}functionloadShinChanImages(){if(SHIN_IMAGES.length)return;letloaded=0;for(leti=0;iSHIN_NAMES.length;i++){constimg=newImage();img.onload=img.onerror=()={loaded++;if(loaded===SHIN_NAMES.length)shinLoaded=true;};img.src=`shinchan/shin${i}.png`;SHIN_IMAGES.push(img);}}functiongetSkinImage(f){if(currentLevel===2heroesLoaded)
返回列表