所以我正在开发这个游戏,我想实现一个分数系统。 这是我第一次使用Cocos2d。 我尝试了几件事,但并没有真正取得成功。
我希望如果对于从场景中删除的每个敌人,名称得分的int将增加1。
你们有什么建议吗?
#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 :(得分:0)
我不确定我是否完全理解你的问题,但似乎你想创建一个标签来显示当前的分数。
当然,您需要一个变量来跟踪您的分数。我们假设变量是一个整数,它被称为 m_score 。
然后,您需要为场景创建并添加标签。在 init()函数中添加:
m_scoreLabel = Label::createWithTTF(std::to_string(m_score), "fonts/Arial.ttf", 36);
this->addChild(m_scoreLabel);
您需要 m_scoreLabel 来保留对 Label 的引用,以便稍后您可以更改其显示文本。现在,每当您更改分数时,首先更新 m_score 的值,然后更新标签调用所显示的文本:
m_scoreLabel->setString(std::to_string(m_score));