zoukankan      html  css  js  c++  java
  • H5 简单实现打砖块游戏

    实现效果如图所示:
    1、布局
      在html中,声明  div1 作为作为带有边框的父物体,一切行为都要在 div1 中进行。创建小球ball、左右可滑动的板子bat,以及存放要销毁的砖块的父物体 brick。
        div1:父物体
        ball:小球
        bat:板子
        brick:承载砖块的父容器
    <body>
        <div class="div1">
            <div class="ball"></div>
            <div class="bat"></div>
            <div class="brick">
            </div>
        </div>
    </body>
    2、样式
      div1:设置大小,边框,线对定位,以及左右居中。
       ball:设成圆形,相对div1居中,设置大小,绝对定位
       bat:设置大小,绝对定位,位置在div1的左下方
       brick::预设一个div样式,并设置浮动,以及边框的大小。目的是为了让砖块可以自动生成 
      
    <style>
            .div1 {
                 600px;
                height: 600px;
                border: 1px solid black;
                margin: 100px auto;
                position: relative;
            }
            
            .ball {
                position: absolute;
                 20px;
                height: 20px;
                background: red;
                border-radius: 50%;
                left: 300px;
                top: 300px;
            }
            
            .bat {
                 100px;
                height: 20px;
                background: blue;
                position: absolute;
                left: 0;
                bottom: 0;
            }
            .brick div {
                height: 8px;
                 98px;
                float: left;
                background-color: yellow;
                border: 1px solid black;
            }
        </style>
    3、行为
      ① 拿到所有定义的标签对象
             const oDiv = document.querySelector('.div1');
                  const oBrick = oDiv.querySelector('.brick');
                  const oBall = oDiv.querySelector('.ball');
                  const oBatt = oDiv.querySelector('.bat');
                  var aBricks = oBrick.getElementsByTagName("div");
      ② 生成指定个数砖块,每个砖块随机生成颜色,并添加到父物体 brick下。为了以后销毁做准备,将每个砖块添加 top left属性,以及absolute绝对定位(解决在销毁时,由于浮动原因,带来销毁后其他砖块左移动的影响)。
         creatStone(60);
                  //生成砖块
                function creatStone(num) {
                      for (var i = 0; i < num; i++) {
                          var div = document.createElement('div');
                          div.style.background = setColors();
                          oBrick.appendChild(div);
                          div.style.left = div.offsetLeft + 'px';
                          div.style.top = div.offsetTop + 'px';
                      }
                      for (var j = 0; j < num; j++) {
                         aBricks[j].style.position = 'absolute';
                      }
                 }
        随机颜色
         //设置砖块随机颜色
                function setColors() {
                    let r = parseInt(Math.random() * 256);
                    let g = parseInt(Math.random() * 256);
                    let b = parseInt(Math.random() * 256);
                    return `rgb(${r},${g},${b})`;
                }
      ③ 设置滑块的移动
       oBatt.onmousedown = function(e) {
                    e = e || window.event;
                    let x = e.clientX - oBatt.offsetLeft;
                    document.onmousemove = function(ev) {
                        ev = ev || window.event;
                        let l = ev.clientX - x;
                        if (l <= 0) {
                            l = 0;
                        }
                        if (l >= oDiv.clientWidth - oBatt.offsetWidth) {
                            l = oDiv.clientWidth - oBatt.offsetWidth;
                        }
                        oBatt.style.left = l + 'px';
                    }
                }
                document.onmouseup = function() {
                    document.onmousemove = null;
                }
            }
      ④ 设置小球随机滚动,这里定义了x y两个方向的随机速度,当ball碰到边框是,将速度设为负值,进行反方向运动。运动时间间隔为40ms。运动形式是通过改变小球的left top值来实现的。这里做了一个校验,当碰到底边时会弹窗,告诉玩家重新开始。knock()为自定义的碰撞函数,接下来会为大家介绍。
                var speedx = parseInt(Math.random() * 4) + 3;
                var speedy = parseInt(Math.random() * 3) + 4;
                setInterval(function() {
                    oBall.style.left = oBall.offsetLeft + speedx + 'px';
                    oBall.style.top = oBall.offsetTop + speedy + 'px';
                    if (oBall.offsetLeft <= 0 || oBall.offsetLeft > oDiv.clientWidth - oBall.offsetWidth) {
                        speedx *= -1;
                    }
                    if (oBall.offsetTop <= 0 || oBall.offsetTop > oDiv.clientHeight - oBall.offsetHeight) {
                        speedy *= -1;
                    }
                    if (oBall.offsetTop == oDiv.clientHeight - oBall.offsetHeight) {
                        window.alert('重新开始')
                        window.location.reload();
                    }
                    if (knock(oBall, oBatt)) {
                        speedy *= -1;
                    }
                    for (var i = 0; i < aBricks.length; i++) {
                        if (knock(oBall, aBricks[i])) {
                            speedy *= -1;
                            oBrick.removeChild(aBricks[i]);
                        }
                    }
                }, 40);
      ⑤ 碰撞函数的介绍:两个参数node1,node2,获取两个对象的每条边相对于父物体的坐标值。通过比较是否发生重叠的原理,判断是否发生了碰撞。
      function knock(node1, node2) {
                let l1 = node1.offsetLeft;
                let r1 = node1.offsetLeft + node1.offsetWidth;
                let t1 = node1.offsetTop;
                let b1 = node1.offsetTop + node1.offsetHeight;

                let l2 = node2.offsetLeft;
                let r2 = node2.offsetLeft + node2.offsetWidth;
                let t2 = node2.offsetTop;
                let b2 = node2.offsetTop + node2.offsetHeight;
                if (l2 >= r1 || r2 <= l1 || t2 >= b1 || b2 <= t1) {
                    return false;
                } else {
                    return true;
                }
            }
    4、详细js代码如下
     <script>
            window.onload = function() {

                const oDiv = document.querySelector('.div1');
                const oBrick = oDiv.querySelector('.brick');
                const oBall = oDiv.querySelector('.ball');
                const oBatt = oDiv.querySelector('.bat');
                var aBricks = oBrick.getElementsByTagName("div");

                creatStone(60);
                //生成砖块
                function creatStone(num) {
                    for (var i = 0; i < num; i++) {
                        var div = document.createElement('div');
                        div.style.background = setColors();
                        oBrick.appendChild(div);
                        div.style.left = div.offsetLeft + 'px';
                        div.style.top = div.offsetTop + 'px';
                    }
                    for (var j = 0; j < num; j++) {
                        aBricks[j].style.position = 'absolute';
                    }
                }
                //设置砖块随机颜色
                function setColors() {
                    let r = parseInt(Math.random() * 256);
                    let g = parseInt(Math.random() * 256);
                    let b = parseInt(Math.random() * 256);
                    return `rgb(${r},${g},${b})`;
                }
                //设置小球随机滚动
                var speedx = parseInt(Math.random() * 4) + 3;
                var speedy = parseInt(Math.random() * 3) + 4;
                setInterval(function() {
                    oBall.style.left = oBall.offsetLeft + speedx + 'px';
                    oBall.style.top = oBall.offsetTop + speedy + 'px';
                    if (oBall.offsetLeft <= 0 || oBall.offsetLeft > oDiv.clientWidth - oBall.offsetWidth) {
                        speedx *= -1;
                    }
                    if (oBall.offsetTop <= 0 || oBall.offsetTop > oDiv.clientHeight - oBall.offsetHeight) {
                        speedy *= -1;
                    }
                    if (oBall.offsetTop == oDiv.clientHeight - oBall.offsetHeight) {
                        window.alert('重新开始')
                        window.location.reload();
                    }
                    if (knock(oBall, oBatt)) {
                        speedy *= -1;
                    }
                    for (var i = 0; i < aBricks.length; i++) {
                        if (knock(oBall, aBricks[i])) {
                            speedy *= -1;
                            oBrick.removeChild(aBricks[i]);
                        }
                    }
                }, 40);
                //设置滑块的移动
                oBatt.onmousedown = function(e) {
                    e = e || window.event;
                    let x = e.clientX - oBatt.offsetLeft;
                    document.onmousemove = function(ev) {
                        ev = ev || window.event;
                        let l = ev.clientX - x;

                        if (l <= 0) {
                            l = 0;
                        }
                        if (l >= oDiv.clientWidth - oBatt.offsetWidth) {
                            l = oDiv.clientWidth - oBatt.offsetWidth;
                        }
                        oBatt.style.left = l + 'px';
                    }
                }

                document.onmouseup = function() {
                    document.onmousemove = null;
                }
            }

            function knock(node1, node2) {
                let l1 = node1.offsetLeft;
                let r1 = node1.offsetLeft + node1.offsetWidth;
                let t1 = node1.offsetTop;
                let b1 = node1.offsetTop + node1.offsetHeight;

                let l2 = node2.offsetLeft;
                let r2 = node2.offsetLeft + node2.offsetWidth;
                let t2 = node2.offsetTop;
                let b2 = node2.offsetTop + node2.offsetHeight;
                if (l2 >= r1 || r2 <= l1 || t2 >= b1 || b2 <= t1) {
                    return false;
                } else {
                    return true;
                }
            }
        </script>
  • 相关阅读:
    使用Xshell为xftp开ssh通道代理
    linux下查找svn的相关目录的命令
    linux服务器A远程连接服务器B的mysql及1045错误
    怎样下载带权限认证的文件?
    Vue项目打包部署总结
    Vue项目打包压缩:让页面更快响应
    axios请求失败自动重发
    可用的后台管理系统
    vue组件间方式总结
    非脚手架创建vue项目,并使用webpack打包
  • 原文地址:https://www.cnblogs.com/cyp926/p/13359059.html
Copyright © 2011-2022 走看看