How to pass variable to other method? - objective-c

I know this is a very beginner question, but I've been struggling to figure it out.
I'm trying to build an iOS game (using cocos2d) and so I have 2 sets of files
GameScene.h and gameScene.m
MainMenu1.h and MainMenu1.m
GameScene has the sharedcode I've leaned to put in.
I call my MainMenu1 - the user chooses how many players from a MenuItemwithImage and that calls ChoosePlayers
I can figure out which menu item was touched, but I need to pass the number of players back to GameScene
in GameScene I put in
-(void) setPlayers (nsinteger*) players
{
totalplayers = players;
}
so in mainmenu1 chooseplayers i did
[[GameScene SharedGameData] setPlayers : 2];
but that doesn't work.
I'm sorry, I don't have the code in front of me (not until tonight); i've been searching for hours and can't figure it out.

Your method format is incorrect. It should be:
-(void)setPlayers:(NSInteger)players;
NSInteger is not a pointer either.
To pass multiplie values, you coud either pass in an array, or:
-(void)setPlayers:(NSInteger)firstValue withSecondValue:(NSInteger)secondValue; and when you want to call it, it would look like this:
[[GameScene SharedGameData] setPlayers:2 withSecondValue:4];

Hi it would be good if you could post some more detail about the errors you are receiving (if any?), this would helpt to diagnose the problem but looking at you code it i think that you need to change the
-(void) setPlayers (nsinteger*) players
to
-(void) setPlayers :(nsinteger*) players
hope this helps!

Related

What is a proper paradigm for having a mutable global value in objective-C

So, let's say that I am displaying an integer myInt value in OneViewController. Then, while a different view is showing, AnotherViewController, I need to increment or decrement myInt.
So the scope needs to be global or at least be able to be accessed by other viewControllers and it needs to be mutable.
I know that properties one way to do this but I haven't been able to get them to work. I have been importing the header file of OneViewController into AnotherViewController but that wasn't what I was missing.
I've gone through several introductory books but multi-view controller variable work wasn't explicitly covered in any of them. Clearly I'm a beginner so please excuse any conceptual misunderstandings.
Doesn't have to be view controllers -- any sort of custom classes.
In FirstClass.h:
#property(whatever) int someIntInFirstClass;
-(void) someMethodInFirstClass;
SecondClass.h
#property(whatever) FirstClass* myParent;
FirstClass.m
SecondClass* second = [[SecondClass alloc] init];
second.myParent = self;
[second startSomething];
SecondClass.m:
[self.myParent someMethodInFirstClass];
int x = self.myParent.someIntInFirstClass;
self.myParent.someIntInFirstClass = x + 1;
Have a look at ReactiveCocoa library and check how the signal pattern works. The library has to offer a lot of things including the scenario you have just mentioned.
https://github.com/ReactiveCocoa/ReactiveCocoa
A bit of a learning curve. But worth!

How to use ios 6 challenge in game centre

