2015-07-11 1 views
1

Моя проблема - обнаружение столкновения, которое я написал для объектов вражеских персонажей и объектов пули.Столкновение между вражескими персонажами и выстрелами - (Cocos2dx, C++, Android)

В Симптомах:

Когда 1 вражеские персонажи нерестятся и я стрелять с моими пулями, враг характер уничтожаются как обычно. Но если 2 или более вражеских персонажа появляются, и я стреляю в первого врага, который был порожден, он ничего не делает. Последний персонаж, который был порожден и застрелен, уничтожен без проблем.

Как я пытался это исправить:

я решил дать каждому вражеского персонажа уникальный идентификатор, создав переменную INT и рандомизации его каждый раз, когда порождены враг. Это гарантирует, что каждый объект персонажа противника определенно будет иметь уникальный идентификатор, чтобы, если я его застрелю, я могу как-то сопоставить этот уникальный идентификатор с моей пулей.

Однако я не знаю, как обойти это. Приведенный ниже код просто удаляет все вражеский характер, связанный с какими-либо рандомизированные теги

Мой вопрос:

Как я могу установить мои объекты пулевых держать каждый уникальный идентификатор моих вражеских персонажей, так что, когда пуля попадает один (не имеет значения, какой конкретный порядок), он будет искать, а затем сравнивать уникальные идентификаторы, которые он имеет, с идентификатором персонажа противника, который он снял?

Извините, если мой вопрос неясен или мой стиль кодирования ужасен.

GameScene.cpp

/** 
* @param ENEMY_SPAWN_FREQUENCY value is 0.002, set to make them spawn automatically every few seconds 
*/ 
void GameScene::updateScheduler() { 
    this -> scheduleUpdate(); 
    this -> schedule(schedule_selector(GameScene::spawnEnemyCharacter),  ENEMY_SPAWN_FREQUENCY * visibleSize.width); 
} 

// ... 

bool GameScene::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event) { 

    // fire button 
    auto target = (Sprite*)this -> getChildByTag(FIRE_BUTTON_TAG); 
    Rect rect = target  -> getBoundingBox(); 
    Point p  = touch   -> getLocation(); 

    // initialize bullets 
    if (rect.containsPoint(p)) { 
     GameScene::spawnBullets(PLAYER_TAG, playerCharacter->getPositionX(), playerCharacter->getPositionY()+100, 0, REFERENCE_SIZE_Y); 
     return true; 
    } 

    // ... 

    return false; 
} 

// ... somewhere below my GameScene.cpp class 

void GameScene::spawnBullets(int shooter_id, int x, int y, int p_x, int p_y) { 

    // load bullet sprites. 
    SpriteFrameCache::getInstance() -> addSpriteFramesWithFile("bullets.plist"); 

    // ... 

    auto bulletBody = PhysicsBody::createBox(bullet_sprite -> getContentSize()); 
    bulletBody  -> setDynamic(true); 
    bulletBody  -> setGravityEnable(false); 
    bulletBody  -> setCollisionBitmask(BULLET_COLLISION_BITMASK); 
    bulletBody  -> setContactTestBitmask(true); 

    bullet_sprite -> setPhysicsBody(bulletBody); 
    bullet_sprite -> setPosition(Point(x, y)); 
    bullet_sprite -> setScale(0.2f); 
    bullet_sprite -> setTag(BULLET_TAG); 
    this    -> addChild(bullet_sprite); 

    // animate bullet object so that it shoots 
    bullet_obj.fireBullet(bullet_sprite, p_x, p_y); 
} 

// ... somewhere further down this class i define my enemy characters to be spawned as enemy objects in the below method 

