【问题标题】:Collision detection using kineticJS (getIntersection function not working)使用 kineticJS 进行碰撞检测(getIntersection 函数不起作用)
【发布时间】:2014-03-11 23:01:47
【问题描述】:

我正在尝试重新创建游戏 http://www.sinuousgame.com/ 并开始学习 html5 canvaskineticJS

最近我遇到了 getIntersection 函数,并没有找到很多关于它的详细信息。但是根据我所拥有的,我确实编写了一个代码来使用 getIntersection() 函数完成碰撞检测。 但它似乎不起作用。

如你所见,我的小提琴http://jsfiddle.net/p9fnq/8/

   //The working player code
var LimitedArray = function(upperLimit) {
    var storage = [];

    // default limit on length if none/invalid supplied;
    upperLimit = +upperLimit > 0 ? upperLimit : 100;

    this.push = function(item) {
        storage.push(item);
        if (storage.length > upperLimit) {
            storage.shift();
        }
        return storage.length;
    };

    this.get = function(flag) {
        return storage[flag];
    };

    this.iterateItems = function(iterator) {
        var flag, l = storage.length;
        if (typeof iterator !== 'function') {
            return;
        }
        for (flag = 0; flag < l; flag++) {
            iterator(storage[flag]);
        }
    };
};

var tail = new LimitedArray(50);

var flag = 0, jincr = 0;
var stage = new Kinetic.Stage({
    container: 'container',
    width: window.innerWidth,
    height: window.innerHeight,
    listening: true
});
var layer = new Kinetic.Layer({
    listening: true
});
stage.add(layer);
var player = new Kinetic.Circle({
    x: 20,
    y: 20,
    radius: 6,
    fill: 'cyan',
    stroke: 'black',
    draggable: true
});
var line = new Kinetic.Line({
    points: [],
    stroke: 'cyan',
    strokeWidth: 2,
    lineCap: 'round',
    lineJoin: 'round'
});
layer.add(line);
layer.add(player);

// move the circle with the mouse
stage.getContent().addEventListener('mousemove', function() {
    player.position(stage.getPointerPosition());
    var obj = {
        x: stage.getPointerPosition().x,
        y: stage.getPointerPosition().y
    };

    tail.push(obj);
    var arr = [];
    tail.iterateItems(function(p) {
        arr.push(p.x, p.y);
    });
    line.points(arr);
});

var x = 0;
var y = 0;
var noOfEnemies = 200;
var enemyArmada = new Array();


createEnemy();

function createEnemy() {
    for (var i = 0; i < noOfEnemies; i++) {
        var enemy = new Kinetic.Circle({
            x: Math.random() * window.innerWidth,
            y: Math.random() * window.innerHeight,
            radius: 4.5 + 1.5 * Math.random(),
            fill: 'red',
            stroke: 'black'
        });
        enemy.speedX = enemy.speedY = (0.5 + Math.random() * 50);
        enemyArmada.push(enemy);
        layer.add(enemy);
    }
}


 var checkCollide = function() {
        var position = stage.getPointerPosition();
        if(position == null)
            position = player.position();
        if(position == null)
            position = {x:0,y:0};
        var collided = stage.getIntersection(position); 
        console.log(position);
        if (typeof collided !== 'Kinetic.Shape') {
            console.log("not shape");
        }
        else {
            console.log("BOOOM!!!");
        }
    };

var anim = new Kinetic.Animation(function(frame) {
    checkCollide();
    for (var i = 0; i < noOfEnemies; i++) {
        var e = enemyArmada[i];
        e.position({
            x: e.position().x - e.speedX * (frame.timeDiff / 400),
            y: e.position().y + e.speedY * (frame.timeDiff / 400)
        });

        if (e.position().y < 0 || e.position().x < 0) {
            e.position({
                x: (Math.random() * (window.innerWidth + 600)),
                y: -(Math.random() * window.innerHeight)
            });
        }
    }

}, layer);
anim.start();

我需要检测碰撞。我在这里写的函数是 checkCollide,它在 kinetic.Animation 函数中被调用。

谁能帮我解决这个问题? (如果您不知道解决方案,请点赞帖子,我非常需要解决方案)

【问题讨论】:

    标签: javascript html5-canvas collision-detection kineticjs


    【解决方案1】:

    问题的根源

    getIntersection(point) 表示“此时是任何对象”。

    由于您使用的点是玩家的位置,getIntersection 将始终返回 true,因为玩家始终在自己的位置!

    一个解决方案

    把你的玩家放在一层,把所有敌人放在一个单独的层上。

    这样你就可以在不受玩家对象干扰的情况下点击测试敌人层。

    代码和演示:http://jsfiddle.net/m1erickson/JCfW8/

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Prototype</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
        <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
    <style>
    body{padding:20px;}
    #container{
      border:solid 1px #ccc;
      margin-top: 10px;
      width:350px;
      height:350px;
    }
    </style>        
    <script>
    $(function(){
    
        var stage = new Kinetic.Stage({
            container: 'container',
            width: 350,
            height: 350
        });
        var enemyLayer = new Kinetic.Layer();
        stage.add(enemyLayer);
        var playerLayer = new Kinetic.Layer();
        stage.add(playerLayer);
    
        var player = new Kinetic.Circle({
            x:100,
            y:100,
            radius: 10,
            fill: 'green',
            draggable: true
        });
        player.on("dragmove",function(){
            if(enemyLayer.getIntersection(player.position())){
                this.fill("red");
                playerLayer.draw();
            }
        });
        playerLayer.add(player);
        playerLayer.draw();
    
        var enemy = new Kinetic.Circle({
            x:200,
            y:100,
            radius: 20,
            fill: 'blue',
            draggable: true
        });
        enemyLayer.add(enemy);
        enemyLayer.draw();
    
    }); // end $(function(){});
    
    </script>       
    </head>
    
    <body>
        <h4>Drag the green player<br>Player will turn red if it collides<br>with the blue enemy</h4>
        <div id="container"></div>
    </body>
    </html>
    

    另一种解决方案

    用数学方法测试玩家对抗每一个敌人:

    警告:未经测试的代码——可能需要进行一些调整

    function playerEnemyCollide(){
        var playerX=player.x();
        var playerY=player.y();
        var playerRadius=player.radius();
    
        for(var i=0;i<enemyArmada.length;i++){
            var e=enemyArmada[i];
            if(circlesColliding(playerX,playerY,playerRadius,e.x,e.y,e.radius)){
                return(true);
            }
        }
        return(false);
    }
    
    function circlesColliding(cx1,cy1,radius1,cx2,cy2,radius2){
        var dx=cx2-cx1;
        var dy=cy2-cy1;
        return(dx*dx+dy*dy<(radius1*2+radius2*2);
    }
    

    【讨论】:

    • 我会应用这个方法,然后回复你。有点忙于项目。
    • 嘿,它成功了。 :) 谢谢 如果你想看看它,这里是小提琴。 jsfiddle.net/p9fnq/11顺便说一句 layer.draw() 真的有必要吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多