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) {
}
Related
I want to show zoom animation after pan.
- (void) didLoadFromCCB
{
self.anchorPoint = ccp( 0.9, 0.9 );
self.scale = 1;
}
- (void) update:(ccTime)delta
{
float posX = self.position.x;
float posY = self.position.y;
float posNewX = posX - 100*delta;
if (posX > -1024) {
self.position = ccp(posNewX, posY);
}else if (posX < -1024) {
id action2=[CCScaleTo actionWithDuration:4.5 scale:1.20];
CCSequence *scaleSeq = [CCSequence actions:action2, nil];
[self runAction:scaleSeq];
}
}
Panning is working, but zoom animation doesnt work.
animaiton.scale--;
write it in your delta function it will decrease the the size of animation each time..if you want to increase use Scale++.
I'm trying to simulate a flick in cocos2d and I need to create a ball every time the users touch is ended, but I can't get the ball to move during the tick method, and I can't destroy the ball (which is a b2body) afterwards without unscheduling the method every time.
- (void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
touch = [touches anyObject];
location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
endPoint = location;
force = b2Vec2(endPoint.x - startPoint.x ,endPoint.y - startPoint.y);
if ((force.x != 0) || (force.y != 0)) {
if (ballCount == 0) {
ball.position = startPoint;
[self createBall]; - Here i create the ball every time
[self schedule: #selector(tick:)]; -I schedule the tick method right after the ball is created
[self scheduleOnce:#selector(kick) delay:0]; - This is the only place the ball will launch. For some reason I can't get the kick method to work any where else
}
}
- (void)kick
{
int speed = 30;
float32 setSpeed = speed/sqrt(powf(force.x,2) + powf(force.y, 2));
b2Vec2 ballSpeed = b2Vec2(force.x * setSpeed, force.y * setSpeed);
_ballBody->SetLinearVelocity(ballSpeed);
}
- (void)tick:(ccTime) dt {
_world->Step(dt, 10, 10);
ballData = (__bridge CCSprite *)_ballBody->GetUserData();
ballData.position = ccp(_ballBody->GetPosition().x * PTM_RATIO,
_ballBody->GetPosition().y * PTM_RATIO);
ballData.rotation = -1 * CC_RADIANS_TO_DEGREES(_ballBody->GetAngle());
std::set<b2Body *>toDestroy;
//takes collisions from contact listener
std::vector<MyContact>::iterator pos;
for(pos = _contactListener->_contacts.begin();
pos != _contactListener->_contacts.end(); ++pos) {
MyContact contact = *pos;
bodyA = contact.fixtureA->GetBody();
bodyB = contact.fixtureB->GetBody();
if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
spriteA = (__bridge CCSprite *) bodyA->GetUserData();
spriteB = (__bridge CCSprite *) bodyB->GetUserData();
contactPositionX = spriteA.position.x;
contactPositionY = spriteB.position.y;
if (spriteA.tag == kCurrentItem && spriteB.tag == 8)
{
NSLog(#"contact");
[self removeChild:spriteA cleanup:YES];
[self removeChild:spriteB cleanup:YES];
toDestroy.insert(bodyA);
toDestroy.insert(bodyB);
[self unschedule:#selector(tick:)]; (i unschedule the tick method every time which in turn messes up my other sprites.)
}
}
}
for(std::set<b2Body *>::iterator pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2)
{
b2Body *body = *pos2;
_world->DestroyBody(body);
}
toDestroy.clear();
}
I need to create an outline like this dynamically:
Not for a CCSprite, but for multiple animated CCSprites united in one CCNode. I'm thinking about:
copying CCNode's content to a texture (like canvasBitmapData.draw(sourceDisplayObject) in AS3)
creating CCSprite with the resulting texture
tinting the sprite to outline color and scaling it up a bit
placing the sprite behind other sprites in the node
I have no idea how to perform step 1. And maybe it is faster to draw "true stroke" around the texture's opaque pixels instead of tint-scale in step 3?
I totally forgot to post an answer for this question. Here's the code for a very smooth stroke. It's not fast but worked great for a couple of big sprites on the first iPad.
The idea is to draw tiny colored and blurred balls around the sprite and place them onto their own texture. It can be used both for CCNode and CCSprite. The code also shifts anchor points because the resulting sprites will have a bit larger width and height.
Resulting outline (body and 2 hands, about 0.3s on iPad1):
White balls examples:
5f: http://i.stack.imgur.com/e9kos.png
10f: http://i.stack.imgur.com/S5goU.png
20f: http://i.stack.imgur.com/qk7GL.png
CCNode category, for Cocos2d-iPhone 2.1:
#implementation CCNode (Outline)
- (CCSprite*) outline
{
return [self outlineRect:CGRectMake(0, 0, self.contentSize.width, self.contentSize.height)];
}
- (CCSprite*) outlineRect:(CGRect)rect
{
NSInteger gap = dscale(4);
CGPoint positionShift = ccp(gap - rect.origin.x, gap - rect.origin.y);
CGSize canvasSize = CGSizeMake(rect.size.width + gap * 2, rect.size.height + gap * 2);
CCRenderTexture* renderedSpriteTexture = [self renderTextureFrom:self shiftedFor:positionShift onCanvasSized:canvasSize];
CGSize textureSize = renderedSpriteTexture.sprite.contentSize;
CGSize textureSizeInPixels = renderedSpriteTexture.sprite.texture.contentSizeInPixels;
NSInteger bitsPerComponent = 8;
NSInteger bytesPerPixel = (bitsPerComponent * 4) / 8;
NSInteger bytesPerRow = bytesPerPixel * textureSizeInPixels.width;
NSInteger myDataLength = bytesPerRow * textureSizeInPixels.height;
NSMutableData* buffer = [[NSMutableData alloc] initWithCapacity:myDataLength];
Byte* bytes = (Byte*)[buffer mutableBytes];
[renderedSpriteTexture begin];
glReadPixels(0, 0, textureSizeInPixels.width, textureSizeInPixels.height, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
[renderedSpriteTexture end];
//SEE ATTACHMENT TO GET THE FILES
NSString* spriteFrameName;
if (IS_IPAD) spriteFrameName = (CC_CONTENT_SCALE_FACTOR() == 1) ? #"10f.png" : #"20f.png";
else spriteFrameName = (CC_CONTENT_SCALE_FACTOR() == 1) ? #"5f.png" : #"10f.png";
CCSprite* circle = [CCSprite spriteWithSpriteFrameName:spriteFrameName];
circle.anchorPoint = ccp(0.48, 0.48);
float retinaScale = (CC_CONTENT_SCALE_FACTOR() == 1) ? 1.0 : 0.5;
CCRenderTexture* strokeTexture = [CCRenderTexture renderTextureWithWidth:textureSize.width height:textureSize.height pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[strokeTexture beginWithClear:0 g:0 b:0 a:0];
for (NSInteger x = 0; x < textureSizeInPixels.width; x++)
{
for (NSInteger y = 0; y < textureSizeInPixels.height; y++)
{
NSInteger idx = y * bytesPerRow + x * bytesPerPixel + 3;
NSInteger w = 1;
if (bytes[idx] <= 254)
{
BOOL shouldBeStroked = NO;
for (NSInteger nx = -w; nx <= w; nx++)
{
for (NSInteger ny = -w; ny <= w; ny++)
{
if (x + nx < 0 || y + ny < 0 || x + nx >= textureSizeInPixels.width || y + ny >= textureSizeInPixels.height)
continue;
if (bytes[idx + nx * bytesPerPixel + ny * bytesPerRow] == 255)
{
shouldBeStroked = YES;
break;
}
}
}
if (shouldBeStroked == YES)
{
circle.position = ccp(x * retinaScale, y * retinaScale);
[circle visit];
}
}
}
}
[strokeTexture end];
CCSprite* resultSprite = [CCSprite spriteWithTexture:strokeTexture.sprite.texture];
[resultSprite.texture setAntiAliasTexParameters];
resultSprite.flipY = YES;
if ([self isKindOfClass:[CCSprite class]]) {
CGPoint oldAnchorInPixels = ccp(roundf(self.contentSize.width * self.anchorPoint.x), roundf(self.contentSize.height * self.anchorPoint.y));
resultSprite.anchorPoint = ccp((oldAnchorInPixels.x + gap) / resultSprite.contentSize.width, (oldAnchorInPixels.y + gap) / resultSprite.contentSize.height);
resultSprite.position = self.position;
} else { //CCNode
resultSprite.anchorPoint = CGPointZero;
resultSprite.position = ccpAdd(self.position, ccp(rect.origin.x - gap, rect.origin.y - gap));
}
return resultSprite;
}
- (CCRenderTexture*) renderTextureFrom:(CCNode*)node shiftedFor:(CGPoint)posShift onCanvasSized:(CGSize)size
{
SoftAssertion(!CGSizeEqualToSize(size, CGSizeZero), #"node has zero size");
BOOL isSprite = [node isMemberOfClass:[CCSprite class]];
CGPoint apSave = node.anchorPoint;
CGPoint posSave = node.position;
BOOL wasVisible = node.visible;
CCRenderTexture* rtx = [CCRenderTexture renderTextureWithWidth:size.width
height:size.height
pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[rtx beginWithClear:0 g:0 b:0 a:0];
node.anchorPoint = CGPointZero;
node.position = posShift;
node.visible = YES;
if (isSprite) [node visit];
else [[self cloneCCNode:node] visit];
node.anchorPoint = apSave;
node.position = posSave;
node.visible = wasVisible;
[rtx end];
return rtx;
}
- (CCNode*) cloneCCNode:(CCNode*)source
{
CCNode* clone = [CCNode node];
void (^copyCCNodeProperties)(CCNode*, CCNode*) = ^(CCNode* source, CCNode* clone)
{
clone.visible = source.visible;
clone.rotation = source.rotation;
clone.position = source.position;
clone.anchorPoint = source.anchorPoint;
clone.zOrder = source.zOrder;
clone.tag = source.tag;
};
for (CCNode* srcSubnode in source.children) {
CCNode* subNode;
if ([srcSubnode isMemberOfClass:[CCSprite class]]) {
CCSprite* srcSprite = (CCSprite*)srcSubnode;
subNode = [CCSprite spriteWithTexture:srcSprite.texture];
CCSprite* subSprite = (CCSprite*)subNode;
subSprite.flipX = srcSprite.flipX;
subSprite.flipY = srcSprite.flipY;
subSprite.displayFrame = srcSprite.displayFrame;
subSprite.opacity = srcSprite.opacity;
}
else if ([srcSubnode isMemberOfClass:[CCLabelTTF class]]) {
CCLabelTTF* srcLabel = (CCLabelTTF*)srcSubnode;
subNode = [CCLabelTTF labelWithString:srcLabel.string fontName:srcLabel.fontName fontSize:srcLabel.fontSize dimensions:srcLabel.dimensions hAlignment:srcLabel.horizontalAlignment vAlignment:srcLabel.verticalAlignment];
CCSprite* subLabel = (CCSprite*)subNode;
subLabel.flipX = srcLabel.flipX;
subLabel.flipY = srcLabel.flipY;
subLabel.color = srcLabel.color;
}
else {
subNode = [self cloneCCNode:srcSubnode];
}
copyCCNodeProperties(srcSubnode, subNode);
[clone addChild:subNode];
}
copyCCNodeProperties(source, clone);
return clone;
}
I have a general purpose function I built up from various sources (that I'm ashamed to say I can't reference here). What it does is take a CCSprite, create a stroke that you can put behind it and return in a CCRenderTexture. If the sprite passed in has children (as yours might) I see no reason why it wouldn't do what you want, but I haven't tried.
Here it is in case it works:
#implementation Cocosutil
+(CCRenderTexture*) createStrokeForSprite:(CCSprite*)sprite size:(float)size color:(ccColor3B)cor
{
CCRenderTexture* rt = [CCRenderTexture renderTextureWithWidth:sprite.texture.contentSize.width+size*2 height:sprite.texture.contentSize.height+size*2];
CGPoint originalPos = [sprite position];
ccColor3B originalColor = [sprite color];
BOOL originalVisibility = [sprite visible];
[sprite setColor:cor];
[sprite setVisible:YES];
ccBlendFunc originalBlend = [sprite blendFunc];
[sprite setBlendFunc:(ccBlendFunc) { GL_SRC_ALPHA, GL_ONE }];
CGPoint bottomLeft = ccp(sprite.texture.contentSize.width * sprite.anchorPoint.x + size, sprite.texture.contentSize.height * sprite.anchorPoint.y + size);
CGPoint positionOffset = ccp(sprite.texture.contentSize.width * sprite.anchorPoint.x - sprite.texture.contentSize.width/2,sprite.texture.contentSize.height * sprite.anchorPoint.y - sprite.texture.contentSize.height/2);
CGPoint position = ccpSub(originalPos, positionOffset);
[rt begin];
for (int i=0; i<360; i+=30)
{
[sprite setPosition:ccp(bottomLeft.x + sin(CC_DEGREES_TO_RADIANS(i))*size, bottomLeft.y + cos(CC_DEGREES_TO_RADIANS(i))*size)];
[sprite visit];
}
[rt end];
[sprite setPosition:originalPos];
[sprite setColor:originalColor];
[sprite setBlendFunc:originalBlend];
[sprite setVisible:originalVisibility];
[rt setPosition:position];
return rt;
}
#end
and here is code where I use it:
- (id) initWithSprite:(CCSprite*)sprite color:(ccColor3B)color strokeSize:(float)strokeSize strokeColor:(ccColor3B)strokeColor {
self = [super init];
if (self != nil) {
strokeColor_ = strokeColor;
strokeSize_ = strokeSize;
CCRenderTexture *stroke = [CocosUtil createStrokeForSprite:sprite size:strokeSize color:strokeColor];
[self addChild:stroke z:kZStroke tag:kStroke];
[self addChild:sprite z:kZLabel tag:kLabel];
[self setContentSize:[sprite contentSize]];
}
return self;
}
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.
I have multiple sprites placed onto a background sprite like this:
//my background
CCSprite *bg = [CCSprite spriteWithFile:#"imageName.png"];
[self addchild:bg];
And then I add my items onto bg
//this is how i add my items
CCSprite *items = [CCSprite spriteWithFile:#"itemName.png"];
[bg addchild:items];
Oh and not forgetting my car sprite
//my car
CCSprite *car = [CCSprite spriteWithFile:#"car.png"];
[self addchild:car];
I use a loop to add multiple sprites onto the bg.
Now the question is how do I detect whether the car collided with the multiple sprites that I have placed onto the bg?
I've tried using CGRectIntersectsRect and it doesn't work.
I've tried using the pythagoras theorem method and once again it doesn't work.
There was a method which involved adding the items sprites into a NSMutableArray and it doesn't work either.
Can anyone suggest a method whereby I can try?
Additional code:
-(void) initializeCarAndItems
{
car = [CCSprite spriteWithFile:#"android.png"];
car.position = ccp(screenSize.width/2, screenSize.height * 0.30);
[self addChild:car z:1];
carRect = [car boundingBox];
}
-(void) initializeMap
{
bg1 = [CCSprite spriteWithFile:#"racingBG.png"];
bg1.anchorPoint = ccp(0, 0);
bg1.position = ccp(0, 0);
[self addChild:bg1 z:-1];
bg2 = [CCSprite spriteWithFile:#"racingBG2.png"];
bg2.anchorPoint = ccp(0,0);
bg2.position = ccp(0, bg1.boundingBox.size.height - 1);
[self addChild:bg2 z:-1];
convertedWidth = (int)bg1.boundingBox.size.width;
convertedHeight = (int)bg1.boundingBox.size.height;
for (y = 0; y < 15; y++)
{
positionX = arc4random()%convertedWidth;
positionY = arc4random()%convertedHeight;
items = [CCSprite spriteWithFile:#"item.png"];
items.position = ccp(positionX, positionY + 300);
[bg1 addChild:items z:100];
[itemsArray addObject:items];
}
for (y = 0; y < 15; y++)
{
positionX = arc4random()%convertedWidth;
positionY = arc4random()%convertedHeight;
items = [CCSprite spriteWithFile:#"item.png"];
items.position = ccp(positionX, positionY);
[bg2 addChild:items z:100];
[itemsArray addObject:items];
}
}
-(void) accelerate
{
bg1.position = ccp(0, bg1.position.y - accelerateNumber);
bg2.position = ccp(0, bg2.position.y - accelerateNumber);
if (bg1.position.y < -bg1.boundingBox.size.height)
{
questionCount++;
bg1.position = ccp(0, bg2.position.y + bg2.boundingBox.size.height - 1);
[self question];
[bg1 removeAllChildrenWithCleanup:YES];
for (y = 0; y < 15; y++)
{
positionY = arc4random()%convertedHeight;
positionX = arc4random()%convertedWidth;
items.position = ccp(positionX, positionY);
items = [CCSprite spriteWithFile:#"item.png"];
[bg1 addChild:items z:100];
[itemsArray addObject:items];
}
}
else if (bg2.position.y < -bg2.boundingBox.size.height)
{
questionCount++;
bg2.position = ccp(0, bg1.position.y + bg1.boundingBox.size.height - 1);
[self question];
[bg2 removeAllChildrenWithCleanup:YES];
for (y = 0; y < 15; y++)
{
positionY = arc4random()%convertedHeight;
positionX = arc4random()%convertedWidth;
items.position = ccp(positionX, positionY);
items = [CCSprite spriteWithFile:#"item.png"];
[bg2 addChild:items z:100];
[itemsArray addObject:items];
}
}
}
-(void) update:(ccTime)deltaTime
{
[self ifEdgeOfScreen];
[self accelerate];
for (CCSprite *itemFromArray in itemsArray)
{
CGRect itemRect = [itemFromArray boundingBox];
if (CGRectIntersectsRect(carRect, itemRect))
{
NSLog(#"Collision!");
}
}
if (leftButton.active == TRUE)
{
[self moveLeftRight:1];
}
else if (rightButton.active == TRUE)
{
[self moveLeftRight:2];
}
}
UPDATE:
It's fixed :)
-(void) update:(ccTime)deltaTime
{
car = [car boundingbox];
[self ifEdgeOfScreen];
[self accelerate];
for (CCSprite *itemFromArray in itemsArray)
{
if (CGRectIntersectsRect(carRect, [itemFromArray boundingbox]))
{
NSLog(#"Collision!");
}
}
if (leftButton.active == TRUE)
{
[self moveLeftRight:1];
}
else if (rightButton.active == TRUE)
{
[self moveLeftRight:2];
}
}
I found so many problems with the code....
When you call removeAllChildren.. Make sure you also remove objects from array.. Removing sprite from parents does not remove it from array.
update the car rect in update Method. So in your update method
-(void) update:(ccTime)deltaTime
{
[self ifEdgeOfScreen];
[self accelerate];
carRect = [car boundingBox];
...........
}
Hope this helps.. :)