Firstly,
I am fairly new to objective c / xcode dev so there is a good chance i am being a muppet. I have written a few simple apps to try things and my most recent one has been testing the gamecentre classes / functionality.
i have linked ok to leaderboards and achievements - but i can't get challenges working.
I have added the following code.... which is in my .m
GKLeaderboard *query = [[GKLeaderboard alloc] init];
query.category = LoadLeaderboard;
query.playerScope = GKLeaderboardPlayerScopeFriendsOnly;
query.range = NSMakeRange(1,100);
[query loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error)
{NSPredicate *filter = [NSPredicate predicateWithFormat:#"value < %qi", scoreint];
NSArray *lesserScores = [scores filteredArrayUsingPredicate:filter];
[self presentChallengeWithPreselectedScores: lesserScores];
}
];
this code is basically taken from apple, just replacing the variable names....
this however gives an error on
[self presentChallengeWithPreselectedScores: lesserScores];
error Implicit conversion of an Objective-C pointer to 'int64_t *' (aka 'long long *') is disallowed with ARC
LoadLeaderboard is defined as a string
scoreint is defined as integer, thought this may be issue as not int64_t but that does not seem to make a difference.
I am sure for someone who has any kind of a clue this is a straightforward fix. But i am struggling at the moment. So if anyone can be kind and help a fool in need it would be most appreciated
Thanks,
Matt
welcome to Stack Overflow. I don't know your implementation of presentChallengeWithPreselectedScores method so I can't tell (although it looks like the method is taking a 64 bit integer and you're trying to feed it an array).
There are two ways to issue challenges:
1 - This is the easier way - if you've successfully implemented leader boards and score posting to game center, the challenges work out of the box in iOS6, the user can always view the leader board - select a submitted score (or a completed achievement) and select "Challenge Friend".
2 - The second way is to build a friend picker and let the user issue challenges within your game. But considering you're new to objective-c and game center, it's not so easy. But for your reference here is how you do it:
when you submit a GKScore object for the leaderboards - you can retain and use that GKScore object (call it myScoreObject) like this:
[myScoreObject issueChallengeToPlayers:selectedFriends message:yourMessage];
where selectedFriends is an NSArray (the friend picker should generate this) - the message is optional and can be used only if you want to send a message to challenged friends.

How to bind a buttons title to a particular value in an array IOS?

I have six on-screen buttons whose titles need to correspond to six elements in an NSMutableArray, when the value in the array changes, I also need the title to change with it. I am having trouble figuring out how to create that constantly updating line to the button, I'm still quiet new to objective-c development as well as Xcode.
I also need to make sure that when there is no value at that particular index of the array, the button cannot be clicked on
here is an example of one of the buttons
- (IBAction)card1Pressed:(id)sender {
if (self.userHasEnteredFirstNumber) {
if (!self.userHasEnteredSecondNumber) {
self.secondNumber = [sender currentTitle];
}
}
else{
self.firstNumber = [sender currentTitle];
}
}
The end goal is to have the user press two buttons, then chose weather to add, subtract, multiply, or divide them. After they pick one of those four operations, the values that the buttons were assigned to in the array will be removed and replaced with whatever the new number is. So after they do this once there will only be 5 numbers left in the array, then 4, then 3..... and so on.
The numbers will be drawn and added to an NSMutable array titled currentHand
UPDATE: Using UIOutletCollection I linked the buttons to the method like this
the link to the picture is here "sorry about not being able to directly post it but new users must have a reputation of 10 before they can"
link to photo of declaration and implementation with interface-builder of IBOutletCollection
was this correct?
the code for the header file regarding the IBOutletCollection is as follows "please note that this has been connected to the six buttons I want to use it with in interface builder, a picture of it is shown above"
#property (nonatomic,retain) IBOutletCollection (UIButton)NSArray *buttonArray;
the code in the implementation file regarding the IBOutletController is as follows
# synthesize buttonArray = _buttonArray;
You want to use Key-Value observing, check out this from the Apple documentation:
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html#//apple_ref/doc/uid/10000177i
Okay okay, so essentially you have a 'Button'-Array, whose 'Caption' is served by a NSMutableArray, which can easily be changed around, correct?
Now, this is only how I'd do it, there may be better solutions out there, but here goes:
You need a 'change' interface, which is called EACH time, something happens to your NSMutableArray. For example (since I don't know WHAT exactly is in that array of yours):
- (void) ChangeArray:(int)IDofElement (NSString *)newValue {
[arr replaceObjectAtIndex:IDofElement withObject:newValue]; //Updates/Empties the indexed Element.
if(newValue != nil) {
[buttons[IDOfElement] setText:newValue];
}
buttons[IDOfElement].enabled = (newValue != nil); //Makes Button 'clickable'
}
Like this, each time the value inside that array of yours gets changed, the corresponding caption also gets updated. Of course you would need an array of the buttons for this to work, but I don't think that's the big problem.
Another possible solution: Save a reference to the button inside of the object that's stored in the array and whenever the value is changed, change the button's caption too.
Does this help? Mind you, this is not the 'perfect solution', but something I'd come up with.
Please also note, that this is just from the top of my head and probably faulty at some points. But it should be able to point you in the general direction.

Error removing sprites from a spritesheet in Cocos2D

I'm in the initial building stages of an iphone game, and I'm using sprite sheets to create some random people, each one with sub-sprites for hair, clothing etc.
I'm storing my sprite images in spritesheets using CCSpriteBatchNode. I'm just doing an initial setup test now, where you tap the screen to generate a new random set of people. So the weird thing is, you can tap once and it will remove the old people and replace them with new people, but the second time, it crashes with the error:
"CCSpriteBatchNode doesn't contain the sprite. Can't remove it"
Now I'm sure I've added the sprite to the batch node, in my Person.m constructor I have this line:
[spriteSheet addChild:person];
In my test code in ccTouchesEnded I've got the following code:
//updated with changes suggested by Mazyod and Jer
for(int i=6; i>=0; i--){
Person *per = [_people objectAtIndex:i];
[_people fastRemoveObjectAtIndex:i];
[_spritesheet removeChild:per cleanup:YES];
per = nil;
}
for(int i = 0; i < 7; i++){
Person *per = nil;
per = [Citizen personFromCountry:_country1 WithSpriteSheet:_spritesheet];
per.position = ccp(100 + (50 * i),160);
[_people addObject:per];
[_spritesheet addChild:per];
}
Can anybody suggest what I'm missing? I've read a bunch about spritesheets in cocos2d and am given to understand that removing individual sprites is tricky so I'm sure there's some vital lines I need to add here. Thanks for your help!
Edit: I googled the error and found this thread: http://www.cocos2d-iphone.org/forum/topic/17170 which seems to confirm that Cocos2d thinks I'm not adding the sprite to the spritesheet - but I am, as proven by the fact that the sprites add correctly the first time, just not the second.
One solution is to simply avoid removing the sprites at all, just make them invisible and redraw them with new characteristics when they need to be reused. I'd rather know what the real solution is though because it seems cleaner.
Looks like you need to change
[_people addObject:per];
to
[_people replaceObjectAtIndex:i withObject:per];
In your first loop you are just setting the value of the object in the array to nil, but not removing it from the array. In the second loop you just add it onto the end of the array, but your array already has 7 nils in it.
Let me know if it works.
Well, I could help you clear out one thing for now:
Any CCNode can only be a child to one parent. ie It has to have a single parent.
But, what you have here:
for(int i=0; i<7; i++){
Person *per = [_people objectAtIndex:i];
[self removeChild:per cleanup:YES];
[_spritesheet removeChild:per cleanup:YES];
per = nil;
}
Suggest you are trying to add the person to both the spriteSheet and self at the same time.. Check your Log, it must have something like:
cocos2d: removeChild, child not found.
And from the error you are getting, I am betting that the person is added to self and not to the sprite sheet.
So, how to solve this?
Well, you have to add the person to the spriteSheet as a child, then add the spriteSheet to self as a child. (Actually, the order you add them doesn't matter).
Sort this out, and maybe this problem will go away, or at least it will be clearer so we can help you.
I just want to mention my experience here with this problem and how I solved it.
Remember, you are either trying to remove a child that was never added..
OR
Trying to remove a child TWICE.
This was the case for me. The collision detection in my game was solid (at least I thought). Then randomly, like 1 out of every 7-10 runs... I would get this crash. I realized it was because I had coded my projectiles to be removed once they intersected a target.
I did not however, put a failsafe where IF my tick method detected that it was in collision with MORE then 1 target at a time.
This was because for every projectile, I iterated through each target to check for a collision, then removed the respective projective if collision was detected. So I created a simple BOOL, and set it to YES if it had already collided with a target. Then I only checked for collision if the projectile had not collided with anything.
So... before:
if (CGRectIntersectsRect(projectileRect, targetRect))
{
//code to remove projectile
}
After:
if (CGRectIntersectsRect(projectileRect, targetRect) && projectile.hasHitaTarget == NO)
{
//code to remove projectile
}

How do I make a button play sounds in a certain order using an array?

I'm coding in Objective-C for the iPhone and I am trying create an array that plays a series of sounds. For example the first time I press the button I want it play sound "0.wav", but the second time I want it to play "1.wav", then "2.wav", "3.wav", etc. Then when I've played a total of 14 sounds (up to "13.wav") I want the loop to start over playing with 0.wav. I've looked around Google and the Apple development documentation for almost 4 days without much luck. So if someone could help me generate a code for this that would be greatly appreciated and if you wouldn't mind could you attempt to explain the code briefly so that I can learn what each part does.
Thank you, Joey
EDIT
Okay I've gotten the Array part down (thanks to Thomas) however neither of us are sure how to implement the soundID from the array to the action where I play the sound and how to play that sound. I used the format Thomas used for his array below if that helps you with your answer.
Thanks, Joey
First, create the array of your different sounds and a variable to hold the current index:
NSArray *sounds = [[NSArray alloc] initWithObjects:#"0.wav", #"1.wav", nil]; // add all your files here
NSUInteger currentSound = 0;
Then, when you handle your button tapped event, go to the next sound, and play it. If it's at the end of your NSArray, go back to index 0:
currentSound++;
if (currentSound >= [sounds count]) {
currentSound = 0;
}
// play the sound. Just call your own method here
[self playSoundWithFilename:[sounds objectAtIndex:currentSound]];