Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

peacetrain67

macrumors member
Original poster
Dec 20, 2007
68
0
Here is my situation:
I have followed a simple guide from the book 'Beginning iPhone Development' but would like to tweak one major aspect (I have tweaked a few things: adding a 'response' when the sprite hits the wall instead of just stopping the velocity, sped up the sprite, etc. = basic tweaks). What I want to do is use the sprite's animation (based off the accelerometer's orienation) on top of another ImageView that will be playng an animation in the background. The way the code is currently set up just loads everything without any user interaction. I would like the sprite, etc. to only show up after an action is called. Preferably, I would like to keep all the code within the same class as well, making the exit simpler as well. Thanks in advance: here is my current code:
BallViewController.h
Code:
#define kUpdateInterval (1.0f/60.0f)
#import <UIKit/UIKit.h>

@interface BallViewController : UIViewController <UIAccelerometerDelegate> {
}
@end
BallViewController.m
Code:
#import "BallViewController.h"
#import "BallView.h"

@implementation BallViewController

- (void)viewDidLoad {
	UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
	accelerometer.delegate = self;
	accelerometer.updateInterval = kUpdateInterval;
    [super viewDidLoad];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}
#pragma mark -
- (void)accelerometer:(UIAccelerometer *)accelerometer
		didAccelerate:(UIAcceleration *)acceleration {
	[(BallView *)self.view setAcceleration:acceleration];
	[(BallView *)self.view draw];
}

@end
BallView.h
Code:
#define kVelocityMultiplier 1000
#import <UIKit/UIKit.h>


@interface BallView : UIView {
	UIImage *image;
	CGPoint currentPoint;
	CGPoint previousPoint;
	
	UIAcceleration *acceleration;
	CGFloat ballXVelocity;
	CGFloat ballYVelocity;
}
@property (nonatomic, retain) UIImage *image;
@property CGPoint currentPoint;
@property CGPoint previousPoint;
@property (nonatomic, retain) UIAcceleration *acceleration;
@property CGFloat ballXVelocity;
@property CGFloat ballYVelocity;

-(void)draw;
@end
BallView.m
Code:
#import "BallView.h"

@implementation BallView

@synthesize image;
@synthesize currentPoint;
@synthesize previousPoint;
@synthesize acceleration;
@synthesize ballXVelocity;
@synthesize ballYVelocity;

-(id)initWithCoder:(NSCoder *)coder {
	if (self = [super initWithCoder:coder]) {
		self.image = [UIImage imageNamed:@"TealBall.png"];
		self.currentPoint = CGPointMake((self.bounds.size.width / 2.0f) + (image.size.width /2.0f), (self.bounds.size.height / 2.0f) + (image.size.height / 2.0f));
		
		ballXVelocity = 0.0f;
		ballYVelocity = 0.0f;
	}
	return self;
}

-(id)initWithFrame:(CGRect)frame {
	if (self = [super initWithFrame:frame]) {
		//Initialization code
	}
	return self;
}

-(void)drawRect:(CGRect)rect {
	[image drawAtPoint:currentPoint];
}

-(CGPoint)currentPoint {
	return currentPoint;
}
-(void)setCurrentPoint:(CGPoint)newPoint {
	previousPoint = currentPoint;
	currentPoint = newPoint;
	
	if (currentPoint.x < 0) {
		currentPoint.x = 0;
		ballXVelocity = - (ballXVelocity *.75);
	}
	if (currentPoint. y < 0) {
		currentPoint.y = 0;
		ballYVelocity = - (ballYVelocity *.75);
	}
	if (currentPoint.x > self.bounds.size.width - image.size.width) {
		currentPoint.x = self.bounds.size.width - image.size.width;
		ballXVelocity = - (ballXVelocity *.75);
	}
	if (currentPoint.y > self.bounds.size.height - image.size.height) {
		currentPoint.y = self.bounds.size.height - image.size.height;
		ballYVelocity = - (ballYVelocity *.75);
	}
	CGRect currentImageRect = CGRectMake(currentPoint.x, currentPoint.y, currentPoint.x + image.size.width, currentPoint.y + image.size.height);
	CGRect previousImageRect = CGRectMake(previousPoint.x, previousPoint.y, previousPoint.x + image.size.width, currentPoint.y + image.size.width);
	[self setNeedsDisplayInRect:CGRectUnion(currentImageRect, previousImageRect)];
}

-(void)draw {
	static NSDate *lastDrawTime;
	if (lastDrawTime != nil) {
		NSTimeInterval secondsSinceLastDraw = 
		-([lastDrawTime timeIntervalSinceNow]);
		
		ballYVelocity = ballYVelocity + -(acceleration.y * secondsSinceLastDraw);
		ballXVelocity = ballXVelocity + acceleration.x * secondsSinceLastDraw;
		
		CGFloat xAcceleration = secondsSinceLastDraw *ballXVelocity * 1000;
		CGFloat yAcceleration = secondsSinceLastDraw *ballYVelocity * 1000;
		
		self.currentPoint = CGPointMake(self.currentPoint.x + xAcceleration, self.currentPoint.y +yAcceleration);
	}
	[lastDrawTime release];
	lastDrawTime = [[NSDate alloc] init];
}

