cocos2d - collision callback doesn't invoke - cocos2d-iphone

I'am trying to build a simple game with a ball and target,
and I want to increse the score when the ball touch the target,
but the callback "onContactBegin" doesnt invoke.
There is a target("goal") in the button of the screen, and when the user touch the screen the ball created and start moving.
#include <string>
#include "HelloWorldScene.h"
#define COCOS2D_DEBUG 1
USING_NS_CC;
enum class PhysicsCategory {
None = 0,
Goal = (1 << 0),
Ball = (1 << 1),
All = PhysicsCategory::Goal | PhysicsCategory::Ball
};
Scene* HelloWorld::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
bool HelloWorld::init()
{
CCLOG("Init");
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
height = visibleSize.height;
width = visibleSize.width;
score = 0;
m_score_label = Label::createWithTTF(Itos(score), "fonts/Marker Felt.ttf", 24);
auto vSize = Director::getInstance()->getVisibleSize();
m_score_label->setPosition(Point(origin.x + vSize.width/2,
origin.y + vSize.height - m_score_label->getContentSize().height));
this->addChild(m_score_label, 1);
goal = Sprite::create("images.jpg");
goal->setPosition(Point((visibleSize.width / 2) + origin.x , (visibleSize.height / 6) + origin.y));
auto goalSize = goal->getContentSize();
auto physicsBody = PhysicsBody::createBox(Size(goalSize.width , goalSize.height),
PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setCategoryBitmask((int)PhysicsCategory::Goal);
physicsBody->setCollisionBitmask((int)PhysicsCategory::None);
physicsBody->setContactTestBitmask((int)PhysicsCategory::Ball);
goal->setPhysicsBody(physicsBody);
mySprite = Sprite::create("CloseNormal.png");
mySprite->setPosition(Point((visibleSize.width / 2) + origin.x , (visibleSize.height / 2) + origin.y));
this->addChild(mySprite);
this->addChild(goal);
CCScaleBy* action = CCScaleBy::create(3,5);
mySprite->runAction(action);
auto eventListener = EventListenerTouchOneByOne::create();
eventListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(eventListener, this);
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegan, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this);
return true;
}
bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event) {
cocos2d::Sprite * sp = Sprite::create("CloseNormal.png");
sp->setPosition(Point(touch->getLocation().x , touch->getLocation().y));
MoveTo *action = MoveTo::create(2, Point(width ,0) );
auto ballSize = sp->getContentSize();
auto physicsBody = PhysicsBody::createBox(Size(ballSize.width , ballSize.height),
PhysicsMaterial(0.1f, 1.0f, 0.0f));
physicsBody->setDynamic(true);
physicsBody->setCategoryBitmask((int)PhysicsCategory::Ball);
physicsBody->setCollisionBitmask((int)PhysicsCategory::None);
physicsBody->setContactTestBitmask((int)PhysicsCategory::Goal);
sp->setPhysicsBody(physicsBody);
sp->runAction( action );
this->addChild(sp);
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
}
bool HelloWorld::onContactBegan(PhysicsContact &contact)
{
CCLOG("onContactBegan");
auto nodeA = contact.getShapeA()->getBody()->getNode();
auto nodeB = contact.getShapeB()->getBody()->getNode();
nodeA->removeFromParent();
nodeB->removeFromParent();
++score ;
m_score_label->setString(Itos(score));
return true;
}
std::string HelloWorld::Itos ( int num )
{
std::ostringstream ss;
ss << num;
return ss.str();
}

HelloWorld.cpp
Scene* HelloWorld::createScene() {
auto scene = Scene::createWithPhysics();
auto layer = HelloWorld::create();
layer->setPhysicsWorld(scene->getPhysicsWorld());
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
scene->addChild(layer);
return scene;
}
bool GameScene::didBeginContact(cocos2d::PhysicsContact &contact) {
PhysicsBody *bodyA = contact.getShapeA()->getBody();
PhysicsBody *bodyB = contact.getShapeB()->getBody();
}
HelloWorld.h
cocos2d::PhysicsWorld *physicsWorld;
void setPhysicsWorld(cocos2d::PhysicsWorld *withWorld) {physicsWorld = withWorld;};
bool didBeginContact(cocos2d::PhysicsContact &contact);

