当前位置: 首页 > news >正文

vue3实现打飞机(雷电)

代码可直接运行直接玩,而且要自己加上一些随机事件都很简单了(例如发射速度变快,子弹变大,敌人变慢等)

<template><div class="flex items-center justify-center h-100vh w-full"><div>SCORE: {{ score }}<div class="box w-400 h-500 relative p-8" ref="box"><divclass="tank-wrap absolute bottom-6"ref="tankWrap":style="{ left: tankLeft + 'px' }"><div class="tank" :style="{ width: tankWidth + 'px' }"></div></div></div></div></div>
</template><script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
const box = ref();
const tankWidth = 40;
const tankWrap = ref();/*** 左右方向键控制坦克*/
const tankLeft = ref<number>(150);
function mousemove(e: MouseEvent) {const boxRect = box.value.getBoundingClientRect();if (!boxRect) return;const left = e.clientX - boxRect.left;if (left < 0) {tankLeft.value = 0;} else if (left > boxRect.width - tankWidth) {tankLeft.value = boxRect.width - tankWidth;} else {tankLeft.value = left;}
}
/*** 发射子弹*/
function start() {const tankWrapRect = tankWrap.value.getBoundingClientRect();const boxRect = box.value.getBoundingClientRect();const bullet = document.createElement("div");bullet.className ="fixed top-0 left-0 w-6 h-6 bg-red-500 border-rd-50% bullet";// 加上一半的坦克宽度,再减去一半的自身宽度bullet.style.left = tankWrapRect.left + tankWidth / 2 - 3 + "px";bullet.style.top = tankWrapRect.top + "px";box.value.appendChild(bullet);let top = 0;const timer = setInterval(() => {top += 5;const result = tankWrapRect.top - top;bullet.style.top = result + "px";if (result < boxRect.top) {clearInterval(timer);bullet.remove();}}, 16);
}
const score = ref(0);
/*** 生成敌人*/
const enemyCreator = () => {const boxRect = box.value.getBoundingClientRect();const enemy = document.createElement("div");//  宽度10-75px随机const enemyWidth = Math.floor(Math.random() * 66) + 10;const enemyHeight = Math.floor(Math.random() * 25) + 5;enemy.style.width = enemyWidth + "px";enemy.style.height = enemyHeight + "px";// 0% 到 50%随机enemy.style.borderRadius = Math.floor(Math.random() * 51) + "%";enemy.style.backgroundColor = `rgb(${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)})`;enemy.className = "fixed enemy";//boxRect.left 到 (boxRect.left + boxRect.width) 之间的随机数enemy.style.left =Math.floor(Math.random() * (boxRect.width - enemyWidth)) +boxRect.left +"px";enemy.style.top = boxRect.top + "px";box.value.appendChild(enemy);let top = 0;const speed = Math.floor(Math.random() * 7) + 2;let timer: any = setInterval(() => {top += speed;enemy.style.top = boxRect.top + top + "px";/*** 检测碰撞敌人*/const enemies = document.querySelectorAll(".fixed.enemy");const bullets = document.querySelectorAll(".fixed.bullet");for (let i = 0; i < bullets.length; i++) {const bulletRect = bullets[i].getBoundingClientRect();if (bulletRect.left < enemy.getBoundingClientRect().right &&bulletRect.right > enemy.getBoundingClientRect().left &&bulletRect.top < enemy.getBoundingClientRect().bottom &&bulletRect.bottom > enemy.getBoundingClientRect().top) {clearInterval(timer);score.value ++;bullets[i].remove();enemy.remove();}}if (enemy && boxRect.top + top + enemyHeight > boxRect.bottom) {alert("你已经输了");clearInterval(timer);window.location.reload();}}, 30);
};let fireTimer: any = null;
let enemyTimer: any = null;
onMounted(() => {document.addEventListener("mousemove", mousemove);fireTimer = setInterval(() => {start();}, 260);enemyTimer = setInterval(() => {enemyCreator();}, 750);
});
const clear = () => {document.removeEventListener("mousemove", mousemove);clearInterval(fireTimer);clearInterval(enemyTimer);
};
onUnmounted(() => {clear();
});
</script>
<style>
.enemy {box-shadow: 0 2px 4px #0000006e;
}
</style>
<style lang="scss" scoped>
.box {border-radius: 4px;border: 1px solid #adadad;background: #ccc;overflow: hidden;
}
// tank-head-percentage
$t-h: 40%;
.tank-wrap {filter: drop-shadow(0 4px 2px #1c0099cc);.tank {height: 40px;border-radius: 8px;background-image: linear-gradient(90deg, #0b33b6 0%, #aaf2ff 100%);clip-path: polygon(0 58%,36% $t-h,36% 20%,50% 0%,64% 20%,64% $t-h,100% 58%,100% 100%,0 100%);}
}
</style>

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • HTML 超链接
  • 常见的正则化方法以及L1,L2正则化的简单描述
  • ELK学习笔记(三)——使用Filebeat8.15.0收集日志
  • 【大模型理论篇】大模型周边自然语言处理技术(NLP)原理分析及数学推导(Word2Vec、TextCNN、FastText)
  • 常见的pytest二次开发功能
  • 垃圾回收概述及算法
  • 机器学习之 PCA降维
  • 外排序之文件归并排序实现
  • 解锁 macOS 剪贴板历史记录,高效复制、粘贴技巧
  • Maven项目父模块POM中不应包含实际依赖(dependency)
  • 【Clickhouse】Clickhouse数据库简介
  • 如何选择web服务
  • Spring Boot Admin集成与自定义监控告警
  • HOT100(九)多维动态规划
  • EmguCV学习笔记 VB.Net 11.3 DNN其它
  • CAP 一致性协议及应用解析
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • Git 使用集
  • interface和setter,getter
  • Java应用性能调优
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • React16时代,该用什么姿势写 React ?
  • SegmentFault 2015 Top Rank
  • 缓存与缓冲
  • 利用DataURL技术在网页上显示图片
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 排序(1):冒泡排序
  • 设计模式(12)迭代器模式(讲解+应用)
  • 使用 QuickBI 搭建酷炫可视化分析
  • 我看到的前端
  • 我这样减少了26.5M Java内存!
  • 小程序button引导用户授权
  • ### RabbitMQ五种工作模式:
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (c语言版)滑动窗口 给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (力扣)1314.矩阵区域和
  • (篇九)MySQL常用内置函数
  • (七)理解angular中的module和injector,即依赖注入
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (十三)MipMap
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)LINQ之路
  • (转)用.Net的File控件上传文件的解决方案
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • ..回顾17,展望18
  • ./configure,make,make install的作用(转)
  • .Net mvc总结
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net Stream篇(六)