error index beyond bounds - cocos2d-iphone

-(id) init
{
if( (self=[super init])) {
_targets = [[NSMutableArray alloc] init];
temp = [NSArray arrayWithObjects:#"1", #"2", #"3", #"4",nil];
tempArray = [[NSMutableArray alloc] initWithArray:temp];
resultArray = [[NSMutableArray alloc] init];
[self thelogic];
}
return self;
}
-(void)thelogic
{
int i;
int count = 4;
for (i = 0; i < 3; i ++) {
int index = arc4random() % (count - i);
[resultArray addObject:[tempArray objectAtIndex:index]];
CCSprite *target = [CCSprite spriteWithFile:[NSString stringWithFormat:#"%#.png", [tempArray objectAtIndex:index]]];
target.tag = [[NSString stringWithFormat:#"%#",[tempArray objectAtIndex:index]] integerValue];
[self addChild:target];
[_targets addObject:target];
[tempArray removeObjectAtIndex:index];
}
}
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[_targets removeAllObjects];
[self thelogic];
}
from the up code, I get three different numbers and they make three sprites with different image when enter this scene, and I want to touch the screen, the three old sprites will be removed, and three new sprites will show, but the up code always crashes, so how should I fix it? thanks

It is hard to understand what you are trying to do in your theLogic method, but I would suggest you to replace
int index = arc4random() % (count - i);
with
int index = arc4random() % [tempArray count];
This will fix the crash, but I doubt that your program will work as expected. Indeed, you only populate tempArray in the init method; the first call to theLogic will remove all of its elements, and as far as I see the array is not populated anymore. So, when you make ccTouchesBegan be called and then theLogic, tempArray will be empty.
Sorry if I am missing any points.

Related

convert c++ vector to Objective-c

I currently have
vector<vector<cv::Point>> example;
and want to be able to pass it to a swift function, So I assume I should start by making it like this (or is there easier way?):
NSArray[NSArray[Int,Int]]
cv::Point is an object of two int properties.
I have tried
NSMutableArray *example1[example.size()];
for(i = 0;i< example.size();i++){
if(example[i].size() > 5){ //irrelevant
NSMutableArray *second[example[i].size()];
for(int p = 0;p<example[i].size();p++){
NSInteger p1 = example[i][p].x;
NSInteger p2 = example[i][p].y;
NSInteger point[2] = {p1,p2};
[second addObject: point];
}
[example addObject: second];
}
}
I have been spending ages and constantly getting different data type errors, etc. How would you do it, or correct this?
Thanks
You can use NSValue to store a simple struct into NSMutableArray:
NSMutableArray *example1 = [NSMutableArray arrayWithCapacity:example.size()];
for(int i = 0;i< example.size();i++){
if(example[i].size() > 5){ //irrelevant
NSMutableArray *second = [NSMutableArray arrayWithCapacity:example[i].size()];
for(int p = 0;p<example[i].size();p++){
NSValue *point = [[NSValue alloc] initWithBytes:&example[i][p] objCType:#encode(cv::Point)];
[second addObject:point];
}
[example1 addObject:second];
}
}

How do we enumerate and modify positions array of CCsprite inside Update method?

How do we enumerate and alter our object's position (contained in array) for each delta time?
I put some CCsprite objects inside array, then I displayed them in scene, but also I wanted to make them move with modifying update method, I failed on last part.
How do I get around this ?
#implementation GameScene
{
Hunter *_hunter;
Bird *_bird;
NSMutableArray *_arrayOfBirds;
}
-(void)update:(CCTime)delta{
CGSize viewSize = [CCDirector sharedDirector].viewSize;
float birdSpeed = 50;
for (Bird *birds in _arrayOfBirds) {
if (birds.position.x < 0) {
birds.flipX = YES;
}
if (birds.position.x > viewSize.width) {
birds.flipX = NO;
}
float distanceToMove = birdSpeed * delta;
float direction = birds.flipX ? 1 : -1;
float newX = birds.position.x + direction * distanceToMove;
float newY = birds.position.y;
birds.position = ccp(newX, newY);
}
}
-(void)addBird{
CGSize viewSize = [CCDirector sharedDirector].viewSize;
for (int i=0; i < 4; i++) {
_bird = [[Bird alloc]initWithBirdType:(i)];
_bird.position = ccp(viewSize.width * 0.5f + 30 * i , viewSize.height * 0.9f - 15* i);
[self addChild:_bird];
[_arrayOfBirds addObject:_bird];
}
}
You forgot to initialize your array
here (assuming ARC)
-(id) init {
if(self=[super init]) {
_arrayOfBirds = [[NSMutableArray alloc] init];
// the rest
}
return self;
}

Cocos2d-iphone v3 - draw a line and convert it so I could use it for CCSprite

http://i.stack.imgur.com/cjZBq.png
Right I've looked and I can seem to find the answer.
I'm using Cocos2d-iphone V3.
What I want to achieve is the above.
I want to take the devices width or height and and draw two lines.
I want to take the drawn lines and use the for the CCProgress.
Question:
How do I take the drawn lines and convert them to CCSprite?
If you can give me the code it would be great, but if you could give me a link to any tutorial or documentation so I can learn how to do this, that would be even better.
Thank you.
#LearnCocos2d
So i'm doing this now but I get a very weird result;
CGSize winSize = [[CCDirector sharedDirector] viewSize];
_progressWidth = winSize.width *2;
//CGPoint position = ccp(0.3, 0.5);
//CCTime interval = 1.0/60.0;
NSMutableArray * tempProgressFg = [[NSMutableArray alloc] initWithCapacity:[Utilities getRows]+1];
NSMutableArray * tempProgressBg = [[NSMutableArray alloc] initWithCapacity:[Utilities getRows]+1];
CCTexture * bg = [_progressBg texture];
CCTexture * fg = [_progressFg texture];
for (int i = 0; i < [Utilities getRows]; i++)
{
if (i == 0)
{
_progressBg.scaleX = _progressWidth;
_progressFg.scaleX = _progressWidth;
_progressBg.position = ccp(0, i * TILE);
_progressFg.position = ccp(0, i * TILE);
[tempProgressFg addObject:_progressFg];
[tempProgressBg addObject:_progressBg];
}
else
{
CCSprite * tempBg = [CCSprite spriteWithTexture:bg];
CCSprite * tempFg = [CCSprite spriteWithTexture:fg];
tempBg.scaleY = 1;
tempFg.scaleY = 1;
tempBg.scaleX = _progressWidth;
tempFg.scaleX = _progressWidth;
tempBg.position = ccp(0, i * TILE);
tempFg.position = ccp(0, i * TILE);
[self addChild:tempBg];
[self addChild:tempFg];
[tempProgressBg addObject:tempBg];
[tempProgressFg addObject:tempFg];
}
}
The result that i get is in this picture:
http://imgur.com/1dMpiUc,V47d65X
is the _progressBg and Fg;
are the tempBg and Fg (multiples of them);
I want to have them all look like number 1.
Am I doing something wrong? is that the correct way to coppy the bar?

Making an incremental counter for scores

How can I make a counter that will increment (run through) from zero to the score attained within two seconds? I plan to use this for displaying the final score in game over popup. I am not really too sure how to go about this. Please help.
Following is the code you can use to setup your animation (using scheduler) according to given values:
float secs = 2.0f;
float deciSecond = 1 / 10;
newScore = 100;
currentScore = 0;
scoreInDeciSecond = (newScore / secs) * deciSecond;
[self schedule:#selector(counterAnimation) interval:deciSecond];
And this is how your method will handle the animation:
- (void)counterAnimation {
currentScore += scoreInDeciSecond;
if (currentScore >= newScore) {
currentScore = newScore;
[self unschedule:#selector(counterAnimation)];
}
scoreLabel.string = [NSString stringWithFormat:#"%d", currentScore];
}
I personally don't know cocos2d and how it displays text or uses timers, but here is how to do it with pure iOS SDK. If you know cocos2d, it shouldn't be a problem converting it.
- (void)viewDidLoad
{
[super viewDidLoad];
highScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(100.0, 100.0, 200.0, 75.0)];
[self displayHighScore];
}
-(void)displayHighScore {
highScore = 140;
currentValue = 0;
NSString* currentString = [NSString stringWithFormat:#"%d", currentValue];
[highScoreLabel setText:currentString];
[self.view addSubview:highScoreLabel];
int desiredSeconds = 2; //you said you want to accomplish this in 2 seconds
[NSTimer scheduledTimerWithTimeInterval: (desiredSeconds/highScore) // this allow the updating within the 2 second range
target: self
selector: #selector(updateScore:)
userInfo: nil
repeats: YES];
}
-(void)updateScore:(NSTimer*)timer {
currentValue++;
NSString* currentString = [NSString stringWithFormat:#"%d", currentValue];
[highScoreLabel setText:currentString];
if (currentValue == highScore) {
[timer invalidate]; //stop the timer because it hit the same value as high score
}
}

warnings when using setDelay and addFrameWithFilename

I want to use the following lines of code in my project.
// Create the intro image
CGSize screenSize = [CCDirector sharedDirector].winSize;
CCSprite *introImage = [CCSprite spriteWithFile:#"intro1.png"];
[introImage setPosition:ccp(screenSize.width/2, screenSize.height/2)];
[self addChild:introImage];
// Create the intro animation, and load it from intro1 to intro7.png
CCAnimation *introAnimation = [CCAnimation animation];
[introAnimation setDelay:2.5f];
for (int frameNumber=0; frameNumber < 8; frameNumber++) {
CCLOG(#"Adding image intro%d.png to the introAnimation.",frameNumber);
[introAnimation addFrameWithFilename:
[NSString stringWithFormat:#"intro%d.png",frameNumber]];
I get the warning:
instance method '-setDelay:' not found (return type defaults to 'id')
pointing to the line
[introAnimation setDelay:2.5f];
and a similar warning pointing to the line
[introAnimation addFrameWithFilename: [NSString stringWithFormat:#"intro%d.png",frameNumber]];
Has setDelay and addFrameWithFilename been deprecated? If yes, what should I use in their place. Please help.
hmmm ... not certain these methods exist at all. Here is an example from my code base (cocos2 version 2.0).
+ (CCAnimation *) getAnimationForSoldier:(Soldier *)theSoldier animationType:(mapAnimationTypeE)animationType {
id animation = nil;
NSString *animationName = [SpriteUtils getAnimationNameForSoldier:theSoldier animationType:animationType];
if (!animationName) return nil;
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:[NSString stringWithFormat:#"%#.plist", animationName]];
if ((animation = [[CCAnimationCache sharedAnimationCache] animationByName:animationName])) {
return animation;
} else {
NSUInteger numberOfFrames = 8;
if (animationType == mapAnimationTypeCast || animationType == mapAnimationTypeSkill) numberOfFrames = 20;
NSMutableArray *frames = [NSMutableArray arrayWithCapacity:numberOfFrames];
for (NSUInteger i = 1 ; i <= numberOfFrames ; i++) {
NSString *frName = [SpriteUtils getFrameNameForAnimationNamed:animationName andFrame:i];
CCSpriteFrame *frr = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:frName];
if (frr) {
[frames addObject:frr];
} else {
MPLOGERROR(#"*** No frame named [%#], bailing out.", frName);
return nil;
}
[frames addObject:frr];
}
animation = [CCAnimation animationWithSpriteFrames:frames delay:.06];
[[CCAnimationCache sharedAnimationCache] addAnimation:animation name:animationName];
}
return animation;
}
note : first create your spriteframes array, then create the animation with the array and the desired delay.
The delay is delay between each frame (not the total duration).
If you are using cocos2d version 2.N, the setter for delay is
animation.delayPerUnit = 0.6f;