Related

Scene freezes after transitioning in cocos2dx

After I transition to the HelloWorldScene from the GameLayerScene, the scene (HelloWorldScene)freezes and the buttons are not clickable. Is it wrong to use replaceScene? How can I implement a function to return to the main menu from the main game? I used push and pop as well but not working.
GameLayerScene
Scene* GameLayer::createScene(int level)
{
auto scene = Scene::create();
auto layer = GameLayer::create(level);
scene->addChild(layer);
return scene;
}
GameLayer* GameLayer::create(int level)
{
GameLayer *pRet = new GameLayer();
pRet->init(level);
pRet->autorelease();
return pRet;
}
bool GameLayer::init(int level)
{
if (!Layer::init())
return false;
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(_swallowsTouches);
touchListener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this);
touchListener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this);
touchListener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this);
touchListener->onTouchCancelled = CC_CALLBACK_2(GameLayer::onTouchCancelled, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
_level = level;
//This will be shown when the pause is pressed.
auto pauseLayer=LayerColor::create(Color4B::BLACK, WINSIZE.width, WINSIZE.height);
auto pauseLabel=Label::createWithTTF("Paused", "fonts/Marker Felt.ttf", 24);
pauseLabel->setPosition(WINSIZE.width / 2.0, (WINSIZE.height/ 2.0) + 100);
pauseLayer->addChild(pauseLabel);
// Add your required content to pauseLayer like pauseLabel
auto resumeButton = cocos2d::ui::Button::create("resume.png");
resumeButton->setPosition(Vec2(WINSIZE.width / 2.0, WINSIZE.height/ 2.0));
resumeButton->addClickEventListener([pauseLayer](Ref*){
//
if(Director::getInstance()->isPaused()) {
Director::getInstance()->resume();
pauseLayer->setVisible(false);
}
});
auto menuButton = cocos2d::ui::Button::create("menu.png");
menuButton->setPosition(Vec2(WINSIZE.width / 2.0, (WINSIZE.height/ 2.0) - 100));
menuButton->addClickEventListener([pauseLayer](Ref*){
Director::getInstance()->replaceScene(HelloWorldScene::createScene());
// Director::getInstance()->end();
});
pauseLayer->addChild(resumeButton);
pauseLayer->addChild(menuButton);
pauseLayer->setVisible(false);
pauseLayer->setOpacity(220); // so that gameplay is slightly visible
addChild(pauseLayer, ZOrder::Level);
AppDelegate
bool AppDelegate::applicationDidFinishLaunching()
{
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview)
{
glview = GLViewImpl::create("KaratePuzzle");
director->setOpenGLView(glview);
}
director->setDisplayStats(false);
director->setAnimationInterval(1.0 / 60);
glview->setDesignResolutionSize(640, 1136, ResolutionPolicy::FIXED_WIDTH);
auto scene = HelloWorldScene::createScene();
director->runWithScene(scene);
return true;
}
HelloWorldScene
Scene* HelloWorldScene::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorldScene::create();
scene->addChild(layer);
return scene;
}
HelloWorldScene::HelloWorldScene()
{
}
HelloWorldScene::~HelloWorldScene()
{
}
bool HelloWorldScene::init()
{
if (!Layer::init()) {
return false;
}
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("battle.mp3", true);
auto director = Director::getInstance();
auto winSize = director->getWinSize();
auto background = Sprite::create("main_back.png");
background->setPosition(Vec2(winSize.width / 2.0, winSize.height / 2.0));
this->addChild(background);
auto logo = Sprite::create("logo.png");
logo->setPosition(Vec2(winSize.width / 2.0, winSize.height - 150));
this->addChild(logo);
auto menuButton = MenuItemImage::create("start.png","start.png","start.png",CC_CALLBACK_1(HelloWorldScene::ImageButton,this));
// menuButton->setPosition(Vec2(winSize.width / 2.0, winSize.height /2.0));
menuButton->setPosition(Vec2(winSize.width / 2.0, ((winSize.height /2.0) - 300)));
menuButton->setScale(1.5f);
auto blink = Sequence::create(FadeTo::create(0.5, 127),
FadeTo::create(0.5, 255),
NULL);
menuButton->runAction(RepeatForever::create(blink));
this->addChild(menuButton);
auto moreButton = MenuItemImage::create("more.png","more.png","more.png",[](Ref*sender){
std::string url = "https://play.google.com/xxx";
cocos2d::Application::getInstance()->openURL(url);
});
winSize.height /2.0));
moreButton->setPosition(Vec2(winSize.width / 2.0, 90));
this->addChild(moreButton);
auto menu = Menu::create(menuButton,moreButton, NULL);
menu->setPosition(Point(0,0));
this->addChild(menu);
return true;
}
//Click event for menuButton
void HelloWorldScene::ImageButton(cocos2d::Ref *pSender) {
// stop background music
CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic();
this->getEventDispatcher()->removeAllEventListeners();
auto delay = DelayTime::create(0.5);
auto startGame = CallFunc::create([]{
auto scene = GameLayer::createScene();
auto transition = TransitionPageTurn::create(0.5, scene, true);
Director::getInstance()->replaceScene(transition);
// CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic();
});
this->runAction(Sequence::create(delay,startGame,
NULL));
}
void HelloWorldScene::onEnterTransitionDidFinish()
{
//CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic(AudioUtils::getFileName("title").c_str());
}
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorldScene :public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();
HelloWorldScene();
virtual ~HelloWorldScene();
bool init() override;
void onEnterTransitionDidFinish() override;
CREATE_FUNC(HelloWorldScene);
void ImageButton(Ref *pSender);
};
#endif // __HELLOWORLD_SCENE_H__
GameLayerScene.h
#include "cocos2d.h"
#include <random>
#include "BallSprite.h"
#include "Character.h"
class GameLayer : public cocos2d::Layer
{
protected:
enum class Direction
{
x,
y,
};
enum ZOrder
{
BgForCharacter = 0,
BgForPuzzle,
Enemy,
EnemyHp,
Char,
CharHp,
Ball,
Level,
Result,
};
std::default_random_engine _engine;
std::discrete_distribution<int> _distForBall;
std::uniform_int_distribution<int> _distForMember;
BallSprite* _movingBall;
bool _movedBall;
bool _touchable;
int _maxRemovedNo;
int _chainNumber;
std::vector<std::map<BallSprite::BallType, int>> _removeNumbers;
Character* _enemyData;
cocos2d::Sprite* _enemy;
cocos2d::ProgressTimer* _hpBarForEnemy;
cocos2d::Vector<Character*> _memberDatum;
cocos2d::Vector<cocos2d::Sprite*> _members;
cocos2d::Vector<cocos2d::ProgressTimer*> _hpBarForMembers;
int _level;
int _nextLevel;
void initBackground();
void initBalls();
BallSprite* newBalls(BallSprite::PositionIndex positionIndex, bool visible);
BallSprite* getTouchBall(cocos2d::Point touchPos, BallSprite::PositionIndex withoutPosIndex = BallSprite::PositionIndex());
void movedBall();
void checksLinedBalls();
bool existsLinedBalls();
cocos2d::Map<int, BallSprite*> getAllBalls();
bool isSameBallType(BallSprite::PositionIndex current, Direction direction);
void initBallParams();
void checkedBall(BallSprite::PositionIndex current, Direction direction);
void removeAndGenerateBalls();
void generateBalls(int xLineNum, int fallCount);
void animationBalls();
void initEnemy();
void initMembers();
void calculateDamage(int &chainNum, int &healing, int &damage, std::set<int> &attackers);
bool isAttacker(BallSprite::BallType type, Character::Element element);
void attackToEnemy(int damage, std::set<int> attackers);
void healMember(int healing);
void attackFromEnemy();
void endAnimation();
cocos2d::Spawn* vibratingAnimation(int afterHp);
void initLevelLayer();
void removeLevelLayer(float dt);
void winAnimation();
void loseAnimation();
void nextScene(float dt);
public:
GameLayer();
virtual bool init(int level);
static GameLayer* create(int level);
static cocos2d::Scene* createScene(int level = 1);
virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* unused_event);
virtual void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* unused_event);
virtual void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* unused_event);
virtual void onTouchCancelled(cocos2d::Touch* touch, cocos2d::Event* unused_event);
void PauseButton(Ref *pSender);
};
#endif
I've not tested your code but it seems problem in this statement :
auto menu = Menu::create(menuButton,moreButton, NULL);
It'll give runtime exception because menuButton and moreButton already added. It can't be added again.
I was able to solve the problem.The problem was due to the scene still paused without being resumed.
auto menuButton = cocos2d::ui::Button::create("menu.png");
menuButton->setPosition(Vec2(WINSIZE.width / 2.0, (WINSIZE.height/ 2.0) - 100));
menuButton->addClickEventListener([pauseLayer](Ref*){
if (Director::getInstance()->isPaused()) {
Director::getInstance()->resume();
}
Director::getInstance()->replaceScene(HelloWorldScene::createScene());
// Director::getInstance()->end();
});

