作者:FrigidWinter
简介:主攻机器人与人工智能领域的理论研究和工程应用,业余丰富各种技术栈。主要涉足:【机器人(ROS)】【机器学习】【深度学习】【计算机视觉】
专栏:
红包也叫压岁钱,是过农历春节时长辈给小孩儿用红纸包裹的礼金。据传明清时期,压岁钱大多数是用红绳串着赐给孩子。民国以后,则演变为用红纸包裹。中国的红包传统民族文化在民间如此,社区、公司也奉行如仪。除了春节以外,在其他喜庆场合,例如婚礼、新店开张等亦有送红包的习俗。
本期迎新春专题用代码制作一个 红包雨小游戏 ,效果如下所示。看完本文相信你也可以完成这样一个小游戏设计。
使用 Vue 构建工程。流程为
从网络上下载一些喜庆的图片作为背景和红包样式,这些样式可以任选,给想整活的同学们充足的自由度。
html样式很简单,主要分为两个部分:红包雨 和 抢红包面板。
<div id="wrapper">div>
<div id="panel">
<div id="hb">
<span id="text">{{ result }}span>
<div id="btn" @click="gameOn">继续抢红包div>
div>
div>
CSS样式稍微复杂一些,放在下文完整代码中,需要的自取。其中比较少用的是annimation
动画渲染样式
animation: dropDowm 3s forwards; /* 旋转动画 */
@keyframes dropDowm {
0% {
top: 0px;
transform: translateY(-100%) rotate(0deg);
}
100% {
top: 110%;
transform: translateY(0%) rotate(360deg);
}
}
这里讲解一下,annimation
常见参数如下:
alternate
(间隔运动)、 reverse
(反向运动)、reverse-alternate
(反向间隔运动)forwards
(动画停止在最后一个关键帧的位置)、backwards
(动画第一个关键帧立即执行)、both
(第一个关键帧也停止在最后一个关键帧)设计完成后运行结果如下图所示,分别为背景和面板。
程序的逻辑如下所示
上述最关键的就是监听用户抢红包的行为,并判断是否抢到了红包,监听函数设计如下所示,如果成功抢到红包,则总金额自动累加。
mouseHandler(e) {
var event = e || window.event,
money = event.target.dataset.money;
if (money) {
this.result = "恭喜抢到红包" + money + "元";
for (var i = 0, len = this.imgList.length; i < len; i++) {
this.imgList[i].style.animationPlayState = "paused";
}
panel.style.display = "block";
this.totalMoney += Number(money);
}
}
接下来要考虑如何让红包随机掉落,核心代码如下:
for (var i = 0; i < num; i++) {
let img = new Image();
img.src = this.imgUrl;
// 随机设置红包分布
img.style.left = this.ranNum(0, window.innerWidth) + "px";
let delay = this.ranNum(0, 100) / 10;
// 设置红包出现时间
img.style.animationDelay = delay + "s";
if (this.delayTime < delay) {
this.delayTime = delay;
this.lastImg = img;
}
//设置每个红包的金额
img.dataset.money = this.ranNum(0, 1000) / 100;
其他函数基本都是服务于这两个核心功能的,这里不赘述。
<template>
<div id="app">
<div id="wrapper">div>
<div id="panel">
<div id="hb">
<span id="text">{{ result }}span>
<div id="btn" @click="gameOn">继续抢红包div>
div>
div>
div>
template>
<script>
export default {
name: "App",
data() {
return {
totalMoney: 0, // 所有抢到红包的总金额
delayTime: 0, // 延时
lastImg: null, // 最后一张掉落的图片
imgList: null, // 红包随机序列
result: "", // 游戏结果
imgUrl: require("./assets/hongbao.jpg"),
};
},
methods: {
// @breif:开始游戏
start() {
let dom = this.createDom(20);
this.imgList = document.getElementsByTagName("img");
document.getElementById("wrapper").appendChild(dom);
},
// @breif: 创建红包序列
createDom(num) {
// 创建文档碎片
let frag = document.createDocumentFragment();
for (var i = 0; i < num; i++) {
let img = new Image();
img.src = this.imgUrl;
// 随机设置红包分布
img.style.left = this.ranNum(0, window.innerWidth) + "px";
let delay = this.ranNum(0, 100) / 10;
// 设置红包出现时间
img.style.animationDelay = delay + "s";
if (this.delayTime < delay) {
this.delayTime = delay;
this.lastImg = img;
}
//设置每个红包的金额
img.dataset.money = this.ranNum(0, 1000) / 100;
frag.appendChild(img);
}
return frag;
},
// @breif:继续游戏
gameOn() {
document.getElementById("panel").style.display = "none";
for (let i = 0, len = this.imgList.length; i < len; i++) {
this.imgList[i].style.animationPlayState = "running";
}
},
// 监听鼠标事件
mouseHandler(e) {
var event = e || window.event,
money = event.target.dataset.money;
if (money) {
this.result = "恭喜抢到红包" + money + "元";
for (var i = 0, len = this.imgList.length; i < len; i++) {
this.imgList[i].style.animationPlayState = "paused";
}
panel.style.display = "block";
this.totalMoney += Number(money);
}
},
// 监听动画事件
annimationHandler(e) {
document.getElementById("panel").style.display = "block";
this.result = "恭喜总共抢到了" + this.totalMoney.toFixed(2) + "元";
},
// @breif:产生min~max间的随机数
ranNum(min, max) {
return Math.ceil(Math.random() * (max - min) + min);
},
},
mounted() {
this.start();
window.addEventListener("mousedown", this.mouseHandler);
this.lastImg.addEventListener("webkitAnimationEnd", this.annimationHandler);
},
};
</script>