vue3实现打飞机(雷电)

ops/2024/10/11 9:21:26/

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

<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">javascript">
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>css">
.enemy {box-shadow: 0 2px 4px #0000006e;
}
</style>
<style lang="scss" scoped>css">
.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>

http://www.ppmy.cn/ops/107238.html

相关文章

分享 | 某省级城商行用零信任破解远程访问安全风险

银行建设了各种各样的业务应用系统&#xff0c;不断拓展金融服务的渠道和场景&#xff0c;对远程访问和身份验证的的要求越来越高。零信任架构以其“持续验证、永不信任”的特性&#xff0c;确保只有经过严格身份验证的用户和设备才能访问银行的内部资源&#xff0c;受到了银行…

2024年AI芯片峰会——边缘端侧AI芯片专场

概述 正文 存算一体&#xff0c;解锁大模型的边端侧潜力——信晓旭 当下AI芯片的亟需解决的问题 解决内存墙问题的路径 产品 面向大模型的国产工艺边缘AI芯片创新与展望——李爱军 端侧AI应用“芯”机遇NPU加速终端算力升级——杨磊 边缘端的大模型参数量基本小于100B AI OS…

【如何有效率地阅读源码】

文章目录 前言阅读源码是一项复杂且耗时的任务&#xff0c;但通过一些有效的方法和技巧&#xff0c;可以提高效率和理解度。下面将介绍如何有效率地阅读源码&#xff1a; 一、准备工作二、工具与环境三、逐步深入四、记录与总结五、实践与应用六、持续学习总结 前言 阅读源码是…

ctfshow-nodejs

什么是nodejs Node.js 是一个基于 Chrome V8 引擎的 Javascript 运行环境。可以说nodejs是一个运行环境&#xff0c;或者说是一个 JS 语言解释器 Nodejs 是基于 Chrome 的 V8 引擎开发的一个 C 程序&#xff0c;目的是提供一个 JS 的运行环境。最早 Nodejs 主要是安装在服务器…

自我提升社团成立啦,欢迎各位同学加入~

欢迎加入 大家好&#xff0c;我是马丁&#xff0c;我们的自我提升社团成立啦&#xff0c;欢迎有新的朋友加入&#xff01;&#xff01; 我们的社团主要目标是帮助每个人实现自我成长、自我提升&#xff0c;不论他是什么年龄、什么经验、什么专业&#xff0c;只要有一个好学和…

ASP.NET Core 入门教学六 异常设置

在ASP.NET Core中&#xff0c;异常处理是一个重要的部分&#xff0c;可以帮助我们捕获和处理应用程序中的错误。以下是如何在ASP.NET Core中设置异常处理的步骤&#xff1a; 1. 全局异常处理中间件 ASP.NET Core提供了一个中间件来捕获未处理的异常。你可以在Startup.cs文件中…

ctfshow-php特性(web123-web150plus)

​web123 <?php error_reporting(0); highlight_file(__FILE__); include("flag.php"); $a$_SERVER[argv]; $c$_POST[fun]; if(isset($_POST[CTF_SHOW])&&isset($_POST[CTF_SHOW.COM])&&!isset($_GET[fl0g])){if(!preg_match("/\\\\|\/|\~|…

[pytorch] --- pytorch基础之模型训练套路

0 深度学习模型训练的一般套路 数据处理 数据读取与预处理&#xff1a;从本地或URL读取数据&#xff0c;并进行预处理操作&#xff0c;如数据校验、格式转换等。数据标注与整理&#xff1a;设定合理的标签体系&#xff0c;并对数据进行标注。将标注好的各种标签数据分别存放&…