I am trying to edit an object inside a method like this:
-(void) createSprite:(CatSprite*) sprite{
UIImage *image = [UIImage imageNamed:BASE_SPRITE_IMAGE];
CGImageRef imageRef = image.CGImage;
sprite =[CatSprite spriteWithCGImage:imageRef key:nil];
}
and the call of the method like this:
[self createSprite:mySprite];
When debugging the method the object sprite is allocated, but after executing the method the object mySprite is null. Thank you.
PS: mySprite is an instance variable of type CatSprite (Extention from CCSprite).
First, I'm assuming you're using ARC. Second, you have two ways of doing this, though I'd recommend the first option...
Option 1
Return a new sprite, instead of trying to modify the caller's pointer:
- (CatSprite *)createSprite{
UIImage *image = [UIImage imageNamed:BASE_SPRITE_IMAGE];
CGImageRef imageRef = image.CGImage;
return [CatSprite spriteWithCGImage:imageRef key:nil];
}
You'd call this method using:
mySprite = [self createSprite];
Option 2
Pass a pointer to a pointer, and dereference:
- (void)createSpriteUsingSpritePointer:(CatSprite **)spritePointer{
UIImage *image = [UIImage imageNamed:BASE_SPRITE_IMAGE];
CGImageRef imageRef = image.CGImage;
*spritePointer = [CatSprite spriteWithCGImage:imageRef key:nil];
}
You'd call this method using:
[self createSprite:&mySprite];
Related
Can you please convert this cocos2d code to cocos2dx?
shiprightnode = [[Shipright alloc] initWithBody:shipright game:game_];
[game_ addBodyNode:shiprightnode z:1];
[shiprightnode release];
shiprightnode = new Shipright();
shiprightnode->init(p_game_);
game_->addBodyNode(shiprightnode);
shiprightnode->release();
auto shiprightnode = Shipright::createWithGame(game_);
game_->addBodyNode(shiprightnode,1);
//no need to release shiprightnode because it create autorelease object.
I am having a problem with CCRenderTexture:
The item on the left is the "copy" .. on the right is the original. I use the code below to try to create and EXACT copy of the sprite/png on the right.
But when I create a sprite from the CCRenderTexture below ... I am losing the drop shadows and the the image looks a bit smudged ... should be an exact copy.
Any ideas?
Am I using CCRenderTexture incorrectly?
Why the difference?
//Sprite on the right
CCSprite* hack = [CCSprite spriteWithFile:#"ColumnMatchCheck.png"];
hack.anchorPoint = ccp(0,0);
CCRenderTexture* render = [CCRenderTexture renderTextureWithWidth:hack.contentSize.width
height:hack.contentSize.height
pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[render beginWithClear:1 g:1 b:1 a:0];
[render.sprite setBlendFunc:(ccBlendFunc){GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}];
[hack visit];
[render end];
//Sprite on the left
CCSprite* test2 = [CCSprite spriteWithTexture:render.sprite.texture];
Most examples I see of assigning userData go something like this:
CCSprite *sprite = [CCSprite spriteWithFile:#"whatever.png" rect:CGRectMake(0, 0, screenSize.width, screenSize.height)];
sprite.tag = kWallTag;
[self addChild:sprite];
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
groundBodyDef.userData = (__bridge void*)sprite;
That's fine if you're using a sprite. But in my case, I don't want to create a sprite because I just want to test collisions with the screen edges. I could create a sprite the size of the screen with just a border but I don't want to use that much texture memory just for detecting walls. So my question is how to assign the kWallTag to the groundBodyDef, without assigning it a sprite. And how would I retrieve the tag value?
I've answered the first part:
GenericUserData *usrData = (GenericUserData*)malloc(sizeof(GenericUserData));
usrData->tag = kWallTag;
groundBodyDef.userData = usrData;
But I don't know how to test for the generic data:
if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
CCSprite *spriteA = (__bridge CCSprite *) bodyA->GetUserData();
CCSprite *spriteB = (__bridge CCSprite *) bodyB->GetUserData();
How do I test for generic user data instead of just assuming that it's a CCSprite?
has anyone an idea how to convert a UIImage to cocos2d-x CCSprite.
My latest attempt was was:
1. Store the UIImage as png on the phone
2. Load the png as a CCSprite
[UIImagePNGRepresentation(photo) writeToFile:imagePath atomically:true];
CCSprite *sprite = CCSprite::spriteWithFile(imagePath);
But this crashed in CCObject retain function
void CCObject::retain(void)
{
CCAssert(m_uReference > 0, "reference count should greater than 0");
++m_uReference;
}
And I do not understand how Walzer Wangs suggestion works
http://cocos2d-x.org/boards/6/topics/3922
CCImage::initWithImageData(void* pData, int nDataLen, ...)
CCTexture2D::initWithImage(CCImage* uiImage);
CCSprite::initWithTexture(CCTexture2D* pTexture);
CCSprite* getCCSpriteFromUIImage(UIImage *photo) {
CCImage *imf =new CCImage();
NSData *imgData = UIImagePNGRepresentation(photo);
NSUInteger len = [imgData length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [imgData bytes], len);
imf->initWithImageData(byteData,imgData.length);
imf->autorelease();
CCTexture2D* pTexture = new CCTexture2D();
pTexture->initWithImage(imf);
pTexture->autorelease();
CCSprite *sprit = new CCSprite();
sprit->createWithTexture(pTexture);
sprit->autorelease();
DebugLog("size :%f :%f ",sprit->getContentSize().width , sprit->getContentSize().height);
return sprit;
}
I got the solution for my own Problem. You can't create a CCSprite before the CCDirector is initialized. There are missing some config settings and cocos releases the image right after it is instantiated.
Save uiimage to documents directory first
now get it using getWritablePath
Texture2D* newTexture2D = new Texture2D();
Image* JpgImage = new Image();
JpgImage->initWithImageFile("your image path.jpg");
newTexture2D->initWithData(JpgImage->getData(),JpgImage->getDataLen(),Texture2D::PixelFormat::RGB888,JpgImage->getWidth(),JpgImage->getHeight(),Size(JpgImage->getWidth(),JpgImage->getHeight()));
How To Have The Same Sprite In Multiple Locations Cocos2d Please Help
I have searched all over and cannot find answer
Just create multiple Sprites (CCSprite instances). They can all use the same texture (bitmap-file).
CCSprite * mySprite1;
CCSprite * mySprite2;
CCSprite * mySprite3;
// create several sprites from the same bitmap file
mySprite1 = [CCSprite spriteWithFile:#"spriteBitmap.png"];
mySprite2 = [CCSprite spriteWithFile:#"spriteBitmap.png"];
mySprite3 = [CCSprite spriteWithFile:#"spriteBitmap.png"];
mySprite1.position = ccp(100, 100);
mySprite2.position = ccp(200, 200);
mySprite3.position = ccp(300, 300);
You can not add the same CCSprite as a child to multiple CCNodes but you can make Cocos2D render the same CCSprite multiple times.
To achieve this you need to create a subclass of CCNode that will store the reference to your CCSprite and draw it in its -draw method applying required transformations.
For example
-(void)draw
{
[super draw];
CGPoint initialPosition = [_node position];
float initialScale = [_node scale];
[_node setScale:self.scale];
[_node setPosition:self.position];
[_node visit];
[_node setPosition:initialPosition];
[_node setScale:initialScale];
}
You may have to to use glScissor if you need picture-in-picture appearance.
Then you just need to addChild an instance of this class for every time you want an additional copy of your original CCSprite rendered.
Put a method on a for loop.
Inside the method create the CCSprite and modify it.
This is best suited for static sprites, since I don't know how you would access these outside of the method.