700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Vue 开发一个简略版的飞机大战小游戏

Vue 开发一个简略版的飞机大战小游戏

时间:2022-05-08 17:28:04

相关推荐

Vue 开发一个简略版的飞机大战小游戏

文章目录

使用 Vue 开发一个简略版的飞机大战小游戏一、实现思路二、所需知识点三、实现步骤

使用 Vue 开发一个简略版的飞机大战小游戏

如题,假设你为了向更多访问你博客的人展示你的技术,你决定小试身手开发一个飞机大战小游戏。

功能: 开始游戏前用户名必填,玩家可以发射子弹,敌军与行星随机出现,鼠标可操控玩家移动,敌军可发射子弹


一、实现思路

如题所述:

玩家可操控玩家飞机可发射子弹,敌军与行星随机生成;

这意味着我们需要一个单独的玩家飞机dom,以及敌军、行星与子弹 用 vue 循环生成的3个dom。

敌军与行星生成后的dom的位置由数据里的 x 与 y 值决定。

按下空格时产生的子弹由当时按下空格键的时候的飞机的位置来决定。

敌军随机发射的子弹由当时发射子弹的敌军的位置来决定。

游戏开始时用户名必填,那么我们只需要在 Vue 实例里为该 input 绑定一个数据,再为开始游戏按钮绑定点击事件。随后计算用户名的长度只要大于3,就调用游戏开始函数或初始化函数。

玩家鼠标操控移动飞机移动只需要为其父节点绑定鼠标移动事件,然后更改 player 里的 x 与 y 的数据 (x与y的值不能小于0,x与y的值不能大于父节点的宽高) 并且赋予 玩家飞机即可。

击毁敌军只需要拿 子弹与敌军 的 x,y 计算对比即可。

二、所需知识点

Vue 事件绑定Vue 监听事件Vue 计算属性Vue Style操作

三、实现步骤

第一步:创建 HTML 与 CSS 文件

HTML

<!DOCTYPE html><html><head><meta charset="utf-8"><title>Vue 飞机大战</title><link rel="stylesheet" href="css/style.css"></head><body><main>-<div class="game-plane" @mousemove="touchmove":style="{backgroundPosition:'0px '+ positionY +'px'}" ref='plane'><div id="hit"><h2>击毁:{{ hitCount }}</h2><h2>与敌机相撞:{{ boom }}</h2><h2>被击中次数:{{ HitTimes }}</h2><h2>用户名:{{ username }}</h2></div><!-- 玩家 --><img src="image/player.png" alt="player" id="p" :style="{top:p.y + 'px',left:p.x+'px'}"><!-- 星球 --><img v-for="(item,index) of plane.arr" :style="{top:item.y + 'px',left:item.x+'px'}" src="image/plane.png" alt="plane"><!-- 敌军 --><img v-for="(item,index) of e.arr" :style="{top:item.y + 'px',left:item.x+'px'}" src="image/e.png" class="e" alt="e"><!-- 子弹 --><img v-for="(item,index) of bullets.arr" class="b":style="{top:item.y + 'px',left:item.x+'px'}" :src="item.tag == 'p' ? 'image/p_b.png' : 'image/e_b.png' " alt="p_b"></div><!-- 开始面板 --><div class="alert" ref="alert"><div class="content"><div class="left"><h1>Vue 飞机大战</h1><p>作者:柴不是柴</p><img :src="faceChange" class="face"></div><div class="right"><input type="text" v-model="username" placeholder="请输入你的名字"><input type="submit" @click="startBtnClick" value="开始游戏"></div></div></div></main><script src="js/vue.js"></script><script src="js/data.js"></script><script src="js/app.js"></script></body></html>

CSS

