就是一个简单的射击游戏,应用于h5页面。点击屏幕实现弓箭x轴移动,箭射出,靶子左右浮动,碰撞时停止。
看看代码吧,简单的几个div()
<div class="target" ref="target"></div> //移动靶
<div class="bow" ref="bow"> //弓
<div class="arrow" ref="arrow" v-show="showArrowClass"></div> //箭
<div class="line"></div> //弓弦,之前想做允许用户拖拽弓弦来瞄准方向和射击力度,由于时间紧张就没做这块
</div>
样式比较简单可自行调节,这里就不上传过多样式了。
.target {
position: absolute;
top: 5em;
width: 9em;
height: 4em;
left: 50%;
margin-left: -4.5em;
background-image: url(图像地址);
background-size: cover;
background-repeat: no-repeat;
animation: move 10s linear infinite;
}
/* 定义动画关键帧 */
@keyframes move {
0% {
left: 0px;
}
50% {
left: 100%;
}
100% {
left: 0px;
}
}
点击屏幕事件,在最外层div 帮个点击事件就行
shootArrow(event) {
const bowElement = this.$refs.bow;
const bowRect = bowElement.getBoundingClientRect();
this.bowInitialX = bowRect.left + bowRect.width / 2;
if( !this.bowInitialY ){
this.bowInitialY = bowRect.top + bowRect.height / 2;
}
//当前弹出打开 或者已经有飞行状态,禁止再次发射
if (this.showAlert || this.isStatus) return;
this.isStatus = true;
const clickX = event.clientX;
const clickY = event.clientY;
// const bowElement = this.$refs.bow;
// 计算点击位置与弓中心的Y轴偏移
const offsetX = clickX - this.bowInitialX;
this.bowInitialX = offsetX + this.bowInitialX;
bowElement.style.position = "static";
bowElement.style.transform = `translate(${clickX}px, ${this.bowInitialY}px)`;
if (!this.isArrowFlying) {
this.isArrowFlying = true;
this.animateArrow(0, clickY);
}
},
动画animateArrow代码
animateArrow(offsetX, offsetY) {
const arrowElement = this.$refs.arrow;
const arrowSpeed = 20;
const animate = () => {
if (this.isArrowFlying) {
this.arrowY += arrowSpeed;
const targetElement = this.$refs.target;
const targetRect = targetElement.getBoundingClientRect();
const arrowRect = arrowElement.getBoundingClientRect();
if (
arrowRect.right >= targetRect.left &&
arrowRect.left <= targetRect.right &&
arrowRect.bottom >= targetRect.top &&
arrowRect.top <= targetRect.bottom
) {
// 靶子与箭重叠,暂停动画
this.showArrowClass = false;
arrowElement.style.animationPlayState = "paused";
targetElement.style.animationPlayState = "paused";
this.isStatus = false;
this.isArrowFlying = false;
this._showLoading();
this.remainingNumber = this.chanceAccount? this.chanceAccount :this.remainingNumber ;
console.log( this.remainingNumber, this.chanceAccount,":chanceAccount")
if( this.remainingNumber > 0){
this.initNumber = true;
this.getPrize();
}else{
this.showTips = true;
this.initNumber = false;
this._dismissLoading();
}
this.arrowX = 0;
this.arrowY = 0;
arrowElement.style.transform = `translate(${this.arrowX}px, ${this.arrowY}px)`;
return;
}
arrowElement.style.transform = `translate(${this.arrowX}px, -${Math.abs(this.arrowY)}px)`
if (this.arrowY > (window.innerHeight + 200)) {
this.showArrowClass = false;
this.arrowX = 0;
this.arrowY = 0;
arrowElement.style.transform = `translate(${this.arrowX}px, ${this.arrowY}px)`;
this.isArrowFlying = false;
setTimeout(() => {
// 在延时结束后执行的操作
this.isStatus = false;
this.showArrowClass = true;
this.message = "定时器已触发!";
}, 100); // 2000毫秒(2秒)后执行操作
// 箭击中目标或飞出边缘后,重置箭的位置
}
requestAnimationFrame(animate); // 在此处继续请求动画帧
}
};
animate();
},
由于像素原原因,有可能存在偏差,所以设计方式只允许y轴改变,没有做斜射方向。具体样式和图片可自行调试