1

よろしくお願いします。

私は Arkanoid/Breakout スタイルのゲームを構築していますが、体の除去のためにいくつかの問題が発生しています (少なくとも、問題があると思われる場所です)。ゲームを実行すると、ほとんどの場合は問題なく動作しますが、ときどきゲームがクラッシュします。このクラッシュの間、ボディに添付されたすべてのスプライトが消え、ボディのないスプライトが画面に残ります。LogCat エラーはありませんが、FPS が大幅に遅くなります。また、連絡先リスナーのコードが起動される前に連絡先が 2 回登録される場合があることに気付きました (以下の ContactListener でログ ファイル出力を実装する場所を確認できます)。

ゲームでは、レンガの代わりにボルトを使用しています。ボルトを生成するために使用したコードを以下に示します。その後、ContactListener の使用方法を示し、その後、ボディとスプライトの組み合わせを削除するコードを示します。どんな助けや提案も大歓迎です!

ありがとう、

アダム

接触したときに削除されるボディ/スプライト アイテムを作成します。

//BOLTS
    final FixtureDef boltFixtureDef = PhysicsFactory.createFixtureDef(1, 1.0f, 0.1f);
    final Body[] boltBody=new Body[BOLT_NUMBER];
    final Sprite[] boltSprite=new Sprite[BOLT_NUMBER];
    final PhysicsConnector[] facePhysicsConnector= new PhysicsConnector[BOLT_NUMBER];
    String[] bodyNames=new String[BOLT_NUMBER];

        for(int i=0; i<BOLT_NUMBER; i++){
            boltSprite[i] = new Sprite(-100,-100, sceneManager.mBolt, sceneManager.activity.getVertexBufferObjectManager());
            boltSprite[i].setCullingEnabled(true);
            boltBody[i] = PhysicsFactory.createBoxBody(mPhysicsWorld, boltSprite[i], BodyType.KinematicBody, boltFixtureDef);
            mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(boltSprite[i], boltBody[i], true, true));
            bodyNames[i]="bolt"+Integer.toString(i);
            boltBody[i].setUserData(bodyNames[i]);
            facePhysicsConnector[i] = mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(boltSprite[i]);
            boltBody[i].setTransform(xLocations[i]/PMR, yLocations[i]/PMR, 0);}

            for(int i=0; i<BOLT_NUMBER; i++){       
                scene.attachChild(boltSprite[i]);}

ContactListener:

final ContactListener contact = new ContactListener(){

    @Override
    public void postSolve(Contact contact, ContactImpulse impulse) {

        String a = (String) contact.getFixtureA().getBody().getUserData();
        String b = (String) contact.getFixtureB().getBody().getUserData();
        if(a != null && b != null) {
            for(int i=0; i<BOLT_NUMBER; i++){
                if(a.equals("wrench") && b.equals(facePhysicsConnector[i].getBody().getUserData()) ||
                             a.equals(facePhysicsConnector[i].getBody().getUserData()) && b.equals("wrench")) {
                               //boltCollision[i]=true;
                    Log.i("contact","bolt contact" + i);
                               myDestroyer(facePhysicsConnector[i], true);
                               Log.i("contact","bolt POSTcontact" + i);}

                else if((a.equals("wrench") && b.equals("paddle")) ||
                        (a.equals("paddle") && b.equals("wrench"))) {
                    Log.i("contact","paddle contact");
                       SpringNoise=true;}

                else if((a.equals("wrench") && b.equals("door")) ||
                         (a.equals("door") && b.equals("wrench"))) {
                    Log.i("contact","door contact");
                           WoodNoise=true;}
            }}

    }
    @Override
    public void endContact(final Contact contact) {}

    @Override
    public void beginContact(Contact contact) {}

    @Override
    public void preSolve(Contact contact, Manifold oldManifold) {}
        };

ボディ/スプライトのコンボを削除するコードは次のとおりです。

private void myDestroyer(final PhysicsConnector facePhysicsConnector2, final Boolean bodyToo){
            if(killingInProcess == false){
                    killingInProcess = true;
                    //final PhysicsConnector facePhysicsConnector2 = mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape(myShape);
                    sceneValue.engine.registerUpdateHandler(new IUpdateHandler(){
                            @Override
                            public void onUpdate(float pSecondsElapsed) {
                                sceneValue.engine.unregisterUpdateHandler(this);
                                sceneValue.engine.runOnUpdateThread(new Runnable(){
                                                    @Override
                                                    public void run() {
                                                        Log.i("contact","removing bolt");
                                                            mPhysicsWorld.unregisterPhysicsConnector(facePhysicsConnector2);
                                                            Vibrator v = (Vibrator) sceneValue.activity.getSystemService(Context.VIBRATOR_SERVICE);
                                                            //myFixture.getBody().destroyFixture(myFixture);
                                                    if(bodyToo == true){
                                                                    mPhysicsWorld.destroyBody(facePhysicsConnector2.getBody());
                                                    }
                                                    facePhysicsConnector2.getShape().registerEntityModifier(new ParallelEntityModifier(new RotationModifier(3,180,0),
                                                    new ScaleModifier(3, 1, 0)));
                                                    sceneValue.mBlockSound.play();
                                                    v.vibrate(75);

                                                    //mScene.detachChild(mySprite);
                                                    System.gc();
                                                    killingInProcess = false;
                                                    }
                                            });
                            }
                            @Override
                            public void reset() {
                            }
                    });    
            }}
4

2 に答える 2

1

クラッシュの問題についてはよくわかりませんが、ボディの削除が遅すぎる理由はわかります。

このメソッドpostSolve UpdaeThreadから呼び出されます。ただし、本文を削除する代わりに、別の更新ハンドラーを登録します(したがって、コードは次のゲーム更新で実行されます)。そして、このコードでは、別のコードを実行して、次のゲームアップデートでrunOnUpdateThread再び実行されるようにします。理由もなく2つの更新をスキップしました:)これにより問題が発生する可能性があります(おそらく発生します)

これを修正することをお勧めします。これは別の問題を探します(これは深刻な場合があり、簡単に解決できます)

于 2012-11-09T00:36:03.347 に答える
1

よくわかりませんが、問題はスプライトの削除にあるのではないかと思います。私は問題に遭遇し、今、このような更新ハンドラでボディを強制終了しようとしています (IUpdateHandler のメソッド onUpdate):

                final PhysicsConnector physicsConnector = physicsWorld
                        .getPhysicsConnectorManager().findPhysicsConnectorByShape(
                                body);
                body.clearEntityModifiers();
                physicsWorld.unregisterPhysicsConnector(physicsConnector );
                physicsWorld.destroyBody(physicsConnector.getBody());
                scene.detachChild(body);
                activity.getEngine().unregisterUpdateHandler(this);
于 2012-11-09T15:12:47.030 に答える