- (void)dealloc {
	[image release];
	[acceleration release];
    [super dealloc];
}

@end
*All this code works on it's own, but I want to use it on top of a imageView within the first class (that code isn't included). I have all that stuff figured out easily and pretty much understand this code, but the pragma mark is tripping me up a little bit, as well as some of the calls from the first class. Once again, thanks in advance.
 

Kingbombs

macrumors member
Jun 24, 2009
98
0
but the pragma mark is tripping me up a little bit

Pragma mark isn't anything really code related
When you click to view all your methods in that class it just puts a line there or says a title (it allows a class with lots of methods to be split up into sections so you can easily work out what each set of methods do in the program)
 

peacetrain67

macrumors member
Original poster
Dec 20, 2007
68
0
Pragma mark isn't anything really code related
When you click to view all your methods in that class it just puts a line there or says a title (it allows a class with lots of methods to be split up into sections so you can easily work out what each set of methods do in the program)

ya i just red into that a little more and realized that. I will look more into that later because the class I have does have a lot of methods (it's well over 2000 lines of code and will probably finish around 3000 lines of code). that was a dead end for how to make this work for me tho. I would be fine with calling the other class if I could tell be specific when to call. using a simple example:
Code:
//calls the imageview and the photos i am using
myimageview.animationImages = [NSArray arrayWithObjects:
	[UIImage imageNamed: @"MyBackground1.png"],
	[UIImage imageNamed: @"MyBackground2.png"],
	[UIImage imageNamed: @"MyBackground3.png"],
	[UIImage imageNamed: @"MyBackground4.png"],
	[UIImage imageNamed: @"MyBackground5.png"], nil];
//sets the basic prefs for the imageview: repeatcount and duration
	[myimageview setAnimationRepeatCount:0];
	myimageview.animationDuration = 1;
//starts the animation
	myimageview startAnimating];
//starts an animation to load the view that has the imageview
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
	[UIView setAnimationDuration:.7];
//loading the view which contains the imageview
	imageviewcontainer.alpha = 1;
	[UIView commitAnimations];
what else would i need to add to call the ballview - in the code i showed earlier it is called from the viewDidLoad
Code:
	UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
	accelerometer.delegate = self;
	accelerometer.updateInterval = kUpdateInterval;
    [super viewDidLoad];
im going to throw that in my method (with the animation) and see what i can do... anybody else know how to handle this to shorten this XCode adventure...
 

peacetrain67

