0

私は、ユーザーがタッチするたびにスプライトを作成するゲームを開発しています。次に、スレッドを実行して、それらのスプライトが他のスプライトと衝突するかどうかを確認します。問題は、タップが速すぎると、nullポインタ例外エラーが発生することです。スレッドが実行されているよりも速くタップしているからだと思います。これは私が持っているスレッドです:

public class grow implements Runnable{

        public grow(Sprite sprite){

        }
        @Override
        public void run() {
            float radf, rads; //fill radius/stationary radius
            float fx=0, fy=0, sx, sy;

            while(down){
                if(spriteC[spriteNum].active){
                    spriteC[spriteNum].sprite.setScale(spriteC[spriteNum].scale += 0.001);
                    if(spriteC[spriteNum].sprite.collidesWith(ground)||spriteC[spriteNum].sprite.collidesWith(roof)||
                            spriteC[spriteNum].sprite.collidesWith(left)||spriteC[spriteNum].sprite.collidesWith(right)){
                        down = false;
                        spriteC[spriteNum].active=false;
                        yourScene.unregisterTouchArea(spriteC[spriteNum].sprite);
                    }

                    fx = spriteC[spriteNum].sprite.getX();
                    fy = spriteC[spriteNum].sprite.getY();
                    radf=spriteC[spriteNum].sprite.getHeightScaled()/2;

                    Log.e("F"+Float.toString(fx),Float.toString(fy));
                    if(spriteNum>0)
                         for(int x=0;x<spriteNum;x++){

                                rads=spriteC[x].sprite.getHeightScaled()/2;
                                sx = spriteC[x].body.getWorldCenter().x * 32;
                                sy = spriteC[x].body.getWorldCenter().y * 32;

                                Log.e("S"+Float.toString(sx),Float.toString(sy));
                                Log.e(Float.toString((float) Math.sqrt(Math.pow((fx-sx),2)+Math.pow((fy-sy),2))),Float.toString((radf+rads)));
                                if(Math.sqrt(Math.pow((fx-sx),2)+Math.pow((fy-sy),2))<(radf+rads)){
                                        down = false;
                                        spriteC[spriteNum].active=false;
                                        yourScene.unregisterTouchArea(spriteC[spriteNum].sprite);
                                        Log.e("Collided",Boolean.toString(down));
                                }
                         }
                }    
            }
            spriteC[spriteNum].body = PhysicsFactory.createCircleBody(mPhysicsWorld, spriteC[spriteNum].sprite, BodyType.DynamicBody, FIXTURE_DEF);
            mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(spriteC[spriteNum].sprite, spriteC[spriteNum].body, true, true));
        }
    }

誰かより良い解決策?ハンドラーと関係があることは知っていますが、それが何であるか、またはハンドラーをどのように使用するかは正確にはわかりません。

4

2 に答える 2

1

前述のように、ボタンをすばやく押したときにrun()メソッドがそれ自体とインターリーブしないように、「grow」Runnableの実行を同期する必要があります。おそらく、単純な同期メソッドまたはブロックを使用してこれを行うことができますが、より高度な制御が必要な場合は、キューも可能です。

速度については、traceviewでプロファイリングし、ボトルネックを見つけます。ユーザーが上でコメントしたように、ロギングはかなり高価になる可能性があります。

于 2012-06-24T04:19:31.163 に答える
0

それを行う方法を理解するのにしばらく時間がかかりましたが、更新ハンドラーは非常にうまく機能しました。シーン更新ハンドラーを使用しました。onCreateSceneでシーンを作成するときは、次のコードを実装します。

        scene.registerUpdateHandler(new IUpdateHandler() {

                @Override
                public void reset() {         
                }

                @Override
                public void onUpdate(float pSecondsElapsed) {
//Whatever you want to update. Any moving or scaling object essentially.
    }

誰かがより多くの情報を必要とするならば、 http: //www.andengine.org/forums/でrphello101にPMを送ってください。

于 2012-07-01T08:10:56.730 に答える