Vue实现飞机大战小游戏

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

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

如题,假设你为了向更多访问你博客的人展示你的技术,你决定小试身手开发一个飞机大战小游戏。
功能: 开始游戏前用户名必填,玩家可以发射子弹,敌军与行星随机出现,鼠标可操控玩家移动,敌军可发射子弹

一、实现思路

如题所述:

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

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

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

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

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

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

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

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

二、所需知识点

1. Vue 事件绑定
2. Vue 监听事件
3. Vue 计算属性
4. Vue Style操作

三、实现步骤

第一步:创建 HTML 与 CSS 文件

HTML

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Vue 飞机大战</title>
        <link rel="stylesheet" href="css/style.css" rel="external nofollow" >
    </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 : {// 玩家 Player
        w : 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 plane
        arr : [],
        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"; } }
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 原生JS实现飞机大战小游戏

    本文实例为大家分享了JS实现飞机大战小游戏的具体代码,供大家参考,具体内容如下 <html> <head> <title> 飞机大战 </title> <style type="text/css"> *{margin:0;padding:0;font-family:"Microsoft yahei"} body{overflow:hidden;;} </style> </head>

  • JavaScript实现飞机大战游戏

    本文实例为大家分享了canvas ,js 实现一个简单的飞机大战,供大家参考,具体内容如下 预览图: 代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport"

  • javascript实现简单飞机大战小游戏

    本文实例为大家分享了javascript实现飞机大战小游戏的具体代码,供大家参考,具体内容如下 效果图 html文件 <!DOCTYPE html><html lang='zh'><head>    <meta charset='UTF-8'>    <title>mm</title>    <link rel="stylesheet" href="./css/index.css">

  • JavaScript实现微信飞机大战游戏

    本文实例为大家分享了JavaScript实现微信飞机大战游戏的具体代码,供大家参考,具体内容如下 html代码 <!DOCTYPE> <html> <head>     <title>微信经典飞机大战 </title>     <meta http-equiv="content" content="text/html" charset="utf-8"/>     <li

  • JavaScript编写实现飞机大战

    本文实例为大家分享了JavaScript实现飞机大战的具体代码,供大家参考,具体内容如下 一.飞机大战游戏介绍: 游戏中,玩家驾驶飞机,在空中进行战斗.点击并移动自己的飞机,发射炮弹,打掉敌小型飞机.中型飞机和大型飞机,来获得分数和奖励,打掉一架小型飞机赢得3分,打掉一架中型飞机赢得5分,打掉一架大型飞机赢得10分,累加得分.撞到敌飞机命减1,当命数为0时,则游戏结束. 二. 效果图页面展示: 初始界面如图-1所示: 玩家在如图-1所示的界面的任意位置,按下鼠标左键,开始游戏. 图-1 默认分数

  • javascript实现飞机大战小游戏

    本文实例为大家分享了javascript实现飞机大战游戏的具体代码,供大家参考,具体内容如下 文档结构如下 其中tool文件中只使用了随机数,audio中是存放的音乐文件,images中是己方和敌方飞机的图片. HTML部分 <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="X

  • JavaScript实现前端飞机大战小游戏

    本文实例为大家分享了JavaScript实现前端飞机大战的具体代码,供大家参考,具体内容如下 html: <!DOCTYPE html> <html>     <head>         <meta charset="utf-8" />         <title>飞机大战</title>         <link rel="stylesheet" type="text/c

  • JavaScript实现简易飞机大战

    本文实例为大家分享了JavaScript实现简易飞机大战的具体代码,供大家参考,具体内容如下 话不多说,直接上代码 <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale

  • js canvas实现飞机大战

    本文实例为大家分享了js canvas实现飞机大战的具体代码,供大家参考,具体内容如下 首先我们绘制一个canvas区域,确实其宽高为480px*852px;水平居中 <!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" conten

  • 用JS实现飞机大战小游戏

    本文实例为大家分享了JS实现飞机大战小游戏的具体代码,供大家参考,具体内容如下 小的时候玩的飞机大战感觉还蛮神奇,今天自己就学着做了一个 先制作好要做好的几步以及背景样式 var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var start = 0; // 开始阶段 var starting = 1; // 开始的加载阶段 var running =

随机推荐