* {padding: 0;margin: 0;}main {display: flex;justify-content: center;align-items: center;width: 100%;height: 100vh;background-color: #282828;}main .game-plane {position: relative;width: 1200px;max-width: 1200px;height: 900px;background-image: url(../image/background.png);background-size: 100% auto;box-shadow: 0 2px 30px rgba(255,255,255,0.5);overflow: hidden;}main .game-plane img {position: absolute; }.alert {position: absolute;top: calc(50% - 100px);left: 0;width: 100%;height: 200px;background: #FFF;box-shadow: 0 0 0 999em rgba(0, 0, 0, 0.5);}.alert .content {display: grid;grid-template-columns: 4fr 6fr;grid-template-rows: 100%;gap: 20px;margin: 0 auto;max-width: 1200px;width: 100%;height: 100%;}.alert .content .left {display: flex;flex-direction: column;align-items: center;justify-content: center;}.alert .content .left * {margin: 5px 0; }.alert .content .right {display: flex;flex-direction: column;align-items: center;justify-content: center;}.alert .content .right input {width: 100%;display: block;box-sizing: border-box;padding: 10px;}.e {transform: rotate(180deg); }.b {width: 30px; }#hit {position: absolute;top: 20px;left: 20px;color: #FFF;}

第二步:创建一个全局 data 文件

window.el = document.querySelector(".game-plane");window.data = {p : {// 玩家 Playerw : document.querySelector("#p").offsetWidth,h : document.querySelector("#p").offsetHeight,x : el.offsetWidth / 2 - document.querySelector("#p").offsetWidth / 2,y : el.offsetHeight - document.querySelector("#p").offsetHeight},e : {// 敌机 enemy planearr : [],speed : 6,},plane : {arr : [] },// 星球bullets : {arr : [] },// 子弹hitCount : 0,// 击中总数boom : 0,// 碰撞次数HitTimes : 0,// 被击中次数start : false,// 游戏是否开始positionY : 0,// 背景 Y 值timers : [],// 定时器face : "ordinary",// 表情username : "" // 玩家名}

第三步:创建Vue 实例

var Game = new Vue({el : "main",data,methods:{startBtnClick() {if ( this.username.length <= 2 ) return alert("用户名不可少于3位字符哦!");this.init();},init() {// 初始化let _this = this;this.start = true;this.$refs.alert.style.display = "none";this.createE();this.createPlane();this.timers.push( setInterval( this.bgMove,20 ) )this.timers.push( setInterval(function() {_this.move('bullets') }, 20 ) )},bgMove () {// 背景移动 顺带判断玩家是否装上敌军this.positionY += 5; if ( this.hit_check(this.p) ) this.boom++;},touchmove(){// 飞机移动let touch,x,y;if ( !this.start ) return;if(event.touches) touch = event.touches[0];else touch = event;x = touch.clientX - this.$refs.plane.offsetLeft - this.p.w / 2;y = touch.clientY - this.$refs.plane.offsetTop - this.p.h / 2;y = y < 0 ? 0 : y > (this.$refs.plane.offsetHeight - this.p.h) ? this.$refs.plane.offsetHeight - this.p.h : y;x = x < 0 ? 0 : x > (this.$refs.plane.offsetWidth - this.p.w) ? this.$refs.plane.offsetWidth - this.p.w : x;this.p.x = x;this.p.y = y;},createE() {// 创建敌军let _this = this,x;this.timers.push( setInterval( function() {x = Math.ceil( Math.random() * ( _this.$refs.plane.offsetWidth - 80 ) );_this.build('e',{x: x, y: 5 }) }, 1000 ));this.timers.push( setInterval( function() {_this.move('e') }, 20 ));},createPlane() {// 创建行星let _this = this,x;this.timers.push( setInterval( function() {x = Math.ceil( Math.random() * ( _this.$refs.plane.offsetWidth - 80 ) );_this.build('plane',{x: x, y: 5 }) }, 2000 ));this.timers.push( setInterval( function() {_this.move('plane') }, 20 ));},createButter(table,e) {// 创建子弹if ( !this.start ) return;let bullter = {x:(e.x + (e.w ? e.w : 30) / 2),y:e.y - (e.h ? e.h : -30),speed : table == "p" ? -6 : 10,tag : table};this.build('bullets',bullter);},build(table,data) {// 公共创建let _this = this;this[table].arr.push( data );},move(table) {// 公共移动for( let i = 0; i < this[table].arr.length; i ++ ){let e = this[table].arr[i],math = Math.random() * 100,speed = this[table].speed ? this[table].speed : 5;if ( table == 'bullets' ) speed = e.speed;e.y += speed;if ( table !== 'bullets' ) {// 如果不是子弹dom的移动if( e.y > this.$refs.plane.offsetHeight - 55 ) this[table].arr.splice(i,1);if ( table == 'e' && math < 1 ) {this.createButter('e',e); }} else {if ( e.tag == 'p' ) {if ( this.hit_check(e) ) this[table].arr.splice(i,1);else if ( e.y < 0 ) this[table].arr.splice(i,1);} else {if ( this.hit(e,this.p) ) {this[table].arr.splice(i,1);this.HitTimes++;}else if ( e.y > this.$refs.plane.offsetHeight - 30 ) this[table].arr.splice(i,1);}}}},hit_check(b) {// 是否击毁敌军for( let i = 0; i < this.e.arr.length; i ++ ){if( this.hit(b,this.e.arr[i]) ){this.e.arr.splice(i,1);this.hitCount++;return true;}}},hit(b,e) {// 碰撞let d = this.judgeHit( b.x, b.y, e.x, e.y );if( d < 35 ) return true;},judgeHit(x1, y1, x2, y2) {// 计算两个点的距离差let a = x1 - x2,b = y1 - y2,result = Math.sqrt( Math.pow( a, 2) + Math.pow( b, 2 ) );return Math.round( result );},pause() {// 暂停this.start = false;this.timers.forEach(element => {clearInterval(element); })}},watch: {username () {// 监听玩家输入事件if ( this.username.length > 2 ) this.face = "shy";else this.face = "ordinary";}},mounted(){let _this = this;document.onkeyup = function(e) {( e.keyCode == 32 ) && _this.createButter("p",_this.p);// ( e.keyCode == 80 ) && _this.pause();}},computed:{faceChange() {return "image/"+this.face + ".png"; } }});

最后这里附上成品包,如果有别的功能想要实现只要在这个基础上改一下就好

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。