jump on sprite touch using box2d

I am new cocos2dx developer.I am using cocos2dx v3.7.1. now i want to jump sprite on touch the sprite.I refer many answer but i am confused.
i implement below code in HelloWorld.cpp file
Scene* HelloWorld::createScene()
{
auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
//scene->getPhysicsWorld()->setGravity(Vec2(0,0.0));
auto layer = HelloWorld::create();
layer->SetPhysicsWorld( scene->getPhysicsWorld() );
scene->addChild(layer);
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
auto dispatcher = Director::getInstance()->getEventDispatcher();
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->setSwallowTouches(true);
touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
touchListener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
sprite3 = Sprite::create("kartoon.png");
sprite3->setPosition(Point(40,40));
sprite3->setAnchorPoint(Vec2(0,0)); spritibody=PhysicsBody::createBox(sprite3->getContentSize(),PhysicsMaterial(0,1,0));
sprite3->setPhysicsBody( spritibody );
spritibody->setDynamic(true);
this->addChild(sprite3,4);
this->schedule(SEL_SCHEDULE(&HelloWorld::chek),0.01f);
return true;
}
void HelloWorld::chek()
{
if (sprite3->getPosition().y>109) {
yvel-=0.1;
}
else{
if(yvel!=6)
{
xvel=0;
yvel=0;
}
}
sprite3->setPosition(Vec2(sprite3->getPosition().x+xvel,sprite3->getPosition().y+yvel));
}
bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
{
CCLOG("onTouchBegan x = %f, y = %f", touch->getLocation().x, touch->getLocation().y);
auto target = static_cast<Sprite*>(event->getCurrentTarget());
Point locationInNode = target->convertToNodeSpace(touch->getLocation());
if(sprite3->boundingBox().containsPoint(locationInNode))
{
// spritibody->setVelocity(Vec2(2, 0));
spritibody->applyImpulse(Vec2(0,40));
sprite3->setPhysicsBody(spritibody);
spritibody->setGravityEnable(true);
}
return true;
}
In this when i tap on sprite, its jump continous and after some type sprite3 go out off screen.But i want to only jump one time when i tap on sprite3.
plese help me.

