2016-06-05 2 views
0

Итак, я работаю над этой игрой, и я хочу реализовать систему оценки. Это первый раз, когда я работаю с Cocos2d. Я пробовал пару вещей, но на самом деле не имел успеха.Cocos2d C++ Score system

Хотелось бы, чтобы для каждого врага, который удаляется со сцены, int с оценкой имени будет увеличен на единицу.

У вас есть предложения?

#include "HelloWorldScene.h" 
#include "SimpleAudioEngine.h" 
using namespace CocosDenshion; 

USING_NS_CC; 

#define BACKGROUND_MUSIC_SFX "bee.mp3" 
#define PEW_PEW_SFX   "splatter.mp3" 

// These bit masks define the physics categories; monster + projectile with two values to specify no type or all types, I use this to see what objects are allowed to collide 
enum class PhysicsCategory { 
    None = 0, 
    Monster = (1 << 0), // 1 
    Projectile = (1 << 1), // 2 
    All = PhysicsCategory::Monster | PhysicsCategory::Projectile // 3 
}; 

Scene* HelloWorld::createScene() 
{ 
    // 'scene' is an autorelease object, turn psysics on 
    auto scene = Scene::createWithPhysics(); 
    scene->getPhysicsWorld()->setGravity(Vec2(0,0)); 
    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_NONE); 

    // 'layer' is an autorelease object 
    auto layer = HelloWorld::create(); 

    // add layer child to scene 
    scene->addChild(layer); 

    // return scene 
    return scene; 
} 

// initialize instance 
bool HelloWorld::init() 
{ 
    // call the super class’s init method, if succeeds proceed HelloWorldScene‘s setup 
    if (!Layer::init()) { 
    return false; 
    } 
    // get window bounds using game Director singleton. 
    auto origin = Director::getInstance()->getVisibleOrigin(); 
    auto winSize = Director::getInstance()->getVisibleSize(); 
    // create a DrawNode to draw a green rectangle that fills the screen 
    auto background = DrawNode::create(); 
    background->drawSolidRect(origin, winSize, Color4F(0.0,0.6,0.0,0.7)); 
    this->addChild(background); 
    // create the player sprite, position 10% from the left edge of the screen, centered vertically 
    _player = Sprite::create("player.png"); 
    _player->setPosition(Vec2(winSize.width * 0.1, winSize.height * 0.5)); 
    this->addChild(_player); 

    // seed the random number generator 
    srand((unsigned int)time(nullptr)); 
    this->schedule(schedule_selector(HelloWorld::addMonster), 1.5); 

    auto eventListener = EventListenerTouchOneByOne::create(); 
    eventListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this); 
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener, _player); 

    auto contactListener = EventListenerPhysicsContact::create(); 
    contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegan, this); 
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this); 

    SimpleAudioEngine::getInstance()->playBackgroundMusic(BACKGROUND_MUSIC_SFX, true); 

    return true; 
} 


void HelloWorld::menuCloseCallback(Ref* pSender) 
{ 
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) 
    MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); 
    return; 
#endif 

    Director::getInstance()->end(); 

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 
    exit(0); 
#endif 
} 

void HelloWorld::addMonster(float dt) { 
    auto monster = Sprite::create("monster.png"); 

    //Create a PhysicsBody for the sprite, Physics bodies represent the object in Cocos2d physics simulation. 
    auto monsterSize = monster->getContentSize(); 
    auto physicsBody = PhysicsBody::createBox(Size(monsterSize.width , monsterSize.height), 
              PhysicsMaterial(0.1f, 1.0f, 0.0f)); 
    //Set the sprite to be dynamic. physics engine will not apply forces to the bear. 
    physicsBody->setDynamic(true); 
    // set the category, collision and contact test bit masks: 
    physicsBody->setCategoryBitmask((int)PhysicsCategory::Monster); 
    physicsBody->setCollisionBitmask((int)PhysicsCategory::None); 
    physicsBody->setContactTestBitmask((int)PhysicsCategory::Projectile); 

    monster->setPhysicsBody(physicsBody); 

    // create a bear sprite and place it offscreen to the right, random y position 
    auto monsterContentSize = monster->getContentSize(); 
    auto selfContentSize = this->getContentSize(); 
    int minY = monsterContentSize.height/2; 
    int maxY = selfContentSize.height - monsterContentSize.height/2; 
    int rangeY = maxY - minY; 
    int randomY = (rand() % rangeY) + minY; 

    monster->setPosition(Vec2(selfContentSize.width + monsterContentSize.width/2, randomY)); 
    this->addChild(monster); 

    // random duration for bear, each bear will move the same distance across the screen, varying the duration results in bears with random speeds. 
    int minDuration = 2.0; 
    int maxDuration = 4.0; 
    int rangeDuration = maxDuration - minDuration; 
    int randomDuration = (rand() % rangeDuration) + minDuration; 

    // move the bear across the screen. 
    auto actionMove = MoveTo::create(randomDuration, Vec2(-monsterContentSize.width/2, randomY)); 
    auto actionRemove = RemoveSelf::create(); 
    monster->runAction(Sequence::create(actionMove,actionRemove, nullptr)); 
} 

bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event) { 
    // 1 - get the _player object 
    //auto node = unused_event->getCurrentTarget(); 

    // coordinate of the click within the scene’s coordinate system, calculate the offset of this point from the current position. vector math. 
    Vec2 touchLocation = touch->getLocation(); 
    Vec2 offset = touchLocation - _player->getPosition(); 

    // If offset‘s x value is negative, the player tries to shoot backwards,return without firing. 
    if (offset.x < 0) { 
    return true; 
    } 

    // Create projectile, add to screen 
    auto projectile = Sprite::create("projectile.png"); 
    projectile->setPosition(_player->getPosition()); 
    auto projectileSize = projectile->getContentSize(); 
    auto physicsBody = PhysicsBody::createCircle(projectileSize.width/2); 
    physicsBody->setDynamic(true); 
    physicsBody->setCategoryBitmask((int)PhysicsCategory::Projectile); 
    physicsBody->setCollisionBitmask((int)PhysicsCategory::None); 
    physicsBody->setContactTestBitmask((int)PhysicsCategory::Monster); 
    projectile->setPhysicsBody(physicsBody); 

    this->addChild(projectile); 

    // call normalize() to convert the offset into a unit vector, which is a vector of length 1. Multiplying that by 1000 that points in the direction of the user’s tap. 
    offset.normalize(); 
    auto shootAmount = offset * 1000; 

    // Adding the vector to the projectile’s position gives the target position. 
    auto realDest = shootAmount + projectile->getPosition(); 

    // move the projectile to the target position, remove after 5 sec. 
    auto actionMove = MoveTo::create(5.0f, realDest); 
    auto actionRemove = RemoveSelf::create(); 
    projectile->runAction(Sequence::create(actionMove,actionRemove, nullptr)); 

    SimpleAudioEngine::getInstance()->playEffect(PEW_PEW_SFX); 

    return true; 
} 


// PhysicsContact passed to this method is collision, remove at the end 
bool HelloWorld::onContactBegan(PhysicsContact &contact) { 
    auto nodeA = contact.getShapeA()->getBody()->getNode(); 
    auto nodeB = contact.getShapeB()->getBody()->getNode(); 

    nodeA->removeFromParent(); 
    nodeB->removeFromParent(); 
    return true; 
} 

ответ

0

Я не уверен, что полностью понял ваш вопрос, но, похоже, вы хотите создать ярлык, чтобы показать текущий счет.

Конечно, вам понадобится переменная, чтобы отслеживать ваш результат. Предположим, что переменная является целым числом и называется m_score.

Затем вы должны создать и добавить ярлык к вашей сцене. В вашем Init() функция добавления:

m_scoreLabel = Label::createWithTTF(std::to_string(m_score), "fonts/Arial.ttf", 36); 
this->addChild(m_scoreLabel); 

Вам потребуется m_scoreLabel сохранить ссылку на ваш Этикетка так, что вы будете иметь возможность изменить отображаемый текст позже. Теперь, когда вы изменить счет, первое обновление значения m_score, а затем обновить текст, показанный по зову этикетки:

m_scoreLabel->setString(std::to_string(m_score)); 
+0

Я думаю, что это хороший подход, как бы я добавить +1 к m_score, когда узлы удаляются из родителя (последний бит кода)? – Labrador

+0

Очевидно, что _ ++ m_score_ должен выполнять эту работу. Убедитесь, что _m_score_ является переменной-членом в вашем классе _HelloWorld_. – mpium