সংঘর্ষ ঘটলে একটি বক্স 2 ডি বডি কীভাবে সরিয়ে ফেলা যায়?


10

আমি এখনও জাভা এবং অ্যান্ড্রয়েড প্রোগ্রামিংয়ে নতুন এবং আমার খুব সমস্যা হচ্ছে যখন সংঘর্ষ ঘটে তখন কোনও বস্তু সরানো। আমি ওয়েবটি ঘুরে দেখলাম যে সংঘর্ষ সনাক্তকরণের সময় আমার কখনই BOX2D মৃতদেহগুলি অপসারণ করা উচিত নয় (কোনও পরিচিতি শ্রোতা) এবং আমার জিনিসগুলি একটি অ্যারেলিস্টে যুক্ত করা উচিত এবং মুছতে বা না এবং পরিচালনা করতে শরীরের ইউজার ডেটা বিভাগে একটি পরিবর্তনশীল সেট করা উচিত একটি আপডেট হ্যান্ডলারের অপসারণ কর্ম। সুতরাং আমি এটি করেছি: প্রথমে আমি দুটি অ্যারেলিস্ট সংজ্ঞা দিয়েছি একটির মুখের জন্য এবং একটির দেহের জন্য:

ArrayList<Sprite> myFaces = new ArrayList<Sprite>();
ArrayList<Body> myBodies = new ArrayList<Body>();

তারপরে আমি যখন কোনও মুখ তৈরি করি এবং সেই মুখটিকে তার শরীরে সংযুক্ত করি তখন আমি তাদের এ্যারেলিস্টে তাদের যুক্ত করে:

face = new AnimatedSprite(pX, pY, pWidth, pHeight, this.mBoxFaceTextureRegion);
Body BoxBody = PhysicsFactory.createBoxBody(mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, BoxBody, true, true));

myFaces.add(face);
myBodies.add(BoxBody);

এখন আমি এইভাবে অনলোডসিনে একটি পরিচিতি শ্রোতা এবং একটি আপডেট হ্যান্ডলার যুক্ত করি:

