• 原生JS实现挡板小球游戏


    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
            }
            
            .box {
                 940px;
                height: 500px;
                border: 1px solid #000;
                margin: 50px auto;
                position: relative;
                /* cursor: none; */
            }
            
            .block {
                position: absolute;
                top: 0;
                left: 0;
                 94px;
                height: 36px;
                background: url(img/block.png);
            }
            
            .ball {
                position: absolute;
                 27px;
                height: 27px;
                background: url(img/ball.png);
            }
            
            .racket {
                position: absolute;
                 179px;
                height: 37px;
                background: url(img/racket.png);
                top: 450px;
                left: 10px;
            }
        </style>
    </head>
    
    <body>
        <div class="box" id="box">
            <div class="ball" id="ball"></div>
            <div class="racket" id="racket"></div>
        </div>
    </body>
    
    <script>
        // 获取dom对象
        var box = document.getElementById('box');
        var ball = document.getElementById('ball');
        var racket = document.getElementById('racket');
        // 面向对象的思维挡板,小球,地图,碰撞块,大盒子都可以是一个类
    
        // 创建碰撞块类
    
        function Block(left, top, color) {
            this.top = top;
            this.left = left;
            this.width = 94;
            this.height = 36;
            this.color = color;
            this.alive = true;
            this.init();
        }
    
        // 块类有一个初始化方法
        Block.prototype.init = function() {
            this.dom = document.createElement('div');
            this.dom.className = 'block';
            box.appendChild(this.dom);
            this.render();
        }
    
        // 块类有一个渲染方法
        Block.prototype.render = function() {
            this.dom.style.top = this.top + 'px';
            this.dom.style.left = this.left + 'px';
            this.dom.style.backgroundPosition = -this.color * this.width + 'px 0';
        };
        // 我们的block也要有碰撞检测,当被小球撞到时消失,并且反弹小球
    
        Block.prototype.check = function() {
            // 上边界检测
            if (b.top >= this.top - b.d && b.top <= this.top && b.left >= this.left - b.d && b.left <= this.left + this.width) {
                b.deltaY *= -1;
                this.hide();
                return true;
                // 下边界检测
            } else if (b.top <= this.top + this.height && b.top >= this.top && b.left >= this.left - b.d && b.left <= this.left + this.width) {
                b.deltaY *= -1;
                this.hide();
                return true;
                // 左边界检测
            } else if (b.left >= this.left - b.d && b.left <= this.left && b.top >= this.top && b.top <= this.top + this.height) {
                b.deltaX *= -1;
                this.hide();
                return true;
                // 右边界检测
            } else if (b.left <= this.left + this.width && b.left >= this.left && b.top >= this.top && b.top <= this.top + this.height) {
                b.deltaX *= -1;
                this.hide();
                return true;
            }
        };
        Block.prototype.hide = function() {
            this.alive = false;
            container.dom.removeChild(this.dom);
        };
    
        // 创建地图类
    
        function Map() {
            // 地图类需要有一个二维数组来表示box内的block数量
            this.data = [
                [0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
                [0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
                [0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
                [0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
                [0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
                [0, 1, 2, 3, 0, 1, 2, 3, 0, 1],
    
            ];
            this.allBlockArr = [];
            this.render();
        }
    
        // Map也有一个render方法
        Map.prototype.render = function() {
            // 遍历二维数组
            for (var row = 0; row < this.data.length; row++) {
                for (var col = 0; col < this.data[row].length; col++) {
                    this.allBlockArr.push(new Block(col * 94, row * 30, this.data[row][col]))
                }
            }
        };
        // 检测所有block是否被小球碰撞
        Map.prototype.checkAll = function() {
            for (var i = 0; i < this.allBlockArr.length; i++) {
                if (this.allBlockArr[i].alive) {
                    var result = this.allBlockArr[i].check()
                }
                if (result) {
                    break;
                }
            }
        }
    
        // 创建小球类
        function Ball() {
            this.left = 480;
            this.top = 400;
            this.d = 27;
            // 小球运动速度,运动角度
            this.speed = 5;
            this.angle = 50;
            // 小球的运动方向
            // 计算机采用的是弧度制,并不是角度制
            // 这里我们将圆球运动看作三角模型那么它斜向运动的speed就是斜线
            // 我们可以根据角度计算出sin 也就是对边 / 斜边 的值
            // 然后让其 * 斜边speed得到对边也就是Y轴的移动速度
            this.deltaY = Math.sin(angleChangeToRadian(this.angle)) * this.speed;
            // 三角函数中余弦就是邻边比斜边
            this.deltaX = Math.cos(angleChangeToRadian(this.angle)) * this.speed;
            this.dom = ball;
            this.fly();
        }
        // 小球有一个运动方法
    
        Ball.prototype.fly = function() {
            var self = this;
            var timer = setInterval(function() {
                self.left += self.deltaX;
                self.top += self.deltaY;
                self.dom.style.left = self.left + 'px';
                self.dom.style.top = self.top + 'px';
                // 每十秒让container检测是否被小球碰到
                container.check();
                map.checkAll();
                oRacket.check();
            }, 10)
    
        }
    
        // 创建一个大盒子的类
        function Box() {
            this.dom = box;
            this.width = 940;
            this.height = 500;
    
        }
        //  大盒子需要一个碰撞检测,当检测到小球碰撞到盒子时反弹
        Box.prototype.check = function() {
            // 左右边界检测
            // 反弹的原理是当我们的小球以X轴5 / s,Y轴 8 / s的速度下降,那么它反弹后
            // X轴的速度不变,Y轴向相反方向运动
            if (b.left >= this.width - b.d || b.left <= 0) {
                b.deltaX *= -1;
            }
    
            if (b.top >= this.height - b.d || b.top <= 0) {
                b.deltaY *= -1;
            }
        }
    
    
        // 创建挡板类
        function Racket() {
            this.width = 179;
            this.height = 37;
            this.top = 450;
            this.left = 10;
            this.dom = racket;
            this.move()
        }
        // 挡板移动
        Racket.prototype.move = function() {
            var self = this;
            container.dom.onmousemove = function(event) {
                event = event || window.event;
                self.left = event.clientX - container.dom.offsetLeft - self.width / 2;
                self.dom.style.left = self.left + 'px';
            }
        };
        // 挡板碰撞检测
        Racket.prototype.check = function() {
            // 上边界检测
            if (b.top >= this.top - b.d && b.top <= this.top && b.left >= this.left - b.d && b.left <= this.left + this.width) {
                b.deltaY *= -1;
                // 下边界检测
            } else if (b.top <= this.top + this.height && b.top >= this.top && b.left >= this.left - b.d && b.left <= this.left + this.width) {
                b.deltaY *= -1;
                // 左边界检测
            } else if (b.left >= this.left - b.d && b.left <= this.left && b.top >= this.top && b.top <= this.top + this.height) {
                b.deltaX *= -1;
                // 右边界检测
            } else if (b.left <= this.left + this.width && b.left >= this.left && b.top >= this.top && b.top <= this.top + this.height) {
                b.deltaX *= -1;
            }
    
        }
        var b = new Ball();
        var map = new Map();
        var container = new Box();
        var oRacket = new Racket()
    
    
        // 定义角度转弧度的函数
        function angleChangeToRadian(angle) {
            return angle * Math.PI / 180;
        }
    </script>
    
    </html>

  • 相关阅读:
    SQL Server CTE 递归查询全解(转载)
    ASP.NET Core MVC中Controller的Action,默认既支持HttpGet,又支持HttpPost
    ASP.NET Core 使用外部登陆提供程序登陆的流程,以及身份认证的流程 (转载)
    SQL Server中比较末尾带有空格的字符串遇到的坑 (转载)
    ASP.NET Core如何设置请求超时时间
    ADO.NET的Connection Timeout和Command Timeout (转载)
    风尘浪子 只要肯努力,梦想总有一天会实现 WF工作流与Web服务的相互调用 —— 通过Web服务调用Workflow工作流(开发持久化工作流) _转
    WPF学习资源整理
    WCF 学习笔记
    WorkFlow 工作流 学习笔记
  • 原文地址:https://www.cnblogs.com/tengx/p/12427643.html
Copyright © 2020-2023  润新知