zoukankan      html  css  js  c++  java
  • 矩形的碰撞检测(模仿俄罗斯方块)

      以前一直以为玄之又玄的碰撞检测算法,其实也不过是一些加减法。看来还是写的太少,大多时候只是停留在望而止步的层次。

    矩形的碰撞检测原理就是两个矩形的x值+宽度和y值+高度的各种比较。

    function(c1,c2{
        return !{
                         b1.x + b1.w < b2.x ||
                         b1.y + b1.h < b2.y ||
                         b2.x + b2.w < b1.x ||
                         b2.y + b2.h < b1.y
                    }     

      意思就是矩形1的x加上矩形1的宽度是否小于矩形2的x,这样就能检测到当矩形1在矩形2的左边的时候,两个矩形在水平方向上是否有重叠;垂直方向同理,把x改为y,宽度改为高度即可。

      碰撞检测的原理搞清楚了之后其他的就是小意思了,利用动画帧即可做出方块下落的动画。  

      完整代码如下:

    <!DOCTYPE html>
    <html lang="en">
    
        <head>
            <meta charset="UTF-8">
            <title>碰撞检测</title>
            <style type="text/css">
                canvas{
                    border: 1px solid #ccc;
                }
            </style>
        </head>
    
        <body>
            <canvas id="cav" width="300" height="300"></canvas>
    
            <script>
            /*通过调整方块的y轴位置而不断下落,如果到了画布的底部或者碰撞到了其他方块则停止下落,这是矩形的碰撞检测*/
            
                var cav = document.getElementById("cav"),
                    ctx = cav.getContext('2d');
    
                var rects = [],//把方块存储起来
                    speed = 2;//下落速度
                
                //方块的初始化
                function rectInit(x, y, width, height) {
                    this.x = x;
                    this.y = y;
                    this.w = width;
                    this.h = height;
                }
                
                //创建方块
                function createRect() {
                    var x = cav.width * Math.random(),
                        y = 0;
    
                    var rect = new rectInit(x, y, 30, 30);
                    rects.push(rect);
                    return rect;
                }
                
                //一开始先创建一个方块
                var oRect = new rectInit(cav.width / 2, 0, 30, 30);
                rects.push(oRect);
                
                //方块下落动画
                function animate() {
                    ctx.clearRect(0, 0, cav.width, cav.height);
                    
                    //如果没有到底部
                    if(oRect.y < cav.height-oRect.h){
                        oRect.y += speed;
                    }
                    else{//到了底部后停止下落
                        oRect.y = cav.height-oRect.h;
                        
                        oRect = createRect();//再度创建一个方块
                    }
                    ctx.fillStyle = '#f00';
                    
                    //循环数组里存储的方块
                    rects.forEach(function(r,i){
                        if(oRect !== r && collision(oRect,r)){
                        //    console.log('碰撞成功');
                            oRect.y = r.y - oRect.h;
                            oRect = createRect();
                        }
                        
                        ctx.fillRect(r.x,r.y,r.w,r.h);
                    });
                    
                    
                    
                    requestAnimationFrame(animate);
                }
                
                animate();
    
                //矩形的碰撞检测
                function collision(c1, c2) {
                    return !(c1.x + c1.w < c2.x ||
                        c1.y + c1.h < c2.y ||
                        c2.x + c2.w < c1.x ||
                        c2.y + c2.h < c1.y
                    );
                }
            </script>
        </body>
    
    </html>
  • 相关阅读:
    线段树
    数据结构<三> 队列
    数据结构<二>双向链表
    数据结构<一>单链表
    扩展欧几里德算法
    90 个 node.js 扩展模块,我们疯了
    nodejs的查询构造器
    express的路由配置优化
    express路由方案
    Redis学习笔记~目录
  • 原文地址:https://www.cnblogs.com/11lang/p/6082811.html
Copyright © 2011-2022 走看看