macrumors member
Original poster
Dec 20, 2007
68
0
Ive spent 2 days on this, posted to 2 threads, and I think I am close. I feel like I am close...
*This is not my actual code, it skims out parts that are not needed to save you time... Everything involving the accelerometer is included, though...
Here is where I am currently:
BasicViewController.m
Code:
-(IBAction)startimageview:(id)sender
{
	NSLog(@"startimageview called");
	//identifies the imageview and the images for it's animation
	imageview.animationImages = [NSArray arrayWithObjects:
	[UIImage imageNamed: @"MyBackground1.png"],
	[UIImage imageNamed: @"MyBackground2.png"],
	[UIImage imageNamed: @"MyBackground3.png"],
	[UIImage imageNamed: @"MyBackground4.png"],
	[UIImage imageNamed: @"MyBackground5.png"], nil];
	//identifies the imageview repeatcount and duration
	[imageview setAnimationRepeatCount:0];
	imageview.animationDuration = 1;
	//starts the imageview animation
	[imageview startAnimating];
	//identifies the fading transition of the view with the imageview
	[UIView beginAnimations:nil context:nil];
	[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
	[UIView setAnimationDuration:.7];
	imageviewcontainer.alpha = 1;
	//starts that fading transition i just mentioned
	[UIView commitAnimations];
	//bunch of uninvolved code including a timer, another ball, etc.
	NSLog(@"Accelerometer-Ball Called");
	//accelerometer-calling code
	UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
	accelerometer.delegate = self;
	accelerometer.updateInterval = kUpdateInterval;
}
//1 gazillion more methods...
- (void)accelerometer:(UIAccelerometer *)accelerometer
		didAccelerate:(UIAcceleration *)acceleration {
	//didAccelerate being called... [U][B][I]APP CRASHES HERE![/I][/B][/U]
	NSLog(@"DidAccelerate Called");
	[(AccelBall *)self.view setAcceleration:acceleration];
	[(AccelBall *)self.view draw];
}
the app crashes where i implied that it crashed... now for the AccelBall code
AccelBall.h
Code:
@interface AccelBall : UIView {
	UIImage *BALLimage;
	CGPoint BALLcurrentpoint;
	CGPoint BALLpastpoint;	
	UIAcceleration *acceleration;
	CGFloat BALLxvelocity;
	CGFloat BALLyvelocity;
}
@property (nonatomic, retain) UIImage *BALLimage;
@property CGPoint BALLcurrentpoint;
@property CGPoint BALLpastpoint;
@property (nonatomic, retain) UIAcceleration *acceleration;
@property CGFloat BALLxvelocity;
@property CGFloat BALLyvelocity;

-(void)draw;
@end
AccelBall.m
Code:
#import "AccelBall.h"

@implementation AccelBall

@synthesize BALLimage;
@synthesize BALLcurrentpoint;
@synthesize BALLpastpoint;
@synthesize acceleration;
@synthesize BALLxvelocity;
@synthesize BALLyvelocity;

-(id)initWithCoder:(NSCoder *)coder {
	//Never reaches here
	NSLog(@"initWithCoder: coder");
	//If anybody could elaborate on initWithCoder for me, that would be appreciated
	if (self = [super initWithCoder:coder]) {
	//Identifies my image "RedBall" as the BALLimage
		self.BALLimage = [UIImage imageNamed:@"RedBall.png"];
	//sets the current/starting point for the BALLimage
		self.BALLcurrentpoint = CGPointMake((self.bounds.size.width / 2.0f) + (BALLimage.size.width / 2.0f),
											(self.bounds.size.height / 2.0f) + (BALLimage.size.height / 2.0f));
	//Sets the (0) velocity for the BALLimage
		BALLxvelocity = 0.0f;
		BALLyvelocity = 0.0f;
	}
	return self;
}
- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // Initialization code
    }
    return self;
}
- (void)drawRect:(CGRect)rect {
    [BALLimage drawAtPoint:BALLcurrentpoint];
}
-(CGPoint)BALLcurrentpoint {
	return BALLcurrentpoint;
}
-(void)setBALLcurrentpoint:(CGPoint)BALLnewpoint {
	//Changing the pastpoint to the currentpoint, newpoint to the currentpoint
	BALLpastpoint = BALLcurrentpoint;
	BALLcurrentpoint = BALLnewpoint;
	//Sets up walls and wall response (bouncing off of the wall)
	if (BALLcurrentpoint.x < 0) {
		BALLcurrentpoint.x = 0;
		BALLxvelocity = - (BALLxvelocity *.7);
	}
	if (BALLcurrentpoint.y < 0) {
		BALLcurrentpoint.y = 0;
		BALLyvelocity = - (BALLyvelocity *.7);
	}
	if (BALLcurrentpoint.x > self.bounds.size.width - BALLimage.size.width) {
		BALLcurrentpoint.x = self.bounds.size.width - BALLimage.size.width;
		BALLxvelocity = - (BALLxvelocity *.7);
	}
	if (BALLcurrentpoint.y > self.bounds.size.height - BALLimage.size.height) {
		BALLcurrentpoint.y = self.bounds.size.height - BALLimage.size.height;
		BALLyvelocity = - (BALLyvelocity *.7);
	}
	//Not sure exactly what this does? Creates a new position for the ball possibly?
	CGRect currentImageRect = CGRectMake(BALLcurrentpoint.x, BALLcurrentpoint.y, BALLcurrentpoint.x + BALLimage.size.width, BALLcurrentpoint.y + BALLimage.size.height);
	CGRect pastImageRect = CGRectMake(BALLpastpoint.x, BALLpastpoint.y, BALLpastpoint.x + BALLimage.size.width, BALLpastpoint.y + BALLimage.size.height);
	[self setNeedsDisplayInRect:CGRectUnion(currentImageRect, pastImageRect)];
}
-(void)draw {
	//Updating based off the last time the image was updated
	static NSDate *lastdrawtime;
	if (lastdrawtime != nil) {
		NSTimeInterval secondssincelastdraw =
		-([lastdrawtime timeIntervalSinceNow]);
	//Setting speed (velocity)				
		BALLyvelocity = BALLyvelocity + -(acceleration.y * secondssincelastdraw);
		BALLxvelocity = BALLxvelocity + acceleration.x * secondssincelastdraw;		
		CGFloat xAcceleration = secondssincelastdraw *BALLxvelocity *1000;
		CGFloat yAcceleration = secondssincelastdraw *BALLyvelocity *1000;		
		self.BALLcurrentpoint = CGPointMake(self.BALLcurrentpoint.x + xAcceleration, self.BALLcurrentpoint.y + yAcceleration);
	}
	//Releasing and refreshing the lastdrawtime from this method
	[lastdrawtime release];
	lastdrawtime = [[NSDate alloc] init];
}

- (void)dealloc {
	//Releasing the BallImage and acceleration
	[BALLimage release];
	[acceleration release];
    [super dealloc];
}

@end

so, why is it crashing (look at the first class's code to see where it crashes...)
*also would appreciate elabarotation on the few parts of the code I didn't fully grasp... That could help me find another way to do all this (specifically initWithCoder.. I could only find info on MAC OS when I searched for info on this - i had never previously seen it).
If this helps:

The Debugger Console Error:
2009-08-31 01:00:49.681 BasicPractice[3193:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIView setAcceleration:]: unrecognized selector sent to instance 0x1361d0'
2009-08-31 01:00:49.694 BasicPractice[3193:207] Stack: (
807990621,
805385689,
807994435,
807497337,
807460528,
17799,
816345951,
814892499,
814888245,
814887267,
839146061,
807743553,
807741297,
839142159,
839142331,
814678883,
814674209,
10469,
10332
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
kill
quit
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.