Cannot Position Instance of Subclass of CCSprite - objective-c

I'm not terribly new to Objective-C, but I can't figure out this issue. I'm attempting to create an instance of a subclass of CCSprite that I made, but it always creates the instance at (0,0), and I can't move it. I've set up my code so that it parses a .txt file in which I put level information, and then it creates sprites based on that information.
Here's the code that initializes the sprite:
-(void)initLevel{
NSLog(#"Level %i is of length %i", lvlNum, [FileReader getLengthOfLevel:[FileReader getStartOfLevel:lvlNum atPath:lvlPack] atPath:lvlPack]);
CCSprite *spriteToMake;
int start = [FileReader getStartOfLevel:lvlNum atPath:lvlPack];
int length = [FileReader getLengthOfLevel:start atPath:lvlPack];
NSString *tmp = [FileReader getLineFromFile:lvlPack byIndex:start];
NSArray *tmpArray = [tmp componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSMutableArray *tmpArray2 = [tmpArray mutableCopy];
[tmpArray2 removeObject:#""];
requiredLinks = [(NSString*)[tmpArray2 objectAtIndex:2] intValue];
[tmpArray2 release];
for(int i = start + 1; i <= start + length; i++){
NSString *line = [FileReader getLineFromFile:lvlPack byIndex:i];
int x = 0;
int y = 0;
NSArray *temp = [line componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSMutableArray *temp2 = [temp mutableCopy];
[temp2 removeObject:#""];
//Determine the type of sprite
if([(NSString*)[temp2 objectAtIndex:0] isEqualToString:#"Basic_Sprite"]){
spriteToMake = [BasicLink sprite];
}else if([(NSString*)[temp2 objectAtIndex:0] isEqualToString:#"Big_Sprite"]){
spriteToMake = [BasicLink spriteWithFile:#"Big_Link.png"];
}else{
spriteToMake = nil;
}
//Create the sprite
if(spriteToMake != nil){
x = [(NSString*)[temp2 objectAtIndex:1] intValue];
y = [(NSString*)[temp2 objectAtIndex:2] intValue];
spriteToMake.position = ccp(x, y);
NSLog(#"%#", spriteToMake);
[self addChild:spriteToMake];
[spriteToMake setUpdate];
}else{
NSLog(#"Sprite set to NULL");
}
NSLog(#"%i, %i, %i", x, y, [temp2 count]);
[temp2 release];
}
}
And here's the subclass' header:
#interface BasicLink : CCSprite{
CGPoint position;
CGPoint movement;
int explosionRadius, width, height;
CCScene *sceneIn;
}
#property (assign)CGPoint pos, movement;
#property (assign)int explosionRadius, width, height;
#property (assign)CCScene* sceneIn;
+(CCSprite*)sprite;
+(CCSprite*)spriteAtX:(int)x atY: (int)y;
-(void)die;
-(void)explode;
-(void)updateSprite;
-(CGRect)getBounds;
-(void)setUpdate;
-(void)move:(int)x, int(y);
#end
And here's the part of the subclass that initializes the sprite:
#implementation BasicLink
#synthesize position, movement, explosionRadius, sceneIn, width, height;
+(CCSprite*)sprite{
return [BasicLink spriteWithFile:#"Basic_Link.png"];
}
Any help is appreciated.

Here's an obvious problem:
-(void)move:(int)x, int(y);
In C, the comma is an operator. The compiler interprets this statement as this method declaration:
- (void)move:(int)x
I'm not entirely certain what it's doing with int(y); it's possibly treating it as a C function declaration. In any case, it isn't part of the method declaration.
Your move declaration should look like this:
- (void)moveToX:(int)x andY:(int)y;
Another minor mistake is the return type of your class methods:
+(CCSprite*)sprite{
return [BasicLink spriteWithFile:#"Basic_Link.png"];
}
That should be:
+ (BasicLink *)sprite{
return [BasicLink spriteWithFile:#"Basic_Link.png"];
}
That's probably not your problem here, though.

Related

copy and sort an NSArray in one step

I am trying to sort an NSArray.
Unfortunately the array appears to stay empty.
I start with an NSMutableArray with normal distributed data called "gaussianPopulation" which is then to be copied and sorted into the NSArray "sortedData".
I checked a similar post here: Sorting NSArray and returning NSArray?
But I am still missing something...
Population.h:
#define ARC4RANDOM_MAX 0x100000000
#import <Foundation/Foundation.h>
#interface Population : NSObject
#property NSMutableArray *totalPopulation;
#property NSMutableArray *gaussianPopulation;
-(void)createPopulation; // test purpose to create uniform distribution. not used anymore.
-(void)createGaussianPopulation;
-(double)calculateAndersonDarling;
#end
and Population.m:
#import "Population.h"
#include <math.h>
#implementation Population
-(void)createPopulation
{
_totalPopulation = [[NSMutableArray alloc] init];
srandom((int)time(NULL));
NSNumber *randomNumber;
for (int i = 0 ; i < 10000 ; i++)
{
randomNumber = [[NSNumber alloc] initWithInt:random()];
[_totalPopulation addObject:randomNumber];
NSLog(#"%#", randomNumber);
}
}
-(void)createGaussianPopulation
{
for (int i = 0; i < 5000 ; i++)
{
double x1, x2, w, y1, y2;
do
{
x1 = 2.0 * ((double)arc4random() / ARC4RANDOM_MAX) - 1.0;
x2 = 2.0 * ((double)arc4random() / ARC4RANDOM_MAX) - 1.0;
w = x1 * x1 + x2 * x2;
} while (w >= 1.0);
w = sqrt((-2.0 * log(w))/w);
y1 = x1 * w;
y2 = x2 * w;
NSNumber *value1 = [NSNumber numberWithDouble:y1];
NSNumber *value2 = [NSNumber numberWithDouble:y2];
[self.gaussianPopulation addObject:value1];
[self.gaussianPopulation addObject:value2];
//NSLog(#"%# %#", value1, value2);
NSString *pathToDesktop = [NSString stringWithFormat:#"/Users/%#/Desktop", NSUserName()];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/testfile.tst", pathToDesktop];
//create content
NSString *content = [NSString stringWithFormat:#"%#\n%# \n", [value1 stringValue], [value2 stringValue]];
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:fileName];
[myHandle seekToEndOfFile];
[myHandle writeData:[content dataUsingEncoding:NSUTF8StringEncoding]];
}
}
-(double)calculateAndersonDarling
{
NSLog((#"in method calculateAndersonDarling"));
NSLog(#"%i", [self.gaussianPopulation count]);
for (id eachObject in self.gaussianPopulation)
{
NSLog(#"%#", eachObject);
}
NSArray *sortedData = [NSArray arrayWithArray:[self.gaussianPopulation sortedArrayUsingSelector:#selector(compare:)]];
//NSArray *sortedData = [self.gaussianPopulation sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"%i", [sortedData count]);
for (id eachObject in sortedData)
{
NSLog(#"%#", eachObject);
}
return 0.0; //return value to be done later
}
#end
As you can see (where the commented line is) I have tried different approaches.
But it seems like the sortedData array remains empty.
The size via NSLog is reported as zero and there is no output for the contents.
Any help would be appreciated.
just in case:
#import <Foundation/Foundation.h>
#import "Population.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
Population *myPopulation;
myPopulation = [[Population alloc] init];
[myPopulation createGaussianPopulation];
[myPopulation calculateAndersonDarling];
}
return 0;
}
NSLog output:
2014-09-12 16:46:44.647 Statistik[4158:303] Hello, World!
2014-09-12 16:46:45.154 Statistik[4158:303] in method calculateAndersonDarling
2014-09-12 16:46:45.154 Statistik[4158:303] 0
2014-09-12 16:46:45.155 Statistik[4158:303] 0
Program ended with exit code: 0
clearly the Array gaussianPopulation is already empty in the method calculateAndersonDarling, or is my calculation of the array size wrong?
But why should it have lost its contents???
You forgot to allocate the gaussianPopulation array before adding elements to it. In Objective-C you can call methods on nil objects, it won't have any effect (no crash, no warning). That's why it's sometimes difficult to see these bugs. Just initialize the array at the beginning of the method:
- (void)createGaussianPopulation
{
self.gaussianPopulation = [NSMutableArray array];
...

Why does NSMutablearray keep returning null?

I am generating a random equation say like 2*3+4..... and using DDMathparser to evaluate it. Here I have a class method which is supposed to return a random equation(stored inside a mutable array) only if it evaluates to a integer.
however it keeps returning Null and i can't figure out why. Please help me out.!
#import "Equation.h"
#import "DDMathParser.h"
#implementation Equation
-(NSMutableArray*)randEquation{
NSMutableArray* usableEquation=[[NSMutableArray alloc]init];
while(1){
NSArray *nums = #[#"1", #"2", #"3", #"4", #"5",#"6",#"7",#"8",#"9"];
unsigned index1=arc4random()%9;
NSString* num = [NSString stringWithFormat:#"%#", [nums objectAtIndex:index1]];
NSArray *symbols = #[#"+", #"-", #"*", #"/"];
unsigned index=arc4random()%4;
NSString* symb = [NSString stringWithFormat:#"%#", [symbols objectAtIndex:index]];
NSMutableArray *arrayOfSymbolsAndNumbers = [[NSMutableArray alloc] init];
for( int i=0;i<=10;i++){
if (i%2==0) {
[arrayOfSymbolsAndNumbers addObject:num];
}
else{
[arrayOfSymbolsAndNumbers addObject:symb];
}
}
NSMutableString *stringOfSymbolsAndNumbers=[[NSMutableString alloc]init];
for (NSObject * obj in arrayOfSymbolsAndNumbers)
{
[stringOfSymbolsAndNumbers appendString:[obj description]];
}
usableEquation=arrayOfSymbolsAndNumbers;
NSNumber *result=[stringOfSymbolsAndNumbers numberByEvaluatingString];
float resultFloat = [result floatValue];
float checker=resultFloat;
if (floor(checker)==checker) {
break;
}
else{
continue;
}
}
return usableEquation;
}
#end
NSLog(#"The content of array is%#",[equation randEquation]);
Based on your code, for this log to output The content of array is(null) means that equation is nil. Your randEquation (while not efficient) looks ok, the problem is that you haven't created the equation instance when you run the log statement.

Self and arrays problems

I am new to Objective C and I'm having trouble getting my head around a few things.
I am trying to make a big integer program, from which I read items entered in a string and put them into an individual elements in the array.
I am currently working on an add method which adds elements from both the arrays together to make a big number stored in a final array.
But I'm kind of confused about to get this array I made from the initWithString method into the array method. I have some understanding of self, but I don't really know how to use it in this sense.
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
NSMutableArray *intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
-(MPInteger *) add: (MPInteger *) x
{
//NSMutableArray *arr1 = [NSMutableArray arrayWithCapacity:100];
//NSMutableArray *arr2 = [NSMutableArray arrayWithCapacity:100];
//for (int i=0; i < 100; i++) {
//int r = arc4random_uniform(1000);
//NSNumber *n = [NSNumber numberWithInteger:r];
//[arr1 addObject:n];
//[arr2 addObject:n];
// }
self.array = [NSMutableArray initialize];
return x;
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
MPInteger *x = [[MPInteger alloc] initWithString:#"123456789"];
MPInteger *y = [[MPInteger alloc] initWithString:#"123456789"];
[x add: y];
}
}
So I want too add the x and y arrays, but I'm not sure how to get the arrays in the add method. Do I use self to represent one of the arrays and initialise it, and x to represent the other. I don't know if I'm going about it completely the wrong way. Some help to understand would be greatly appreciated.
When referring to self you're actually accessing the current instance of the class. In other languages this may be implemented as this instead. There are a couple ways of designing the approach you're going for but the simplest pattern is probably composition:
#interface MPInteger
{
NSMutableArray *digits;
}
#end
----------------------------------------------------------------------------
#implementation MPInteger
-(id) initWithString: (NSString *) x
{
// Create a new instance of this class (MPInteger) with a default
// constructor and assign it to the current instance (self).
self = [super init];
if (self) {
// Previously we initialized a string, but then threw it out!
// Instead, let's save it to our string representation:
self->digits = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[self->digits addObject:ch];
}
return self;
}
// Depending on how you want to implement this function, it could return
// a new MPInteger class or update the current instance (self):
-(MPInteger *) add: (MPInteger *) x
{
NSArray *a = self->digits;
NSArray *b = x->digits;
// Have both strings for A + B, so use them to find C:
NSArray *c = ????;
// Return a new instance of MPInteger with the result:
return [ [ MPInteger alloc ] initWithString:c ];
}
#end
Notice that now the MPInteger class has an instance of an NSString object that will exist during the entire lifetime of the MPInteger object. To update/access this string, all you need to do is say:
self->digits

Array of floating point values in Objective-C

How can I create array of floating point numbers in Objective-C?
Is it possible?
You can create a dynamic array (size decided at runtime, not compile time) in different ways, depending on the language you wish to use:
Objective-C
NSArray *array = [[NSArray alloc] initWithObjects:
[NSNumber numberWithFloat:1.0f],
[NSNumber numberWithFloat:2.0f],
[NSNumber numberWithFloat:3.0f],
nil];
...
[array release]; // If you aren't using ARC
or, if you want to change it after creating it, use an NSMutableArray:
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:0];
[array addObject:[NSNumber numberWithFloat:1.0f]];
[array addObject:[NSNumber numberWithFloat:2.0f]];
[array addObject:[NSNumber numberWithFloat:3.0f]];
...
[array replaceObjectAtIndex:1 withObject:[NSNumber numberWithFloat:99.9f]];
...
[array release]; // If you aren't using ARC
Or using the new-ish Objective-C literals syntax:
NSArray *array = #[ #1.0f, #2.0f, #3.0f ];
...
[array release]; // If you aren't using ARC
C
float *array = (float *)malloc(sizeof(float) * 3);
array[0] = 1.0f;
array[1] = 2.0f;
array[2] = 3.0f;
...
free(array);
C++ / Objective-C++
std::vector<float> array;
array[0] = 1.0f;
array[1] = 2.0f;
array[2] = 3.0f;
For an dynamic approach you can use NSNumber object and add it to NSMutableArray, or if you need only static array then use suggestions from comments, or use standard C.
like:
NSMutableArray *yourArray = [NSMutableArray array];
float yourFloat = 5.55;
NSNumber *yourFloatNumber = [NSNumer numberWithFloat:yourFloat];
[yourArray addObject:yourFloatNumber];
and then to retrive:
NSNumber *yourFloatNumber = [yourArray objectAtIndex:0]
float yourFloat = [yourFloatNumber floatValue];
If you are using Xcode 4.4+, you can try this:
NSArray *a = #[ #1.1f, #2.2f, #3.3f];
Here is all new literals of LLVM Compiler 4.0.
How about something like this?
#interface DoubleArray : NSObject
#property(readonly, nonatomic) NSUInteger count;
#property(readonly, nonatomic) double *buffer;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithCount:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (double)valueAtIndex:(NSUInteger)idx;
- (void)setValue:(double)value atIndex:(NSUInteger)idx;
#end
#implementation DoubleArray
- (void)dealloc
{
if (_buffer != 0) {
free(_buffer);
}
}
- (instancetype)initWithCount:(NSUInteger)count
{
self = [super init];
if (self) {
_count = count;
_buffer = calloc(rows * columns, sizeof(double));
}
return self;
}
- (double)valueAtIndex:(NSUInteger)idx
{
return *(_buffer + idx);
}
- (void)setValue:(double)value atIndex:(NSUInteger)idx
{
*(_buffer + idx) = value;
}
#end
It's a basic array. You can extend this with more complex features like appending, indexed removal etc.

Can't withdraw CGPoint Values from A mutableArray of NSValue

I made an NSMUtableArray of CGpoints and I stored them by subclassing as NSValue, but I cant get the values out. here I what I did.
CGPoint graphPoint;
NSMutableArray *pointValues = [[NSMutableArray alloc] init];
for( int x =0;x<5; x++)
{
NSDictionary* xValue = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:x] forKey:#"X"];
graphPoint.x =x;
graphPoint.y = [CalculatorBrain runProgram: self.graphingPoint usingVariableValues:xValue];
[pointValues addObject:[NSValue valueWithCGPoint:graphPoint]];
}
I tried using this to get the values but I just get null back
for( int x=0; x<5; x++) {
NSValue *val = [pointValues objectAtIndex:x];
CGPoint point = [val CGpointValue];
NSLog(#"Points = %#", point);
}
You can't print a CGPoint using the %# format specifier, as it is not an object. Instead, use NSStringFromCGPoint():
NSLog(#"%#", NSStringFromCGPoint(myPoint));