“我正在参加「初夏创意投稿大赛」详情请看:初夏创意投稿大赛”
夏天这个季节让人讨厌却又恨不起来,干燥炎热的天气让人烦闷,但是我们可以在空调间里尽情的享受冰凉的果饮。
游戏简介
这个小游戏的游戏规则很简单,就是给你一杯按顺序调配好的饮料,你需要在规定的时间内记住饮料调配的顺序,然后在规定的时间内将这杯饮料调配出来。这个游戏难度分三级,简单、较难和超难,主要是饮料的层数不同,短时间内记忆的难度不同。
代码讲解
主要核心
- 杯子和倾倒果汁的动画
- 随机生成一杯饮料
- 计时器功能
- 计算分数,弹窗播报
- 组合游戏场景
杯子和倾倒果汁的动画
先用css画一个空杯子,这个杯子是用来盛果汁原材料的
.empty-cup { width: var(--cup-w); height: var(--cup-h); border-radius: 0 0 20px 20px; background-color: var(--cup-bg); }
然后是盛果汁后的样式,里面的果汁高度略小于杯子
水果图案取材于iconfont
接下来是倾倒果汁的动画
果汁上方的三角形是伪类元素通过border-width宽度变化来进行遮挡,里面液体的高度随着倾倒逐渐变大到100%,最后在瓶口用伪类元素作出一个长条液体流出的动画。
当第二个border-width参数为0时,会形成直角三角形,如图
.dumping .juice::before { content: ""; display: block; width: 0; height: 0; border: 60px solid transparent; border-width: 105px 0px 45px 65px; border-top-color: var(--cup-bg); position: absolute; top: -1px; right: -1px; animation: fall 1s linear forwards; animation-delay: 1s; opacity: 0;}
动画,改变边框的宽度大小可以修改三角形的边长度:
@keyframes fall { from { border-width: 35px 0px 45px 35px; opacity: 1; } to { border-width: 105px 0px 45px 65px; opacity: 1; } }
液体流出:
.dumping .juice::after { content: ""; display: block; width: 5px; height: 0; background-color: var(--juice); position: absolute; top: 0px; left: 5px; transform: rotate(95deg); transform-origin: top; border-top-left-radius: 5px; animation: fall3 1s linear forwards; animation-delay: 2s; // 延迟执行 }
@keyframes fall3 { 0% { height: 0; } 50% { height: 80px; } 100% { height: 80px; } }
装调配饮料的杯子,我们和装材料的杯子略有所不同,这个我们用逼格比较高的高脚杯:
高脚杯的“脚”用伪类元素来拼接,这个很简单就不放代码了。
随机生成一杯饮料
杯子和果汁的代码设计好之后,我们开始随机生成饮料配方
首先,给定一个原材料数组
this.juices = [ { title: "猕猴桃", color: "#00bc12", icon: "icon-mihoutao" }, { title: "樱桃", color: "#f00056", icon: "icon-yingtao" }, { title: "香蕉", color: "#ffc773", icon: "icon-xiangjiao" }, { title: "苹果", color: "#dc3023", icon: "icon-pingguo" }, { title: "橘子", color: "#ff7500", icon: "icon-juzi" }, { title: "葡萄", color: "#801dae", icon: "icon-putao" }, { title: "椰子", color: "#edd1d8", icon: "icon-yezi" }, { title: "青提", color: "#7bcfa6", icon: "icon-tizi" }, { title: "草莓", color: "rgb(255, 0, 75)", icon: "icon-icon-test" }, { title: "蓝莓", color: "rgb(89, 152, 216)", icon: "icon-lanmei" }, ];
我们根据难易程度层数分别随机生成一个索引值,为了避免重复我们要删掉已经调配的果汁
for (let i = 0; i < this.level; i++) { const index = Math.floor(Math.random() * juices.length); this.fruitJuice.push(juices[index]);
juices.splice(index, 1);}
计时器功能
因为记忆饮料顺序和配置饮料都有时间限制,所以我们要做一个计时器:
这个计时器是svg动画,通过stroke-dasharray、stroke-dashoffset两个属性,作出圆圈边收缩的效果。stroke-dasharray的大小可以通过getTotalLength函数计算。
#timer { stroke-dasharray: 141;}@keyframes rotate { 0% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: 141; }}
<svg> <path id="timer" d="M 25.5 3 A 4.5 4.5 90 0 0 25.5 48 A 4.5 4.5 90 0 0 25.5 3 Z" fill="transparent" stroke="black" strokeDasharray="141" ></path> <text x="15" y="30" fill="#666"></text> </svg>
计算分数,弹窗播报
当你调配好了一杯饮料后,判断你调配的数组和原先随机生成的果汁数组顺序是否一致。
checkCorrect() { if (this.yourJuice.length == this.fruitJuice.length) { let flag = true; for (let i = 0; i < this.yourJuice.length; i++) { if (this.yourJuice[i].color !== this.fruitJuice[i].color) { this.gameOver("很遗憾,你调的果汁不对哦!"); flag = false; break; } } if (flag) { this.score += this.currentScore; this.setScore(); this.gameOver("恭喜你通关,调配的果汁很不错哦!", true); } } }
计算之后,我们需要弹窗播报结果
弹窗左侧放上需要调配的饮料,方便做对比,这块代码样式不需要额外写,只需要缩放杯子的大小即可。
这里有一点要注意的是,我们需要在动画结束之后才能播报结果,否则会出现果汁还没倒进杯子里,游戏就结束了。
组合游戏场景
要做成一个完整的游戏,需要有一个完整的游戏场景,第一步是首页设计,主要展示游戏名称和游戏按钮,第二步就是生成一杯需要调配的果汁,第三步到调配果汁界面。
按照这个思路,写一个游戏的类,大概是这样子的:
有兴趣的朋友,源码链接戳这里☜