实现效果如图所示:

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 {
            width: 600px;
            height: 600px;
            border: 1px solid black;
            margin: 100px auto;
            position: relative;
        }
        
        .ball {
            position: absolute;
            width: 20px;
            height: 20px;
            background: red;
            border-radius: 50%;
            left: 300px;
            top: 300px;
        }
        
        .bat {
            width: 100px;
            height: 20px;
            background: blue;
            position: absolute;
            left: 0;
            bottom: 0;
        }
        .brick div {
            height: 8px;
            width: 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>

H5 简单实现打砖块游戏的更多相关文章

  1. H5简单内容

    1.简单认识H5 HTML5不仅仅是作为HTML标记语言的一个最新版本,更重要的是它指定了Web开发的一系列标准,成为第一个将Web作为应用开发平台的HTML语言. 我们日常讨论的H5其实是有一个泛称 ...

  2. h5 简单拖放

    最新的HTML5标准为所有的html元素规定了一个draggable属性,它表明了元素是否可以拖动,默认情况下,图像,链接,选中的文字是可以拖动的,因为他们的draggable属性被自动设置为true ...

  3. js进阶 10-7 简单的伪类选择器可以干什么

    js进阶 10-7 简单的伪类选择器可以干什么 一.总结 一句话总结:伪类选择器是冒号. 1.学而不用,有什么用? 多用啊,在项目中多用 2.简单的伪类选择器可以干什么? 除某元素以外,某元素的一切索 ...

  4. MVC文件上传 - 使用jquery异步上传并客户端验证类型和大小

    本篇体验MVC上传文件,从表单上传过渡到jquery异步上传. MVC最基本的上传文件是通过form表单提交方式 □ 前台视图部分 <% using(Html.BeginForm("F ...

  5. ionic新入坑-环境搭建+新建项目+打开低版本项目处理

    是的.我又双叒叕入新坑了.想我大学的时候web-app刚火起来.还帮忙做了我们学校医务室系统的web-app页面部分呢.时间太紧最后也没出个完整的版本.那时候只是用H5简单做了web部分.是想着用ph ...

  6. MVC文件上传01-使用jquery异步上传并客户端验证类型和大小

    本篇体验MVC上传文件,从表单上传过渡到jquery异步上传. MVC最基本的上传文件是通过form表单提交方式 □ 前台视图部分 <% using(Html.BeginForm("F ...

  7. js进阶 10-8 伪类选择器有哪几类(自己不用,永远不是自己的)

    js进阶 10-8 伪类选择器有哪几类(自己不用,永远不是自己的) 一.总结 一句话总结:自己不用,永远不是自己的. 0.学而不用,却是为何? 自己不用,永远不是自己的,有需求的时候要想到它,然后操作 ...

  8. 用PHP+H5+Boostrap做简单的音乐播放器(进阶版)

    前言:之前做了一个音乐播放器(纯前端),意外的受欢迎,然后有人建议我把后台一起做了,正好也想学习后台,所以学了两天php(不要吐槽我的速度,慢工出细活嘛~)然后在之前的基础上也又完善了一些功能,所以这 ...

  9. 移动端 H5图片裁剪插件,内置简单手势操作

    前面曾经写过一篇<H5图片裁剪升级版>,但里面需要借助第三方手势库,这次就不需要使用手势库,全部封装在代码中. 下图是裁剪的展示,下面就做了拖放和裁剪,没有做缩放,在插件中需要用到大量的计 ...

随机推荐

  1. 微服务架构学习Day01-SpringBoot入门

    基本概念 SpringBoot的优点: 可以创建独立的Spring应用 SpringBoot嵌入Tomcat,Jetty和Unsertow, 不需要部署war文件 根据需要通过maven获取start ...

  2. K8s Deployment YAML 名词解释

    Deployment 简述 Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的 ReplicationControlle ...

  3. OpenStack Train版-14.安装块存储服务cinder(存储节点)

    安装cindoer块存储服务节点(存储节点192.168.0.40)使用默认的LVM卷方法,之后改为ceph存储 安装LVM软件包 [root@cinder01 ~]# yum install lvm ...

  4. MySQL数据库系列(四)- InnoDB下的共享表空间和独立表空间详解

    一.概念 共享表空间: Innodb的所有数据保存在一个单独的表空间里面,而这个表空间可以由很多个文件组成,一个表可以跨多个文件存在,所以其大小限制不再是文件大小的限制,而是其自身的限制.从Innod ...

  5. meterpreter php payload && windows payload 学习

    一 情景 本地kali linux 192.168.1.2 目标 windows NT 服务器192.168.1.4 目的是获取shell 二 过程 首先在linux建立终端 ,msfconsole ...

  6. Gym 101174D Dinner Bet(概率DP)题解

    题意:n个球,两个人每人选C个球作为目标,然后放回.每回合有放回的拿出D个球,如果有目标球,就实现了这个目标,直到至少一个人实现了所有目标游戏结束.问结束回合的期望.误差1e-3以内. 思路:概率DP ...

  7. CDD All In One

    CDD All In One 组件驱动开发 (CDD) refs https://www.componentdriven.org/ https://www.learnstorybook.com/int ...

  8. git merge bug

    git merge bug 本地分支 dev commit 后, 直接 pull 远程 dev 分支, 导致远程 dev 分支 merge 到本地 dev 分支了, 取消本次 merge 操作? Re ...

  9. vue 的 computed 属性在什么时间执行

    vue 的 computed 属性在什么时间执行

  10. TypeScript keyof typeof All In one

    TypeScript keyof typeof All In one keyof typeof refs https://www.typescriptlang.org/docs/handbook/re ...