SceneKit – Playing DAE and USDZ animation using Objective-C - objective-c

I want to create walking man animation in SceneKit.
I'm exporting animated .dae files from 3DSMax + OpenCollada , I also use ConvertToXcodeCollada to combine all animations in one.
How i get animation:
SCNScene *humanScene = [SCNScene sceneNamed:#"art.scnassets/myScene.DAE"];
CAAnimation *Animation = [[humanScene rootNode] animationForKey:#"myScene-1"];
I also try to get animation from "SCNSceneSource"
How i add animation:
SCNNode *humanNode = [humanScene.rootNode childNodeWithName:#"myScene-1" recursively:YES];
[humanNode addAnimation:walkingAnimation forKey:#"myScene-1"];
or:
SCNNode* humanNode = [SCNNode new];
for(SCNNode* node in humanScene.rootNode.childNodes){
[humanNode addChildNode:node];
}
[humanNode addAnimation:walkingAnimation forKey:#"myScene-1"];
My object "walkingAnimation" is "CAAnimationGroup".
But it doesn't animate in application.
I can see animation only in Xcode sceneKit editor.
example of my .DAE file

Try the following code with your model. It works. I used Xcode 13.2.1 in macOS 12.1.
At first fill viewDidLoad method:
#import "GameViewController.h"
#implementation GameViewController
SCNView *sceneView;
bool notRunningSwitch;
NSMutableDictionary<NSString*, CAAnimation*> *animations;
SCNNode *node;
- (void)viewDidLoad
{
[super viewDidLoad];
sceneView = (SCNView *)self.view;
notRunningSwitch = YES;
animations = #{}.mutableCopy;
node = [SCNNode node];
SCNScene *scene = [SCNScene scene];
sceneView.scene = scene;
sceneView.autoenablesDefaultLighting = YES;
sceneView.allowsCameraControl = YES;
[self anime];
}
Then anime and loadAnime methods:
- (void)anime
{
SCNScene *standStillScene = [SCNScene sceneNamed:#"art.scnassets/Idle"];
for (SCNNode *childNode in standStillScene.rootNode.childNodes)
{
[node addChildNode:childNode];
}
node.scale = SCNVector3Make(0.1, 0.1, 0.1);
node.position = SCNVector3Make(0, 0,-2.5);
[sceneView.scene.rootNode addChildNode: node];
[self loadAnime:#"running" inScene:#"art.scnassets/Running" withID:#"Running-1"];
}
- (void)loadAnime:(NSString*)withKey inScene:(NSString*)scene withID:(NSString*)id
{
NSURL *url = [NSBundle.mainBundle URLForResource:scene withExtension:#"usdz"];
SCNSceneSource *source = [SCNSceneSource sceneSourceWithURL:url options:Nil];
CAAnimation *charAnimation = [source entryWithIdentifier:id
withClass:CAAnimation.self];
charAnimation.repeatCount = 1;
charAnimation.fadeInDuration = 1;
charAnimation.fadeOutDuration = 1;
[animations setValue:charAnimation forKey:withKey];
}
And at last touchesBegan:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CGPoint point = [touches.allObjects.firstObject locationInView: sceneView];
NSDictionary<SCNHitTestOption, id> *options = #{ SCNHitTestBoundingBoxOnlyKey: #(YES) };
NSArray<SCNHitTestResult *> *hitTestResults = [sceneView hitTest: point options: options];
if (notRunningSwitch == YES) {
[sceneView.scene.rootNode addAnimation:animations[#"running"] forKey:#"running"];
} else {
[sceneView.scene.rootNode removeAnimationForKey:#"running" blendOutDuration:1.0];
}
notRunningSwitch = !notRunningSwitch;
NSLog(#"%#", hitTestResults.firstObject.node.name);
NSLog(#"%f", hitTestResults.firstObject.modelTransform.m43);
}
#end

Related

Variables not updating while using CADisplayLink

I cannot get the variables to change when I update them. The method "reCenterYaw" fires when I touch the button and the variable "self.hasYawCenterPointBeenSet" gets updated within the method but when "updateCycle" method comes back around the variable is not showing it was updated. updateCycle is my CADisplaylink driven method. I've tried updating the variables to atomic, referenced them as their instance variables with "_" and with "self." Not sure what is going on.
#import "GameViewController.h"
#import <CoreMotion/CoreMotion.h>
#import <SpriteKit/SpriteKit.h>
#import "HUDOverlay.h"
#interface GameViewController ()
#property (strong, nonatomic) CMMotionManager *motionManager;
#property (strong, nonatomic) CMAttitude *currentAttitude;
#property (strong, nonatomic) SCNNode *cameraNode;
#property (strong, nonatomic) SCNScene *scene;
#property (nonatomic) float roll;
#property (nonatomic) float yaw;
#property (nonatomic) float pitch;
#property (atomic) float yawCenterPoint;
#property (atomic) BOOL hasYawCenterPointBeenSet;
#end
GameViewController* sharedGameViewController = nil;
#implementation GameViewController
+(GameViewController*)sharedController{
if (sharedGameViewController == nil) {
sharedGameViewController = [[GameViewController alloc] init];
}
return sharedGameViewController;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// create a new scene
//SCNScene *scene = [SCNScene sceneNamed:#"art.scnassets/ship.dae"];
_scene = [SCNScene new];
self.hasYawCenterPointBeenSet = NO;
// create and add a camera to the scene
_cameraNode = [SCNNode node];
_cameraNode.camera = [SCNCamera camera];
[_scene.rootNode addChildNode:_cameraNode];
// place the camera
_cameraNode.position = SCNVector3Make(0, 0, 0);
// create and add a light to the scene
SCNNode *lightNode = [SCNNode node];
lightNode.light = [SCNLight light];
lightNode.light.type = SCNLightTypeOmni;
lightNode.position = SCNVector3Make(0, 10, 10);
[_scene.rootNode addChildNode:lightNode];
// create and add an ambient light to the scene
SCNNode *ambientLightNode = [SCNNode node];
ambientLightNode.light = [SCNLight light];
ambientLightNode.light.type = SCNLightTypeAmbient;
ambientLightNode.light.color = [UIColor whiteColor];
[_scene.rootNode addChildNode:ambientLightNode];
// retrieve the SCNView
SCNView *scnView = (SCNView *)self.view;
scnView.delegate = self;
scnView.playing = YES;
// set the scene to the view
scnView.scene = _scene;
scnView.overlaySKScene = [HUDOverlay sceneWithSize:scnView.frame.size];
// allows the user to manipulate the camera
scnView.allowsCameraControl = NO;
// show statistics such as fps and timing information
scnView.showsStatistics = YES;
// configure the view
scnView.backgroundColor = [UIColor blueColor];
// // add a tap gesture recognizer
// UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
// NSMutableArray *gestureRecognizers = [NSMutableArray array];
// [gestureRecognizers addObject:tapGesture];
// [gestureRecognizers addObjectsFromArray:scnView.gestureRecognizers];
// scnView.gestureRecognizers = gestureRecognizers;
SCNNode *sampleNode = [SCNNode new];
SCNPlane *samplePlane = [SCNPlane planeWithWidth:3 height:5];
SCNMaterial *angryFrontMaterial = [SCNMaterial material];
angryFrontMaterial.diffuse.contents = [UIImage imageNamed:#"angryfront110.png"];
sampleNode.geometry = samplePlane;
sampleNode.geometry.firstMaterial = angryFrontMaterial;
sampleNode.position = SCNVector3Make(0, 0, -10);
[_scene.rootNode addChildNode:sampleNode];
// SCNAction *moveToCamera = [SCNAction moveTo:SCNVector3Make(0, 0, -10) duration:10];
// [sampleNode runAction:moveToCamera];
[self setupRotationGrid];
[self setupMotionCapture];
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(updateCycle)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
//This is the update loop for the sceneView. When the view updates per frame this is where the logic goes
-(void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time{
}
-(void)updateCycle{
_currentAttitude = _motionManager.deviceMotion.attitude;
_roll = _currentAttitude.roll + (.5 * M_PI);
_yaw = _currentAttitude.yaw;
_pitch = _currentAttitude.pitch;
_cameraNode.eulerAngles = SCNVector3Make(-_roll, _yaw, _pitch);
//NSLog(#"yawCenterPoint = %d", _hasYawCenterPointBeenSet);
if (self.hasYawCenterPointBeenSet == NO) {
_yawCenterPoint = _yaw;
self.hasYawCenterPointBeenSet = YES;
NSLog(#"Yawcenter point set to %f", _yawCenterPoint);
}
//NSLog(#"Roll: %f Yaw: %f Pitch: %f", _roll, _yaw, _pitch);
}
-(void)setupRotationGrid {
double radius = 30;
double numberOfItems = 8;
SCNGeometry *geometry = [SCNBox boxWithWidth:4.5 height:8 length:3.25 chamferRadius:0.5];
double x = 0.0;
double z = radius;
double theta = (M_PI)/(numberOfItems/2);
double incrementalY = (M_PI)/(numberOfItems*2);
SCNNode *nodeCollection = [SCNNode node];
nodeCollection.position = SCNVector3Make(0, 4, 0);
for (int index = 1; index <= numberOfItems; index++) {
x = radius * sin(index*theta);
z = radius * cos(index*theta);
SCNNode *node = [SCNNode node];
node.geometry = geometry;
node.position = SCNVector3Make(x, 0, z);
float rotation = incrementalY * index;
node.rotation = SCNVector4Make(0, 1, 0, rotation);
[nodeCollection addChildNode:node];
}
[_scene.rootNode addChildNode:nodeCollection];
}
- (void) handleTap:(UIGestureRecognizer*)gestureRecognize
{
// retrieve the SCNView
SCNView *scnView = (SCNView *)self.view;
// check what nodes are tapped
CGPoint p = [gestureRecognize locationInView:scnView];
NSArray *hitResults = [scnView hitTest:p options:nil];
// check that we clicked on at least one object
if([hitResults count] > 0){
// retrieved the first clicked object
SCNHitTestResult *result = [hitResults objectAtIndex:0];
// get its material
SCNMaterial *material = result.node.geometry.firstMaterial;
// highlight it
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0.5];
// on completion - unhighlight
[SCNTransaction setCompletionBlock:^{
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0.5];
material.emission.contents = [UIColor blackColor];
[SCNTransaction commit];
}];
material.emission.contents = [UIColor redColor];
[SCNTransaction commit];
}
}
-(void)reCenterYaw{
self.hasYawCenterPointBeenSet = NO;
NSLog(#"Tapped recenter");
}
-(void)setupMotionCapture{
_motionManager = [[CMMotionManager alloc] init];
_motionManager.deviceMotionUpdateInterval = 1.0/60.0;
if (_motionManager.isDeviceMotionAvailable) {
[_motionManager startDeviceMotionUpdates];
_currentAttitude = _motionManager.deviceMotion.attitude;
}
// if (!_hasYawCenterPointBeenSet) {
// _yawCenterPoint = _currentAttitude.yaw;
// _hasYawCenterPointBeenSet = YES;
// }
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return UIInterfaceOrientationMaskLandscape;
} else {
return UIInterfaceOrientationMaskAll;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#end
I figured it out. I had created a singleton so that I could reference the view controller from the sprite kit hud class. The problem is that I load the view controller from the storyboard and then later, from the hud class init, I instantiate a new view controller because the "sharedViewController" never got initiated by the storyboard load. So, I just created a view controller property on the hud class and set it to self from the view controller did load code.

how can I create a menu screen for my spritekit game?

I already put my actual Gamescene inside the MyScene class. How can I create a menu screen even If I already put the game in the MyScene class. I tried to include the menu before the actual gamescene but that didnt work
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size]) {
if (self = [super initWithSize:size]){
SKSpriteNode *startButton = [SKSpriteNode spriteNodeWithImageNamed:#"startButton"];
startButton.position = CGPointMake(160, 300);
startButton.size = CGSizeMake(200, 200);
startButton.name = #"startButton";
[self addChild:startButton];
}
return self;
/* Setup your scene here */
self.anchorPoint = CGPointMake(0.5, 0.5);
self.physicsWorld.contactDelegate = self;
//SKSpriteNode *bgImage = [SKSpriteNode spriteNodeWithImageNamed:#""];
//[self addChild:bgImage];
self.backgroundColor = [SKColor colorWithRed:0.171875 green:0.2421875 blue:0.3125 alpha:1.0];
world = [SKNode node];
[self addChild:world];
self.physicsWorld.contactDelegate = self;
generator = [SPWorldGenerator generatorWithWorld:world];
[self addChild:generator];
[generator populate];
hero = [SPHero hero];
[world addChild:hero];
[self loadScoreLabels];
cloud1 = [SPHero cloud1];
[world addChild:cloud1];
cloud2 = [SPHero cloud2];
[world addChild:cloud2];
cloud3 = [SPHero cloud3];
[world addChild:cloud3];
cloud4 = [SPHero cloud4];
[world addChild:cloud4];
//uihui//
SKLabelNode *tapToBeginLabel = [SKLabelNode labelNodeWithFontNamed:GAME_FONT];
tapToBeginLabel.name = #"tapToBeginLabel";
tapToBeginLabel.text = #"tap to begin";
tapToBeginLabel.fontSize = 20.0;
[self addChild:tapToBeginLabel];
[self animateWithPulse:tapToBeginLabel]; // ** GETS RESET LABEL PULSING ** //
// ** PULSING TEXT ** //
SKAction *disappear = [SKAction fadeAlphaTo:0.0 duration:0.6];
SKAction *appear = [SKAction fadeAlphaTo:1.0 duration:0.6];
SKAction *pulse = [SKAction sequence:#[disappear, appear]];
[tapToBeginLabel runAction:[SKAction repeatActionForever:pulse]];
// ** PULSING TEXT ** //
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node.name isEqualToString:#"startButton"]) {
SKTransition *transition = [SKTransition doorsOpenVerticalWithDuration:1.0];
MyScene *game = [[MyScene alloc] initWithSize: CGSizeMake(self.size.width, self.size.height)];
[self.scene.view presentScene:game transition:transition];
}
}

adding CCPhysicsSprite to CCLayer cocos2d

I'm trying to reorganize HelloWorld project in cocos2d to our needs.
The thing I did - made a class, which is inherent from CCPhysicsSprite and wanted to add it to CCLayer (HelloWorldLayer). But something goes wrong. According to debugger my instance is created, but I can't see it in the iOS emulator. Need your help and explanations.
HelloWorldLayer.h
#interface HelloWorldLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate>
{
CCTexture2D *spriteTexture_; // weak ref
b2World* world_; // strong ref
GLESDebugDraw *m_debugDraw; // strong ref
}
HelloWorldLayer.mm (only changed by me functions:)
-(id) init
{
if( (self=[super init])) {
// enable events
self.touchEnabled = YES;
self.accelerometerEnabled = YES;
CGSize s = [CCDirector sharedDirector].winSize;
// init physics
[self initPhysics];
// create reset button
//[self createMenu];
//Set up sprite
//#if 1
// // Use batch node. Faster
// CCSpriteBatchNode *parent = [CCSpriteBatchNode batchNodeWithFile:#"blocks.png" capacity:100];
// spriteTexture_ = [parent texture];
//#else
// // doesn't use batch node. Slower
// spriteTexture_ = [[CCTextureCache sharedTextureCache] addImage:#"blocks.png"];
// CCNode *parent = [CCNode node];
//#endif
// [self addChild:parent z:0 tag:kTagParentNode];
//
//
// [self addNewSpriteAtPosition:ccp(s.width/2, s.height/2)];
CCLabelTTF *label = [CCLabelTTF labelWithString:#"Tap screen" fontName:#"Marker Felt" fontSize:32];
[self addChild:label z:0];
[label setColor:ccc3(0,0,255)];
label.position = ccp( s.width/2, s.height-50);
[self scheduleUpdate];
}
return self;
}
-(void) addNewSpriteAtPosition:(CGPoint)p
{
CCLOG(#"Add sprite %0.2f x %02.f",p.x,p.y);
if([self getChildByTag:kTagParentNode] == nil)
{
BloodRobotUnit *unit = [[BloodRobotUnit alloc] initWithOwner:world_ at:p];
[self addChild:unit z:0 tag:kTagParentNode];
}
}
And Creating unit: (header and mm file:)
#interface BloodRobotUnit : CCPhysicsSprite
{
b2Body *body_;
b2World *owner_;
}
-(id) initWithOwner:(b2World*)owner at:(CGPoint)pt;
mm:
-(id) initWithOwner:(b2World*)owner at:(CGPoint)pt
{
if(self = [super initWithFile:#"blocks.png" rect:CGRectMake(0, 0, 32, 32)])
{
owner_ = owner;
//create body at position
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(pt.x/PTM_RATIO, pt.y/PTM_RATIO);
body_ = owner->CreateBody(&bodyDef);
// Define another box shape for our dynamic body.
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m box
// Define the dynamic body fixture.
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body_->CreateFixture(&fixtureDef);
[self setB2Body: body_];
[self setPosition:pt];
return (self);
}
return nil;
}
Where is my mistake? Any help will be very appreciated
The trick was in setting position to self
Debugger showed that my texture was at position inf:inf
Code change to make everything work is the following:
in mm file of creating a CCPhysicsSprite iheriter do the following:
[self setB2Body: body_];
self.PTMRatio = PTM_RATIO;
//[self setPosition:CGPointMake(pt.x/PTM_RATIO, pt.y/PTM_RATIO)];
That is - you need to set only body position and set PTMRatio (thanx to #giorashc). Setting sprite texture is not necessary.

Objective C - CCSprites scaling and displaying differently in different parts of my code

I'm building an app that has a main menu layer and a background layer (for gameplay). I am loading the exact same CCParallax node code in both places, using the same images to create an infinite scrolling background.
On the gameplay background layer, the background displays and scrolls appropriately. However, on the main menu layer, the backgrounds are scaled weird (they don't take up the entire screen), and also don't scroll appropriately (probably because the scale is off somehow, so the offset isn't working).
Here is a screenshot of what the background looks like on the main menu:
And here it is on the background layer (green lines are part of the gameplay):
It almost looks like the menu layer is adding the non-retina display version of the files, but if I load the simulator into the iPhone (non-retina) mode, the meny background is still way off:
The code that loads the two is pretty much identical.
Here is the main menu loader code:
-(id)init {
self = [super init];
if (self != nil) {
CGSize winSize = [CCDirector sharedDirector].winSize;
_backgroundNode = [CCParallaxNode node];
[self addChild:_backgroundNode z:-1];
_backgroundGrid1 = [CCSprite spriteWithFile:#"grid.png"];
_backgroundCircuits1 = [CCSprite spriteWithFile:#"bg-circuits.png"];
_backgroundGrid1.anchorPoint = CGPointMake(0,0);
_backgroundCircuits1.anchorPoint = CGPointMake(0,0);
CGPoint gridSpeed = ccp(0.05, 0.05);
CGPoint circuitSpeed = ccp(0.1, 0.1);
[_backgroundNode addChild:_backgroundGrid1 z:1 parallaxRatio:gridSpeed positionOffset:ccp(0,-winSize.height)];
[_backgroundNode addChild:_backgroundCircuits1 z:0 parallaxRatio:circuitSpeed positionOffset:ccp(0,-winSize.height)];
[self scheduleUpdate];
}
return self;
}
- (void)update:(ccTime)dt {
CGPoint backgroundScrollVel = ccp(0, 1000);
_backgroundNode.position = ccpAdd(_backgroundNode.position, ccpMult(backgroundScrollVel, dt));
NSArray *backgroundGrids = [NSArray arrayWithObjects:_backgroundGrid1, nil];
for (CCSprite *b in backgroundGrids) {
if ([_backgroundNode convertToWorldSpace:b.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(b.contentSize.height/3)) forChild:b];
}
}
NSArray *backgroundCircuits = [NSArray arrayWithObjects:_backgroundCircuits1, nil];
for (CCSprite *bc in backgroundCircuits) {
if ([_backgroundNode convertToWorldSpace:bc.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(bc.contentSize.height/3)) forChild:bc];
}
}
}
And here is the code for the background layer:
- (id)init
{
self = [super init];
if (self != nil) {
CGSize winSize = [CCDirector sharedDirector].winSize;
_backgroundNode = [CCParallaxNode node];
[self addChild:_backgroundNode z:-1];
_backgroundGrid1 = [CCSprite spriteWithFile:#"grid.png"];
_backgroundCircuits1 = [CCSprite spriteWithFile:#"bg-circuits.png"];
_backgroundGrid1.anchorPoint = CGPointMake(0,0);
_backgroundCircuits1.anchorPoint = CGPointMake(0,0);
CGPoint gridSpeed = ccp(0.05, 0.05);
CGPoint circuitSpeed = ccp(0.1, 0.1);
[_backgroundNode addChild:_backgroundGrid1 z:1 parallaxRatio:gridSpeed positionOffset:ccp(0,-winSize.height)];
[_backgroundNode addChild:_backgroundCircuits1 z:0 parallaxRatio:circuitSpeed positionOffset:ccp(0,-winSize.height)];
[self scheduleUpdate];
return self;
}
- (void)update:(ccTime)dt {
CGPoint backgroundScrollVel = ccp(0, 1000);
_backgroundNode.position = ccpAdd(_backgroundNode.position, ccpMult(backgroundScrollVel, dt));
NSArray *backgroundGrids = [NSArray arrayWithObjects:_backgroundGrid1, nil];
for (CCSprite *b in backgroundGrids) {
if ([_backgroundNode convertToWorldSpace:b.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(b.contentSize.height/3)) forChild:b];
}
}
NSArray *backgroundCircuits = [NSArray arrayWithObjects:_backgroundCircuits1, nil];
for (CCSprite *bc in backgroundCircuits) {
if ([_backgroundNode convertToWorldSpace:bc.position].y > 0) {
[_backgroundNode incrementOffset:ccp(0,-(bc.contentSize.height/3)) forChild:bc];
}
}
}

UIImagePickerController only working once

I am using UIImagePickerController for users to select the background in my Cocos2D game. It works the first time you use it, but if you try to change the background again the picker will show up, but when you select the image the background will stay the same.
This is my code:
- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSArray *TouchesA = touches.allObjects;
for (int i = 0; i < TouchesA.count; i++) {
CGPoint touchLocation = [self convertTouchToNodeSpace:[TouchesA objectAtIndex:i]];
CGRect rect = CGRectMake(touchLocation.x, touchLocation.y, 1, 1);
if(CGRectIntersectsRect(rect, infoButton.boundingBox))
{
[self pickPhoto:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
}
}
}
-(void)pickPhoto:(UIImagePickerControllerSourceType)sourceType{
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
picker.sourceType = sourceType;
//picker.wantsFullScreenLayout = YES;
//[picker presentModalViewController:picker animated:YES];
[[[CCDirector sharedDirector] openGLView] addSubview:picker.view];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissModalViewControllerAnimated:YES];
[picker.view removeFromSuperview];
[picker release];
}
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info{
newImage = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[picker dismissModalViewControllerAnimated:YES];
[picker.view removeFromSuperview];
[picker release];
CCSprite *imageFromPicker = [CCSprite spriteWithCGImage:newImage.CGImage key:#"ImageFromPicker"];
Background = imageFromPicker;
int SSw = [CCDirector sharedDirector].winSize.width;
int SSh = [CCDirector sharedDirector].winSize.height;
Background.position = ccp(SSw/2, SSh/2);
Background.scaleX = SSw / Background.textureRect.size.width;
Background.scaleY = SSh / Background.textureRect.size.height;
[[self children] removeObjectAtIndex: 0];
[[self children] insertObject:Background atIndex:0];
}
How can I fix this?
EDIT:
#interface HelloWorldLayer : CCLayer <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>
{
CCSprite *infoButton;
CCSprite *Background;
UIImage *newImage;
}
-(id) init
{
if( (self=[super init])) {
self.isTouchEnabled = true;
[[CCDirector sharedDirector].openGLView setMultipleTouchEnabled:YES];
int SSw = [CCDirector sharedDirector].winSize.width;
int SSh = [CCDirector sharedDirector].winSize.height;
Background = [CCSprite spriteWithFile:#"B.jpg"];
Background.position = ccp(SSw/2, SSh/2);
Background.scaleX = SSw / Background.textureRect.size.width;
Background.scaleY = SSh / Background.textureRect.size.height;
infoButton = [CCSprite spriteWithFile:#"info.png"];
infoButton.position = ccp(SSw - 15, 15);
[self addChild:Background];
[self addChild:infoButton];
[self schedule:#selector(nextFrame:)];
}
return self;
}
I've had the same problem
Check this line:
CCSprite *imageFromPicker = [CCSprite spriteWithCGImage:newImage.CGImage key:#"ImageFromPicker"];
and try to replace it with:
// resize image
UIImage* image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
// add current shot
CCTexture2D *texture2D = [[[CCTexture2D alloc] initWithImage:image] autorelease]; // this is new
CCSprite *sprite = [CCSprite spriteWithTexture:texture2D]; // this is new
also look here:
http://www.cocos2d-iphone.org/forum/topic/30259?replies=8#post-149117
Hope this helps.
How about trying something like:
[Background removeFromParentAndCleanup:YES];
CCSprite *imageFromPicker = [CCSprite spriteWithCGImage:newImage.CGImage key:#"ImageFromPicker"];
Background = imageFromPicker;
int SSw = [CCDirector sharedDirector].winSize.width;
int SSh = [CCDirector sharedDirector].winSize.height;
Background.position = ccp(SSw/2, SSh/2);
Background.scaleX = SSw / Background.textureRect.size.width;
Background.scaleY = SSh / Background.textureRect.size.height;
[[self children] insertObject:Background atIndex:0];