this.mPhysicsWorld.setContactListener(new ContactListener() {
private AnimatedSprite face2;
@Override
public void beginContact(final Contact pContact) {
}
@Override
public void endContact(final Contact pContact) {
}
@Override
public void preSolve(Contact contact,Manifold oldManifold) {

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



scene.registerUpdateHandler(new IUpdateHandler() {


@Override
public void reset() { }

@Override
public void onUpdate(final float pSecondsElapsed) {

}
});

আমার পরিকল্পনাটি হ'ল শরীরের ব্যবহারকারীর ডেটা বিভাগ থেকে পরিবর্তনশীল পরীক্ষা করে কোন দুটি সংস্থার যোগাযোগের শ্রোতার সাথে সংঘর্ষ হয়েছিল, তাদের সংখ্যা অ্যারে তালিকায় পাওয়া যাবে এবং অবশেষে এই মৃতদেহগুলি অপসারণ করতে আপডেট হ্যান্ডলারটি ব্যবহার করুন detect

প্রশ্নগুলি হ'ল: আমি কি অ্যারেলিস্টটি সঠিকভাবে ব্যবহার করছি? কীভাবে ব্যবহারকারীর ডেটাতে ভেরিয়েবল যুক্ত করবেন (কোডটি দয়া করে)। আমি এই আপডেট হ্যান্ডলারের একটি শরীর অপসারণ করার চেষ্টা করেছি তবে এটি এখনও আমাকে নুলপয়েন্টারএক্সেপশন ছুড়ে ফেলেছে, তাই আপডেট হ্যান্ডলার যুক্ত করার সঠিক উপায় কী এবং আমি কোথায় যুক্ত করব। এটি করার জন্য অন্য কোনও পরামর্শ দুর্দান্ত। আগাম ধন্যবাদ.

উত্তর:


7

জবক্স 2 ডি-তে সঠিক সময়ে অপসারণ করতে:

public class Main
{
    World world;
    ...

    public void update() //your game loop
    {
        ... //do all actual update loop stuff, including detection of collision/death/destruction
        for (Entity entity : manager.entitiesToRemove)
        {
            world.destroyBody(entity.body); //this might be all you need -- adapt to your own purposes. but you will still need a list such that you remove only at the end of each tick.
        }

        manager.entitiesToRemove.clear();
    }
}

public class Entity
{
    Body body; //body representing this Entity
    EntityManager manager; //set ref via Entity constructor
    ...

    //Call from your contact listener when the entity expires
    //body.userData is set to the Entity representing that body
    //so you can get access to the Entity from the Body, as vice versa.
    public void die()
    {
        manager.removeEntity(this);
    }
    ...
}   

public class EntityManager
{
    public List<Entity> entities = new ArrayList<Entity>(); //extant entities
    public List<Entity> entitiesToAdd = new ArrayList<Entity>(); //forthcoming entities
    public List<Entity> entitiesToRemove = new ArrayList<Entity>(); //erstwhile entities <-- the important one for you.
    ...
    public void remove()
    {
        if (!stage.entitiesToRemove.contains(entity))
            stage.entitiesToRemove.add(entity);
            //or just use a Set<Entity>, as dual additions are implicitly prevented.
    }
    ...
    //also add(), and other utility functions for managing entities.
}   

ব্যবহার করুন body.getUserData()এবং body.setUserData()পড়তে ও লিখতে userDataউপর Body


1

আমি সপ্তাহে আগে একই সমস্যা ছিল কিন্তু সি ++ এ এবং আমি ইন্টারনেটে সমাধান খুঁজে পাই! আমি বক্স 2 ডি ওয়ার্ল্ড-> পদক্ষেপের পরে যে পদ্ধতি কোডটি ব্যবহার করছি তা এখানে রয়েছে এবং এটি কার্যকর করে:

void physics::clean_up() {
std::vector<b2Body *> to_nuke;

b2Body * body = _world->GetBodyList();
for(; body; body = body->GetNext()) {
    gx::sprite * sprite = (gx::sprite *)body->GetUserData();
    if(sprite->is_killed()) {
        to_nuke.push_back(body);
    }
}

std::sort(to_nuke.begin(), to_nuke.end());
// destroying, but skip duplicates!
uint i = 0;
uint size = to_nuke.size();
while(i < size) {
    b2Body * b = to_nuke[i++];
    while(i < size && to_nuke[i] == b) {
        ++i;
    }
    _world->DestroyBody(b);
    b = 0;
}

পোর্টিং সহ শুভকামনা এবং আপনার দিনটি শুভ হোক। আমি আশা করি আপনি এই সহায়তায় আপনার সময় সাশ্রয় করবেন;)

সম্পাদনা করুন: পদ্ধতি স্প্রিট-> is_killed () স্প্রাইট এবং এর দৈহিক শরীর অপসারণের জন্য প্রস্তুত কিনা তা পরীক্ষা করে দেখুন।


1
-1, প্রশ্নটি জাভা সম্পর্কিত এবং এটি একটি ভাষা যা বিভিন্ন ভাষায় বেশ আলাদা। এটি খুব ভাল সি ++ও নয় - একটি এসটিডি :: সেট বা এসটিডি :: আনর্ডারড_সেট ব্যবহার করে দেখুন, এবং ধ্বংসকে পরিচালনা করতে আমি একটি এসটিএল অ্যালগরিদম বা কমপক্ষে আরও ভাল লুপ শর্ত ব্যবহার করব।

1

আপনি যদি isDeadআপনার ব্যবহারকারীর ডেটাতে একটি পতাকা যুক্ত করতে চান , আপনি যখন এটি তৈরি করবেন তখন আপনার ব্যবহারকারী ডেটা হিসাবে যা সেট করুন তাতে এটি যুক্ত করুন Body

GameObject box = new GameObject(face, boxBody);
boxBody.setUserData(box);

তারপরে endContact()পতাকাগুলিতে আপনি মৃত হিসাবে মরতে চান দেহগুলি:

if( a collision happens ) {
    ((GameObject) bodyA.getUserData()).setDead(true);
    ((GameObject) bodyB.getUserData()).setDead(true);
}

তারপরে নিশ্চিত হয়ে নিন যে আপনি মৃত জিনিসগুলি সরিয়ে ফেলছেন update()। ফিজিক্স ওয়ার্ল্ড আপডেট হওয়ার সময় এটি করবেন না:

foreach(GameObject go : gameObjects) {
    if(go.isDead()) {
         destroyGameObject(go);
         go.onDestroyed();
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.