cocos2d-x CCControlSlider doesn't slide

i try to follow the cocose2d-x 2.2 Test file :
cocos2d-x-2.2\samples\Cpp\TestCpp\Classes\SchedulerTest\SchedulerTest.h
i implemented the slider control and i see it and the :
virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
function are triggerd just right when i try to slide
but its not sliding at all this is what i have :
the default close menu is working find :
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
bSliderCtlTouched = false;
this->setTouchEnabled(true);
this->schedule(schedule_selector(HelloWorld::tick));
return true;
}
void HelloWorld::tick(float dt)
{
;
}
void HelloWorld::onEnter()
{
CCLayer::onEnter();
CCSize s = CCDirector::sharedDirector()->getWinSize();
m_pSliderCtl = sliderCtl();
m_pSliderCtl->retain();
m_pSliderCtl->setPosition(ccp(s.width / 2.0f, s.height - (m_pSliderCtl->getContentSize().height*2)));
this->addChild(m_pSliderCtl,1);
}
CCControlSlider* HelloWorld::sliderCtl()
{
CCControlSlider * slider = CCControlSlider::create("extensions/sliderTrack2.png","extensions/sliderProgress2.png" ,"extensions/sliderThumb.png");
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::sliderAction), CCControlEventValueChanged);
slider->setMinimumValue(-3.0f);
slider->setMaximumValue(3.0f);
slider->setValue(1.0f);
return slider;
}
void HelloWorld::sliderAction(CCObject* pSender, CCControlEvent controlEvent)
{
bSliderCtlTouched =true;
CCControlSlider* pSliderCtl = (CCControlSlider*)pSender;
float scale;
scale = pSliderCtl->getValue();
}
void HelloWorld::registerWithTouchDispatcher()
{
// higher priority than dragging
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this,0, true);
}
bool HelloWorld::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if(bSliderCtlTouched)
CCLOGWARN("bSliderCtlTouched is true");
CCPoint touchLocation = touch->getLocation();
CCPoint location = convertToNodeSpace( touchLocation );
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
float screenSizeW = screenSize.width;
//CCLOGWARN("pos: %f,%f -> %f,%f", touchLocation.x, touchLocation.y, location .x, location .y);
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
float halfScreen = screenSize.width/2;
if(location.x <= halfScreen)
{
left = true;
right = false;
}
else
{
left = false;
right = true;
}
#ifdef MOUSEJOINT
return isNodeTouched(locationWorld);
#else
return true;
#endif
}
void HelloWorld::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
if (!bSliderCtlTouched)
{
return;
}
CCPoint touchLocation = touch->getLocation();
CCPoint location = convertToNodeSpace( touchLocation );
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
}
void HelloWorld::ccTouchEnded(CCTouch* touch, CCEvent* event)
{
if(bSliderCtlTouched)
{
bSliderCtlTouched = false;
}
CCPoint touchLocation = touch->getLocation();
CCPoint nodePosition = convertToNodeSpace( touchLocation );
}
As far as your question was unanswered about 7 months, I will answer your question for the new version of cocos2d-x. This code works for cocos2d-x 3.0:
cocos2d::extension::ControlSlider* slider = cocos2d::extension::ControlSlider::create(
"images/buttons/container.png", "images/buttons/progress.png", "images/buttons/knob.png");
slider->setPosition(200, 200);
slider->setMinimumValue(0);
slider->setMaximumValue(10);
slider->setValue(3);
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(IntroView::valueChangedCallback), cocos2d::extension::Control::EventType::VALUE_CHANGED);
addChild(slider);
void IntroView::valueChangedCallback(Ref* sender, cocos2d::extension::Control::EventType evnt)
{
float value = static_cast<cocos2d::extension::ControlSlider*>(sender)->getValue();
CCLOG(std::to_string(value).c_str());
}
Don't forget to #include "GUI/CCControlExtension/CCControlExtensions.h" and use libExtensions in your project.

