【问题标题】:Phaser check if sprite is inside another sprite not working?移相器检查精灵是否在另一个精灵中不起作用?
【发布时间】:2015-09-13 14:53:14
【问题描述】:

我正在使用这个 JS 检查一个精灵是否在另一个精灵中。

    if (ball.x > cup.x &&
        ball.x + ball.width < cup.x + cup.width &&
        ball.y > cup.y &&
        ball.y + ball.height < cup.y + cup.height) {
        game.paused = true;
    }

所以我正在检查我的“球”精灵是否在“杯子”的边界矩形内。

但是,有时游戏并没有暂停,即使视觉上我可以看到“球”在“杯”内。我的条件陈述是正确的,对吧?有时它会按预期工作,有时它不会,这非常令人沮丧,因为它不会生成任何可追踪的错误消息......

index.html

<!DOCTYPE html>

<html lang="en">
    <meta charset="UTF-8" />
    <head>
        <link rel="stylesheet" type="text/css" href="stylesheet.css">
    </head>
<body>

<script src="js/phaser.min.js"></script>
<script src="js/game.js"></script>
</body>
</html>

game.js

window.onload = function() {

    var game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload: preload, create: create, update: update });

    function preload() {
        game.load.image('table', 'assets/img/table.png');
        game.load.image('cup', 'assets/img/cup.png');
        game.load.image('ball', 'assets/img/ball.png');
    }

    var table;
    var cups;
    var p1cups;
    var p2cups;
    var ball;
    var bounces = 0;
    var ballAscending = true;
    var ballThrown = false;
    var checkCollisions = true;
    var goalScored = false;
    var cupW;
    var cupH;
    var gameOver = false;
    var clickTime;

    function create() {

        game.physics.startSystem(Phaser.Physics.ARCADE);

        table = game.add.sprite(game.world.centerX, game.world.centerY, 'table');
        table.anchor.setTo(0.5,0.5);

        cupW = game.cache.getImage('cup').width;
        cupH = game.cache.getImage('cup').height;

        p1cups = game.add.group();
        p1cups.create(game.world.centerX, cupH / 2, 'cup');
        p1cups.create(game.world.centerX - cupW, cupH / 2, 'cup');
        p1cups.create(game.world.centerX + cupW, cupH / 2, 'cup');
        p1cups.create(game.world.centerX - cupW / 2, cupH + (cupH / 2), 'cup');
        p1cups.create(game.world.centerX + cupW / 2, cupH + (cupH / 2), 'cup');
        p1cups.create(game.world.centerX, (cupH * 2) + (cupH / 2), 'cup');

        p2cups = game.add.group();
        p2cups.create(game.world.centerX, game.world.height - (cupH / 2), 'cup');
        p2cups.create(game.world.centerX - cupW, game.world.height - (cupH / 2), 'cup');
        p2cups.create(game.world.centerX + cupW, game.world.height - (cupH / 2), 'cup');
        p2cups.create(game.world.centerX - cupW / 2, game.world.height - (cupH / 2) - cupH, 'cup');
        p2cups.create(game.world.centerX + cupW / 2, game.world.height - (cupH / 2) - cupH, 'cup');
        p2cups.create(game.world.centerX, game.world.height - (cupH / 2) - (cupH * 2), 'cup');

        ball = game.add.sprite(game.world.centerX, game.world.centerY + (cupH*4),'ball');
        ball.anchor.setTo(0.5,0.5);
        ball.z = 0;
        ball.checkWorldBounds = true;
        ball.events.onOutOfBounds.add(restart,this);

        game.physics.enable([ball, p1cups,p2cups],Phaser.Physics.ARCADE);

        p1cups.forEach(function(item) {
            item.anchor.setTo(0.5);
            item.body.immovable = true;
        },this);

        p2cups.forEach(function(item) {
            item.anchor.setTo(0.5);
            item.body.immovable = true;
        },this);

        ball.body.bounce.set(0.50);
        ball.body.drag.set(20);
        ball.body.allowRotation = false;

        game.stage.backgroundColor = "#d3d3d3";

        game.input.onDown.add(onDown,this);
        game.input.onUp.add(throwBall,this);

        console.log(ball.scale);
    }

    function onDown() {
        clickTime = game.time.time;
    }

    function throwBall() {
        if (ballThrown == false) {
            var delta = game.time.time - clickTime;
            game.physics.arcade.velocityFromAngle(ball.angle, delta, ball.body.velocity);
            ballThrown = true;  
        }   
    }

    function update() {

        ball.rotation = game.physics.arcade.angleToPointer(ball);

        if (ballThrown) {

            game.physics.arcade.collide(ball,p1cups,collisionHandler,collisionProcess,this);    
            game.physics.arcade.collide(ball,p2cups,collisionHandler,collisionProcess,this);

            if (ballAscending) {
                ball.z = ball.z + 2;
                if (ball.z > 100 - bounces * 20) {
                    ballAscending = false;
                }
            } else {
                ball.z = ball.z - 2;
                if (ball.z < 1) {
                    bounces = bounces + 1;
                    ballAscending = true;
                }
            }

            ball.scale.set((ball.z + 100) / 100);

            if (Math.abs(ball.body.velocity.x) < 1 && Math.abs(ball.body.velocity.y) < 1 && ball.scale.x == 1) {
                restart();
            }

        }

    }

    function restart() {
        ball.body.velocity.set(0);
        ball.inputEnabled = true;
        ball.z = 0;
        bounces = 0;
        ball.position.x = game.world.centerX;
        ball.position.y = game.world.centerY + (cupH*4);
        ball.scale.set(1);
        ballThrown = false;
        checkCollisions = true;
        goalScored = false;
    }

    function collisionHandler(ball,cup) {
        return true;
    }

    function collisionProcess(ball,cup) {

        if (ball.x > cup.x &&
            ball.x + ball.width < cup.x + cup.width &&
            ball.y > cup.y &&
            ball.y + ball.height < cup.y + cup.height) {
            game.paused = true;
        }

        return false;

    }

}

【问题讨论】:

  • 我们需要能够重现所描述的行为。你能给我们展示一个最小的例子吗?
  • 当然,我会制作一个 JSFiddle 并发布我正在使用的确切代码,大约 150 行。一秒钟……
  • 刚刚用我的游戏的确切来源更新了我的问题,希望对您有所帮助...请注意问题发生在我的碰撞处理函数中。有时我在函数中的条件是正确地评估为“真”,有时不是。
  • 提问时,试着举一个简短的例子来清楚地说明你的问题。我们是懒惰的人,如果您的问题不容易理解,我们可能不会阅读完整的问题:S

标签: javascript css html phaser-framework


【解决方案1】:

如果要检查一个移相器矩形是否包含在另一个矩形中,可以使用Phaser.Rectangle.containsRect 函数。

由于精灵是一个移相器矩形,你可以这样做:

var a = game.add.sprite(100,100, 'a');
var b = game.add.sprite(120,120, 'b');
game.physics.arcade.enable(a);
game.physics.arcade.enable(b);

// this will print whether or not a is contained inside b
console.log(Phaser.Rectangle.containsRect(a.body, b.body));

ohbtw,您正在使用街机物理系统...如果您正在寻找复杂的几何动作,您可能应该使用 P2 系统;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多