void GameScene::spawnEnemyCharacter(float dt) { 
    int random_tag = rand();  // ensure that each enemy character object has a unique random id as its tag 
    enemyCharacter_obj.spawnEnemy(this, random_tag); 
    enemy_tags.push_back(random_tag); 

// ... destroy enemy characters if hit by bullet: 

bool GameScene::onContactBegin(cocos2d::PhysicsContact &contact) { 
    PhysicsBody *a = contact.getShapeA() -> getBody(); 
    PhysicsBody *b = contact.getShapeB() -> getBody(); 

    if (BULLET_COLLISION_BITMASK == a->getCollisionBitmask() && ENEMY_COLLISION_BITMASK == b-> getCollisionBitmask() || 
     BULLET_COLLISION_BITMASK == b->getCollisionBitmask() && ENEMY_COLLISION_BITMASK == a-> getCollisionBitmask()) { 

     // delete enemys with random tag 
     for (std::vector<int>::iterator itl = enemy_tags.begin(); itl != enemy_tags.end(); ++itl) { 
      enemyCharacter_obj.destroyEnemyCharacter(this, *itl); 
     }  
     this -> removeChild(bullet_sprite); 
    } 

    return true; 
} 

Bullet.cpp

void Bullet::fireBullet(Sprite* bullet_sprite, int x, int y) { 
    auto bulletAction = Sequence::create(MoveBy::create(BULLETSPEED, Point(x, y)), CallFuncN::create(CC_CALLBACK_1(Bullet::doRemoveFromParentAndCleanup, this, true)), NULL); 
    bullet_sprite  -> runAction(bulletAction); 
} 

А теперь мой враг классовый характер:

void EnemyCharacter::spawnEnemy(cocos2d::Layer* layer, int random_tag) { 

    // データ読み込み 
    SpriteFrameCache::getInstance() -> addSpriteFramesWithFile("enemies.plist"); 

    // 敵キャラクター 
    enemyCharacter = Sprite::createWithSpriteFrameName("enemy_1.png"); 
    auto enemyCharacterBody = PhysicsBody::createBox(enemyCharacter -> getContentSize()/5); 

    // ... 

    auto enemyCharacterPosition = (random * visibleSize.height) + (enemyCharacter -> getContentSize().height/2); 
    enemyCharacterBody   -> setDynamic(false); 
    enemyCharacterBody   -> setCollisionBitmask(ENEMY_COLLISION_BITMASK); 
    enemyCharacterBody   -> setContactTestBitmask(true); 
    enemyCharacter    -> setScale(0.3f); 
    enemyCharacter    -> setTag(random_tag); 
    enemyCharacter    -> setPhysicsBody(enemyCharacterBody); 
    enemyCharacter    -> setPosition(Point(((random * visibleSize.width) + (enemyCharacter->getContentSize().width/2)), visibleSize.height)); 
    layer     -> addChild(enemyCharacter); 

    // ... 
} 

// .. further down this class 

void EnemyCharacter::destroyEnemyCharacter(cocos2d::Layer* layer, int randomized_tag) { 
    layer-> removeChild(layer -> getChildByTag(randomized_tag)); 
} 
+0

выбор случайного числа для «обеспечения того, чтобы каждый объект персонажа противника определенно имел уникальный идентификатор» является промахом , Уникальность может быть, скорее всего, выбором такого подхода, но не обеспечена. Совершенно верно, что это не проблема, с которой вы столкнулись, для которой я не представляю себя, я подумал, что я брошу вас на то, что вы оставите еще одну неприятность позже. – mikyra

+0

Привет, я не уверен, что вы имеете в виду ... не могли бы вы рассказать, когда вы сказали: «Уникальность может быть, скорее всего, выбором такого подхода, но не обеспечена»? благодаря! –

+0

Если вам не повезло 'int random_tag = rand();' может генерировать число, которое уже используется как тэг для другого врага. – mikyra

ответ

0

Я закончил использование Box2D в моем случае, добавив каждый объект в CCArray, а затем пересек его в моем методе обновления. Я думаю, что мой вопрос зависит только от моих потребностей, поэтому, скорее всего, это не будет полезно для кого-либо.