I am very confused by this Out of Scope problem I keep receiving. For some reason any time I try to add an object to the array it's data isn't stored. This problem when I use the function fireCanonBall. I tried storing objects in the array 2 different ways with the same data, the first way local to the method and released at the end of the method. The second way public with accessors in the class. For some reason when I try to create a ball object using the former the object wont properly create. But the later will properly create the object. If I dont use the array during the update the program will run fine, but when I try to use the array it will still run without errors, just the canon will not shoot the canon ball. Also, initObject from the canonBall class is basically the same as here in the canon class. Any ideas about why it is not storing the canon ball objects would be appreciated.
// .h
Code:
#import <OpenGLES/ES1/gl.h>
#import "3DObject.h"
#import "Canonball.h"
@interface Canon : NSObject
{
Object3D canonObject; //contains rot, pos, deg, and scale.
Object3D ballObject; //contains rot,pos,scale for canon ball object;
NSMutableArray *canonBalls;
Canonball *curball;
Vector3D vel; //different cannons might be able to shoot cannon balls faster, or slower.
float gravity;
}
-(void) update: (float) dt;
-(id) initObject: (Object3D)O ballObject:(Object3D)B gravity:(float)g vel:(Vector3D)v;
-(void) fireCanonBall;
//dont understand @property. nonatomic means not multithreaded, and atomic is vice versa.
@property (nonatomic,retain) Canonball *curball;
@property (nonatomic,retain) NSMutableArray *canonBalls;
@property Object3D canonObject;
@property Object3D ballObject;
@property Vector3D vel;
@property float gravity;
@end
// .m
Code:
#import "Canon.h"
@implementation Canon
@synthesize curball;
@synthesize canonObject;
@synthesize canonBalls;
@synthesize gravity;
@synthesize vel;
@synthesize ballObject;
-(id) initObject: (Object3D)O ballObject:(Object3D)B gravity:(float)g vel:(Vector3D)v
{
self = [super init];
if (self)
{
canonObject = O;
ballObject = B;
gravity = g;
vel = v;
canonBalls = [[NSMutableArray alloc]init];
}
return self;
}
-(void) dealloc
{
[curball release];
[canonBalls release];
[super dealloc];
}
-(void) update: (float) dt
{
//update cannon and any launched cannon balls
//[curball setBallObject:ballObject];
//[curball update: dt];
//ballObject = curball.ballObject;
.
for(canonball *obj in canonBalls)
{
[obj update: dt];
[obj setBallObject:ballObject];
ballObject = obj.ballObject;
}
}
-(void) fireCanonBall
{
//first way I tried to add object
Canonball *tmpBall = [[Canonball alloc]initObject:ballObject gravity:gravity initVel:vel];
[canonBalls addObject:tmpBall];
//second way I tried to add object not using my custom init.
curball = [[Canonball alloc]init];
[curball setBallObject:ballObject];
[curball setGravity:gravity];
[curball setInitVel:vel];
[canonBalls addObject:curball];
[tmpBall release];
//create Canonball]
//give it data
}
@end
Try this before and after adding the cannonball to the array:
Code:
NSLog(@"canonBalls: %@",canonBalls);
That'll let you know how many cannonballs you have, and whether that methods is really being run. Also add a similar line in the cannon update: method.
Code:
NSLog(@"canonBalls in update: %@",canonBalls);
If any of those read 0x0 (nil) then you are probably not calling your [cannon initObject: BallObject: gravity: vel:] method. If you just call [[cannon alloc] init] then the array woulds still be nil and you'd be unable to store anything in it.
If you get some other result then something else is going on; let me know what the logs say.
PS if you capitalize your class names and lower-case your variable names it'll make it easier for others to scan your code quickly. Right-click a class or variable and choose "Refactor" to rename it everywhere in the program.
PS if you capitalize your class names and lower-case your variable names it'll make it easier for others to scan your code quickly. Right-click a class or variable and choose "Refactor" to rename it everywhere in the program.
Thanks for the tip, didnt know I could do that.
Here is the output from the logs. Also, here is a code sample of where I am creating the canon object.
Okay, it sure looks like the cannonballs are getting added to the array. So what's the problem again?
If they're not moving I'd check the Canonball update method.
When I run through debug and check immediately whats in the array it shows the 2 objects in the array are out of scope. If I check the array during the update it shows the 2 objects are out of scope. When I run the program using the array the cannon wont fire the canon balls. But whenever I dont use the array and just use the pointer" Canonball *curball during the update the canon fires the canon balls perfectly and the canonball does its trajectory perfectly. I really dont get why its not working...
When I run through debug and check immediately whats in the array it shows the 2 objects in the array are out of scope. If I check the array during the update it shows the 2 objects are out of scope.
Quote:
Sounds like an issue with the debugger; I don't think it's related to your trouble though.
When I run the program using the array the cannon wont fire the canon balls. But whenever I dont use the array and just use the pointer" Canonball *curball during the update the canon fires the canon balls perfectly and the canonball does its trajectory perfectly. I really dont get why its not working...
Do you mean this code works:
Code:
//update cannon and any launched cannon balls
[curball setBallObject:ballObject];
[curball update: dt];
ballObject = curball.ballObject;
You swapped the order of update and setBallObject there. I assume the problem is inside one of those methods. The code you posted looks OK, although it's hard to tell what it's supposed to do. What do those two methods do? Why do you set ballObject = obj.ballObject and not use the value?
You swapped the order of update and setBallObject there. I assume the problem is inside one of those methods. The code you posted looks OK, although it's hard to tell what it's supposed to do. What do those two methods do? Why do you set ballObject = obj.ballObject and not use the value?
Wow... I didnt even look at that because when I would go in debug it would say everything in the array was out of scope so I was convinced it was a memory problem of some sort. But by making the switch you noticed above that fixed the problem. Basically the ball was never updating because I was never setting its new data before updating...