Cocos2d-x : Convert from CCTime to SEL_SCEDULE error

I'm a beginner that just followed cocos2d-x's native tutorials and I am faced with a huge wall!
This is my error:
>c:\cocos2d-2.0-x-2.0.3\cocos2dsimplegame\classes\helloworldscene.cpp(86): error C2440: 'type cast' : cannot convert from 'void (__thiscall HelloWorld::* )(cocos2d::CCTime)' to 'cocos2d::SEL_SCHEDULE'
>Pointers to members have different representations; cannot cast between them
My cpp file:
#include "HelloWorldScene.h"
using namespace cocos2d;
CCScene* HelloWorld::scene()
{
CCScene * scene = NULL;
do
{
// 'scene' is an autorelease object
scene = CCScene::create();
CC_BREAK_IF(! scene);
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
CC_BREAK_IF(! layer);
// add layer as a child to scene
scene->addChild(layer);
} while (0);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
bool bRet = false;
_targets = CCArray::create();
_projectiles = CCArray::create();
do {
////////////////////
// super init first
////////////////////
if ( !CCLayerColor::initWithColor( ccc4(255, 255, 255, 255) ) )
{
return false;
}
////////////////////
// add your codes below..
////////////////////
// 1. Add a menu item with "X" image, which is clicked to quit the program.
// Create a "close" menu item with close icon, it's an auto release object.
CCMenuItemImage *pCloseItem = CCMenuItemImage::itemWithNormalImage(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
CC_BREAK_IF(! pCloseItem);
// Place the menu item bottom-right conner.
pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
//Create a menu with the "close" menu item, it's an auto release object.
CCMenu* pMenu = CCMenu::menuWithItems(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
CC_BREAK_IF(! pMenu);
//Add the menu to HelloWorld layer as a child layer.
this->addChild(pMenu, 1);
//////////////////////
// 2. add your codes below...
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSprite *player = CCSprite::spriteWithFile("Player.png", CCRectMake(0, 0, 27, 40));
player->setPosition(ccp(player->getContentSize().width/2, winSize.height/2));
this->addChild(player);
bRet = true;
} while (0);
// Call game logic about every second
this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0);
// You can shoot the bullet
this->setTouchEnabled(true);
this->schedule( schedule_selector(HelloWorld::update) );
return bRet;
}
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
// "close" menu item clicked
CCDirector::sharedDirector()->end();
}
void HelloWorld::addTarget()
{
CCSprite *target = CCSprite::spriteWithFile("Target.png", CCRectMake(0, 0, 27, 40));
// Determine where to spawn the target along the Y axis
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
int minY = target->getContentSize().height/2;
int maxY = winSize.height - target->getContentSize().height/2;
int rangeY = maxY - minY;
// srand( TimGetTicks() );
int actualY = ( rand() % rangeY ) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated
target->setPosition( ccp(winSize.width + (target->getContentSize().width/2), actualY) );
this->addChild(target);
// Determine speed of the target
int minDuration = (int)2.0;
int maxDuration = (int)4.0;
int rangeDuration = maxDuration - minDuration;
// srand( TimGetTicks() );
int actualDuration = ( rand() % rangeDuration ) + minDuration;
// Create the actions
CCFiniteTimeAction* actionMove = CCMoveTo::actionWithDuration( (float)actualDuration, ccp(0 - target->getContentSize().width/2, actualY) );
CCFiniteTimeAction* actionMoveDone = CCCallFuncN::actionWithTarget( this, callfuncN_selector(HelloWorld::spriteMoveFinished) );
target->runAction( CCSequence::actions( actionMove, actionMoveDone, NULL) );
// Add to targets array
target->setTag(1);
_targets->addObject(target);
}
void HelloWorld::spriteMoveFinished(CCNode* sender)
{
CCSprite *sprite = (CCSprite *)sender;
this->removeChild(sprite, true);
if (sprite->getTag() == 1) // target
{
_targets->removeObject(sprite);
}
else if (sprite->getTag() == 2) // projectile
{
_projectiles->removeObject(sprite);
}
}
void HelloWorld::gameLogic(float dt)
{
this->addTarget();
}
void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
// Choose one of the touches to work with
CCTouch* touch = (CCTouch*)( touches->anyObject() );
CCPoint location = touch->locationInView();
location = CCDirector::sharedDirector()->convertToGL(location);
// Set up initial location of projectile
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCSprite *projectile = CCSprite::spriteWithFile("Projectile.png", CCRectMake(0, 0, 20, 20));
projectile->setPosition( ccp(20, winSize.height/2) );
// Determine offset of location to projectile
int offX = location.x - projectile->getPosition().x;
int offY = location.y - projectile->getPosition().y;
// Bail out if we are shooting down or backwards
if (offX <= 0) return;
// OK to add now - we've double checked position
this->addChild(projectile);
// Determine where we wish to shoot the projectile to
int realX = winSize.width + (projectile->getContentSize().width/2);
float ratio = (float)offY / (float)offX;
int realY = (realX * ratio) + projectile->getPosition().y;
CCPoint realDest = ccp(realX, realY);
// Determine the length of how far we're shooting
int offRealX = realX - projectile->getPosition().x;
int offRealY = realY - projectile->getPosition().y;
float length = sqrtf((offRealX * offRealX) + (offRealY * offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length/velocity;
// Move projectile to actual endpoint
projectile->runAction( CCSequence::actions( CCMoveTo::actionWithDuration(realMoveDuration, realDest), CCCallFuncN::actionWithTarget(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL) );
// Add to projectiles array
projectile->setTag(2);
_projectiles->addObject(projectile);
}
void HelloWorld::update(CCTime dt)
{
CCArray *projectilesToDelete = CCArray::create();
CCObject* arrayItem1;
CCARRAY_FOREACH(_projectiles, arrayItem1)
{
CCSprite* projectile = (CCSprite*)arrayItem1;
CCRect projectileRect = CCRectMake(
projectile->getPosition().x - (projectile->getContentSize().width/2),
projectile->getPosition().y - (projectile->getContentSize().height/2),
projectile->getContentSize().width,
projectile->getContentSize().height);
CCArray* targetsToDelete = CCArray::create();
CCObject* arrayItem2;
CCARRAY_FOREACH(_targets, arrayItem2)
{
CCSprite* target = (CCSprite*) arrayItem2;
CCRect targetRect = CCRectMake(
target->getPosition().x - (target->getContentSize().width/2),
target->getPosition().y - (target->getContentSize().height/2),
target->getContentSize().width,
target->getContentSize().height);
if (CCRect::CCRectIntersectsRect(projectileRect, targetRect))
{
targetsToDelete->addObject(target);
}
}
CCARRAY_FOREACH(targetsToDelete, arrayItem2)
{
CCSprite* target = (CCSprite*) arrayItem2;
_targets->removeObject(target);
this->removeChild(target, true);
}
if (targetsToDelete->count() > 0)
{
projectilesToDelete->addObject(projectile);
}
targetsToDelete->release();
}
CCARRAY_FOREACH(projectilesToDelete, arrayItem1)
{
CCSprite* projectile = (CCSprite*) arrayItem1;
_projectiles->removeObject(projectile);
this->removeChild(projectile, true);
}
projectilesToDelete->release();
}
Maybe this part is a problem:
bool HelloWorld::init()
{
....
this->schedule( schedule_selector(HelloWorld::update) );
....
}
But I don't understand why this part is a problem.
Please, help me!
change CCTime to float.
in old cocos2d-x version, they have ccTime instead of CCTime
but in 2.0 they remove it. since it is duplicated with float.

Animating sprite while jumping

How to animate a sprite while jumping?
i.e, moving the eyes or animating the sprite using CCAnimate
CCSpriteFrameCache.sharedSpriteFrameCache().addSpriteFrames("AnimBear.plist");
this._bear = CCSprite.sprite("bear1.png", true);
spritesheet1 = CCSpriteSheet.spriteSheet("AnimBear.png");
spritesheet1.addChild(_bear, 1);
addChild(spritesheet1, 1);
ArrayList<CCSpriteFrame> animFrames = new ArrayList<CCSpriteFrame>();
CCSpriteFrameCache.sharedSpriteFrameCache();
for (int i = 1; i <= 8; i++) {
CCSpriteFrame frame = CCSpriteFrameCache
.spriteFrameByName(
"bear" + i + ".png");
animFrames.add(frame);
}
CCAnimation anim = CCAnimation.animation("AnimBear", .175f,
animFrames);
_bear.setPosition(CGPoint.make(_bear.getContentSize().width, 50));
CCIntervalAction action=CCAnimate.action(0.1f, anim, false);
this.walkAction = CCRepeatForever.action(action);
_bear.runAction(walkAction);
and moving on touch
public boolean ccTouchesEnded(MotionEvent event) {
CGPoint touchLocation = CCDirector.sharedDirector().convertToGL(
CGPoint.make(event.getX(), event.getY()));
float bearVelocity = 480.0f/3.0f;
CGPoint moveDifference = CGPoint.ccpSub(touchLocation, _bear.getPosition());
float distanceToMove = CGPoint.ccpLength(moveDifference);
float moveDuration = distanceToMove / bearVelocity;
if (moveDifference.x < 0) {
_bear.flipX_= false;
} else {
_bear.flipX_ = true;
}
_bear.stopAction(moveAction);
if (!_moving) {
_bear.runAction(walkAction);
}
CCMoveTo actionMove=CCMoveTo.action(moveDuration, touchLocation);
CCCallFuncN actionMoveDone1 = CCCallFuncN.action(this, "bearMoveEnded");
CCSequence actions = CCSequence.actions(actionMove, actionMoveDone1);
_bear.stopAllActions();
this.moveAction = actions;
_bear.runAction(moveAction);
_moving = true;
return CCTouchDispatcher.kEventHandled;
}
In this animation complete first and after this if you touch on the screen then the activity you want it'll happen.....
If you want the animation n move the sprite simultaneously, complete your all code in the
public boolean ccTouchesEnded(MotionEvent event) {
}