As we always use the function in cocos2d,I can scale my sprite whenever I want.Can I do the same thing in box2d?For example, I created a circle shaped body,then I want to make it bigger.
I tried reassign the m_radius after I created a circle,but not work.
If you are simply assigning shape.m_radius to a new value, it will not work.
You need to reference the shape object associated with the b2Fixture that you created for your object:
fixture->GetShape()->m_radius = new_radius/PTM_RATIO;
Hope this helps.
Related
I exchange sprite content with this code:
mySprite->setTexture(Director::getInstance()->getTextureCache()->addImage("newImage.png"));
The problem is that newImage.png is much smaller than the old content image of the sprite. But cocos2d-x scales newImage.png to have the same size as oldImage.png. How I can prevent this scaling. I need newImage.png to be its natural size, but to appear in the coordinates of oldImage.png (I want to retain the same sprite object, as far as I have a pointer on it and also the same position and same anchor point. That's why I use setTexture just to change the image.)
Well, this may not be the cleanest way, but it seems the most straigthforward to me :
Sprite *newSprite = Sprite::create("newImage.png");
newSprite->setAnchorPoint(mySprite->getAnchorPoint());
newSprite->setPosition(mySprite->getPosition());
mySprite->removeFormParentAndCleanup(true);
mySprite = newSprite; // <-- magic happens here
So basically you create a new sprite, place it based in old sprites position/anchor and then after removing the old one, you assigne the mySprite variable to point to the same place as newSprite.
mySprite->setTexture("newImage.png");
This sets the content Rect too.
I'm making an endless running game in which users dodge obstacles, and I'm working on producing the obstacles right now. The plan I had where I'm spawning these obstacles is as follows:
obstacle->setPosition(CCPointMake(this->getContentSize().width, this->getContentSize().height*.75));
obstacle->setScale(.5);
this->addChild(obstacle);
_obstacles->addObject(obstacle);
obstacle->runAction(CCMoveBy::create(2.0, CCPointMake(-(this->getContentSize().width + obstacle->getContentSize().width/2), 0)));
obstacle->removeFromParent();
I set the position, set it's scale, add it to the scene, run an action on it so that it moves across the screen from right to left, add it to an array called _obstacles to be used elsewhere, and then I remove it from the scene so as to save memory. However, the problem is that once I try implement this, the obstacle doesn't show up at all as if it's nowhere to be seen. When I don't call obstacle->removeFromParent() it shows up and performs the action. What am I doing wrong here? If I don't call removeFromParent(), what do I call? Is there a problem in my code not related to removeFromParent()?
The reason that obstacle doesn't apeear at all is that it is removed as it start moving. You just have to create a sequence of move action and function call with obstacle as parameter and than remove this obstacle in that function , so that obstacle will be removed after moving out of screen.
CCCallFuncN *myCallFunc = CCCallFuncN::create(this, callfuncN_selector(CLASS_NAME::removeObstacles));
obstacle->runAction(CCSequence::create(CCMoveBy::create(2.0, CCPointMake(-(this->getContentSize().width + obstacle->getContentSize().width/2), 0)),myCallFunc,NULL));
Method to remove obstacle from array and from parent view
void CLASS_NAME::removeObstacles(CCObject* pSender){
// Type cast pSender to obstacle type e.g if obstacle is of CCSprite type.
CCSprite *tempObstacle = (CCSprite *)pSender;
_obstacle.pop_back(tempObstacle);
tempObstacle->removeFromParent();
}
Don't forget to replace CLASS_NAME by your class name
I would need more info on what removeFromParent is doing and how you use _obstacles
I'm taking a guess on how the parent is structured. I would guess that it has a list of children and when the parent is updated/render, it calls those functions for its children. If removeFromParent removes the object from its parent list, then that would explain why it is not being render or used in the scene. If you have a setup like this, then you should only call removeFromParent before destroying the parent object
I know that there are ways to create a shadow on Raphael object:
By creating glow() and changing its offsetx and offsety
Also there is a library to do that
My issue is that I need to drag the shadow with the object. So far I can get object moving, but shadow will not move. Any hints?
To answer to your question "Any hints?"
Well do the following:
Create a clone and make it glow
Hide your new object so that only glow will apeare
Adjust the coords of glow
Then create a Raphael SET and add those two objects to it
Now you can apply drag on your SET
Good luck
Is there any possibility to show only a part of an CCSprite?
It seams that contentSize property doesn't have a good result.
I think you might have to create a new sprite for this. The general pseudo code is this.
CCTexture2D *origTexture = originalSprite->getTexture();
CGRect rect = {0, 0, 20, 20};
CCSprite *destSprite = CCSprite::spriteWithTexture(origTexture, CGRect);
Both doc_180's and James' answers work by creating new CCSprite using a portion of the texture, but if you are using clipping method, you will get CCSprite that uses the full texture but have the ability to only draw a portion of it on screen. One advantage of this method is you are able to modify how big or small the portion that you want shown or hidden on the fly rather than having to re-create the CCSprite again and again (or replacing the texture again and again).
So, to use the clipping method, simply download the ClippingNode class from here, and add the CCSprite you want clipped to that ClippingNode. Then you call one of its methods to specify which region to limit the drawing to. I'm currently using it to create a progress bar so I know for sure it works great.
Get the [sprite displayedFrame], change the frame of that, and create a new sprite with that spriteframe: CCSprite *sprite2 = [CCSprite spriteWithSpriteFrame:frame]
In the isometric tiled map z-ordering example for cocos2d-iphone, they use an object that is already in the tilemap as the player sprite, which is rendered as moving through the trees.
Is there a way to use a random CCNode, created though code (not in the tmx file, and not part of the sprite sheet), and have it z-ordered correctly with the tilemap? addChild is not supported on a CCTMXLayer, and the gives an error when using that reads:'addChild: is not supported on CCTMXLayer. Instead use setTileGID:at:/tileAt:'.
There's got to be a way to have a CCNode (let's say a simple CCSprite) z-order correctly with a tilemap, either using cocos2d's API, or some z-buffer technique. Any pointers?
The CCTMXLayer doesn't support adding tiles at runtime because it's implemented with all sprites on a single spritesheet. Because of this implementation detail you also can't call setTexture on an individual tile.
The easiest solution would be to have the sprite you want to use on the spritesheet at the beginning. If you can't do this because it's generated at runtime or something, the next best thing (without touching cocos2d code) would be to modify the spritesheet.
Put a dummy tile in the spritesheet you're using for the TMXLayer and then, once you have the image you want to use, write it to the spritesheet using CCRenderTexture or something and use the newly generated Texture as your TMXLayer's texture.
You could also modify the CCTMXLayer to allow for your functionality but it sounds like you want to avoid that.
If you want to add a tile to say tile (x,y) ( (x,y) in Tiled Map editor coordinates ) then use the following code -
myTileMap is the reference to the CCTMXTiledMap object.
CCTMXLayer *layer=[myTileMap layerNamed:#"yourlayer"];
NSAssert(floorLayer !=nil, #"Ground layer not found!");
CGPoint tileAddPosition = [layer positionAt: CGPointMake(x,y)];
//Create your CCNode or CCSprite or whatever...say object name is **tileToBeAdded**
tileToBeAdded.anchorPoint = CGPointZero;
tileToBeAdded.position = tileAddPosition;
[myTileMap addChild:addedTile z:1];