How can I test if the scroll view is bouncing? - iphone

How can I test if the scroll view is bouncing? Is there a notification or something when the bounce ends?

Here is how I detected if the scroll view is bouncing horizontally:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.x < 0) {
NSLog(#"bouncing left");
}
if (scrollView.contentOffset.x > (scrollView.contentSize.width - scrollView.frame.size.width)) {
NSLog(#"bouncing right");
}
}

I've implemented extension for UIScrollView to handle this for vertical and horizontal scrolling. This will work even with non-zero contentInsets and in case when content is not big enough for covering scrollView insets:
Objective-C
#interface UIScrollView (Bouncing)
#property (nonatomic, readonly) BOOL isBouncing;
#property (nonatomic, readonly) BOOL isBouncingTop;
#property (nonatomic, readonly) BOOL isBouncingLeft;
#property (nonatomic, readonly) BOOL isBouncingBottom;
#property (nonatomic, readonly) BOOL isBouncingRight;
#end
#implementation UIScrollView (Bouncing)
- (BOOL)isBouncing
{
return self.isBouncingTop || self.isBouncingLeft || self.isBouncingBottom || self.isBouncingRight;
}
- (BOOL)isBouncingTop
{
return self.contentOffset.y < - self.contentInset.top;
}
- (BOOL)isBouncingLeft
{
return self.contentOffset.x < - self.contentInset.left;
}
- (BOOL)isBouncingBottom
{
BOOL contentFillsScrollEdges = self.contentSize.height + self.contentInset.top + self.contentInset.bottom >= CGRectGetHeight(self.bounds);
return contentFillsScrollEdges && self.contentOffset.y > self.contentSize.height - CGRectGetHeight(self.bounds) + self.contentInset.bottom;
}
- (BOOL)isBouncingRight
{
BOOL contentFillsScrollEdges = self.contentSize.width + self.contentInset.left + self.contentInset.right >= CGRectGetWidth(self.bounds);
return contentFillsScrollEdges && self.contentOffset.x > self.contentSize.width - CGRectGetWidth(self.bounds) + self.contentInset.right;
}
#end
Swift 3.0+
extension UIScrollView {
var isBouncing: Bool {
return isBouncingTop || isBouncingLeft || isBouncingBottom || isBouncingRight
}
var isBouncingTop: Bool {
return contentOffset.y < -contentInset.top
}
var isBouncingLeft: Bool {
return contentOffset.x < -contentInset.left
}
var isBouncingBottom: Bool {
let contentFillsScrollEdges = contentSize.height + contentInset.top + contentInset.bottom >= bounds.height
return contentFillsScrollEdges && contentOffset.y > contentSize.height - bounds.height + contentInset.bottom
}
var isBouncingRight: Bool {
let contentFillsScrollEdges = contentSize.width + contentInset.left + contentInset.right >= bounds.width
return contentFillsScrollEdges && contentOffset.x > contentSize.width - bounds.width + contentInset.right
}
}
For RxSwift you can just map scrollViewDidScroll with isBouncing and filter with distinctUntilChanged.

A minor amendment to Justin's method, allowing for contentInset:
if( scrollView.contentOffset.x < -scrollView.contentInset.left )
{
NSLog( #"bounce left" );
}
if( scrollView.contentOffset.x > scrollView.contentSize.width - scrollView.frame.size.width + scrollView.contentInset.right )
{
NSLog( #"bounce right" );
}

Yes... check out the UIScrollViewDelegate spec, implement the methods including the two below, and set your UIScrollView's delegate accordingly:
// User stops dragging the table view.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
willDecelerate:(BOOL)decelerate;
// Control slows to a halt after the user drags it
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
You will probably be most interested in scrollViewDidEndDecelerating. These also work in UITableView which is where I originally found them (UITableView inherits from UIScrollView).

Old question but I just ran into a similar issue and wanted to add that it is a good idea to also check that the scroll views content is larger than the scroll view's frame:
+ (BOOL) isScrollViewBouncing:(UIScrollView *)scrollView
{
return scrollView.contentOffset.y > scrollView.contentSize.height - scrollView.frame.size.height
&& scrollView.contentSize.height > scrollView.frame.size.height;
}
This now makes sure the scroll view is large enough to be in a scroll-bouncing state, so that if the scroll view is small it does NOT always evaluate to true.
Cheers

For those of you who would be able to "bounce" downwards in a scrollview in order to update contents of the view. (And the event is only fired once.)
- (void)scrollViewDidEndDragging:(UIScrollView *)aScrollView
willDecelerate:(BOOL)decelerate{
CGPoint offset = aScrollView.contentOffset;
CGRect bounds = aScrollView.bounds;
CGSize size = aScrollView.contentSize;
UIEdgeInsets inset = aScrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
//Distance in points before update-event occur
float reload_distance = 50;
//
if(y > h + reload_distance) {
NSLog(#"load more rows");
}
}

Using Glavid's answer, I added bouncing to bottom also, and added as a category
#import "UIScrollView+Additions.h"
#implementation UIScrollView (Additions)
- (BOOL)isBouncing
{
BOOL isBouncingBottom = self.contentOffset.y >= self.contentSize.height - self.frame.size.height
&& self.contentSize.height >= self.frame.size.height;
BOOL isBouncingTop = self.contentOffset.y <= 0;
BOOL isBouncing = isBouncingBottom || isBouncingTop;
return isBouncing;
}
#end

Related

cut a sprite sheet on cocos2d for animation

I want to cut a sprite in 6 equivalent parts just with one image, a .png file which I found on the web, no with texturepacker, (the image below by example)
I can take other way, but I want to know if I can do that. any one haves idea?
I'll revise my answer if this isn't what you were asking about, but I think you are asking how to 'manually run an animation' using a spritesheet without a plist.
Here's one way. It would be better if you encapsulated this into it's own class, but this can push you in the right direction I think:
ManualAnimationTest.h
#interface ManualAnimationTest : CCLayer
{
CCSprite *animatedSprite;
int x,y;
float animatedSpriteWidth, animatedSpriteHeight;
int animatedSpriteColumns, animatedSpriteRows;
}
#end
ManualAnimationTest.m
#import "ManualAnimationTest.h"
#implementation ManualAnimationTest
-(id) init
{
if( (self=[super init]))
{
CGSize s = [CCDirector sharedDirector].winSize;
x = 0;
y = 0;
animatedSpriteColumns = 3;
animatedSpriteRows = 2;
animatedSpriteWidth = 95.0f;
animatedSpriteHeight = 125.0f;
animatedSprite = [CCSprite spriteWithFile:#"animal_animation.png" rect:CGRectMake(x * animatedSpriteWidth,y * animatedSpriteHeight,animatedSpriteWidth,animatedSpriteHeight)];
[self addChild:animatedSprite];
[animatedSprite setPosition:ccp(s.width / 2.0f, s.height / 2.0f)];
[self schedule:#selector(animateAnimatedSprite) interval:0.5f];
}
return self;
}
-(void) animateAnimatedSprite
{
[animatedSprite setTextureRect:CGRectMake(x * animatedSpriteWidth, y * animatedSpriteHeight, animatedSpriteWidth, animatedSpriteHeight)];
x +=1;
if(x > (animatedSpriteColumns - 1))
{
x = 0;
y +=1;
}
if(y > (animatedSpriteRows - 1))
{
y = 0;
}
}
#end

Can I have a UICollectionViewFlowLayout with scrollDirection different from layout direction?

The UICollectionViewFlowLayout is great, however, I want it tweaked slightly so that the scrollDirection is different from the layout direction. Examples of what I'd like is the springboard home screen or the emoji keyboards where you can swipe left/right, but the cells are laid out left to right, top to bottom (instead of top to bottom, left to right as they are with the UICollectionViewFlowLayout with scrollDirection set to horizontal). Anyone know how I can easily subclass the FlowLayout to make this change? I'm disappointed they don't have a layoutDirection in addition to scrollDirection on the UICollectionViewFlowLayout object :(
#rdelmar I implemented something similar to your solution, and that works (not as elegant as I'd like), but I noticed that occasionally items disappear from the collection unless re-drawn, which is why I didn't accept the answer. Here is what I ended up with:
#interface UICollectionViewPagedFlowLayout : UICollectionViewFlowLayout
#property int width;
#property int height;
#end
#implementation UICollectionViewPagedFlowLayout
#warning MINOR BUG: sometimes symbols disappear
- (CGSize)collectionViewContentSize {
CGSize size = [super collectionViewContentSize];
// make sure it's wide enough to cover all the objects
size.width = self.collectionView.bounds.size.width * [self.collectionView numberOfSections];
return size;
}
- (NSArray*) layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes* attributes in array) {
if (CGRectIntersectsRect(attributes.frame, rect)) {
// see which section this is in
CGRect configurableRect = UIEdgeInsetsInsetRect(visibleRect, self.sectionInset);
int horizontalIndex = attributes.indexPath.row % self.width;
int verticalIndex = attributes.indexPath.row / self.width;
double xspace = (configurableRect.size.width - self.width * self.itemSize.width) / self.width;
double yspace = (configurableRect.size.height - self.height * self.itemSize.height) / self.height;
attributes.center = CGPointMake(attributes.indexPath.section * visibleRect.size.width + self.sectionInset.left + (self.itemSize.width + xspace) * horizontalIndex + self.itemSize.width / 2, self.sectionInset.top + (self.itemSize.height + yspace) * verticalIndex + self.itemSize.height / 2);
}
}
return array;
}
#end
IIRC, exactly this is demonstrated in the WWDC 2012 sessions on UICollectionView.
I don't know about easily, depends on your definition I guess. I made a project where I had the layout that's close to what you're looking for. This lays out the rows horizontally, left to right, top to bottom. My data source was an array of arrays, where each subarray provided the data for one line.
#import "SimpleHorizontalLayout.h" // subclass of UICollectionViewFlowLayout
#define kItemSize 60
#implementation SimpleHorizontalLayout
-(CGSize)collectionViewContentSize {
NSInteger xSize = [self.collectionView numberOfItemsInSection:0] * (kItemSize + 20); // the 20 is for spacing between cells.
NSInteger ySize = [self.collectionView numberOfSections] * (kItemSize + 20);
return CGSizeMake(xSize, ySize);
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path {
UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path];
attributes.size = CGSizeMake(kItemSize,kItemSize);
NSInteger xValue = kItemSize/2 + path.row * (kItemSize +20) ;
NSInteger yValue = kItemSize + path.section * (kItemSize +20);
attributes.center = CGPointMake(xValue, yValue);
return attributes;
}
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
NSInteger minRow = (rect.origin.x > 0)? rect.origin.x/(kItemSize +20) : 0; // need to check because bounce gives negative values for x.
NSInteger maxRow = rect.size.width/(kItemSize +20) + minRow;
NSMutableArray* attributes = [NSMutableArray array];
for(NSInteger i=0 ; i < self.collectionView.numberOfSections; i++) {
for (NSInteger j=minRow ; j < maxRow; j++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:j inSection:i];
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
}
return attributes;
}
Until Apple adds a simple flag to change the layout orientation on flow layouts, I ended up sub-classing. Some of the stuff is specific to my implementation, but it might help someone else:
#interface UICollectionViewPagedFlowLayout : UICollectionViewFlowLayout
#property int width;
#property int height;
#end
#implementation UICollectionViewPagedFlowLayout
#warning MINOR BUG: sometimes items disappear
- (CGSize)collectionViewContentSize {
CGSize size = [super collectionViewContentSize];
size.width = self.collectionView.bounds.size.width * [self.collectionView numberOfSections];
return size;
}
- (NSArray*) layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes* attributes in array) {
if (CGRectIntersectsRect(attributes.frame, rect)) {
// see which section this is in
CGRect configurableRect = UIEdgeInsetsInsetRect(visibleRect, self.sectionInset);
int horizontalIndex = attributes.indexPath.row % self.width;
int verticalIndex = attributes.indexPath.row / self.width;
double xspace = (configurableRect.size.width - self.width * self.itemSize.width) / self.width;
double yspace = (configurableRect.size.height - self.height * self.itemSize.height) / self.height;
attributes.center = CGPointMake(attributes.indexPath.section * visibleRect.size.width + self.sectionInset.left + (self.itemSize.width + xspace) * horizontalIndex + self.itemSize.width / 2, self.sectionInset.top + (self.itemSize.height + yspace) * verticalIndex + self.itemSize.height / 2);
}
}
return array;
}
#end

iphone slider with constum steps

i am not really familiar with objC and looking for a solution to build a slider that slides with "steps". on moving the slider the value increases like value+=10 or maybe value+=100. how do i do that?
I modified the code above for a custom Cocos2D slider http://yannickloriot.com/library/ios/cccontrolextension/Classes/CCControlSlider.html
It has properties:
#property (nonatomic, readwrite) float value;
#property (nonatomic, readwrite) minimumValue;
#property (nonatomic, readwrite) maximumValue;
#property (nonatomic, readwrite) int steps;
the recalculation:
- (void)recalcuateValue
{
float stepValues[self.steps];
stepValues[0] = self.minimumValue;
stepValues[self.steps - 1] = self.maximumValue;
for(int i = 1; i < self.steps; i++){
stepValues[i] = i * (self.maximumValue - self.minimumValue) / (self.steps - 1);
if (self.value < stepValues[i] && self.value > stepValues[i-1]){
self.value = (self.value > (stepValues[i] - stepValues[i-1]) / 2 + stepValues[i-1])?stepValues[i]:stepValues[i-1];
}
}
}
And the ccTouchesEnded: I added if(self.steps != 0), for the case steps is set to 0, the slider could work in usual mode
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
if ([self isSelected]){
self.value = [self valueForLocation:_thumbSprite.position];
if(self.steps != 0) {
[self recalcuateValue];
[_thumbSprite setPosition:[self locationFromValue:self.value]];
}
}
self.thumbSprite.color = ccWHITE;
self.selected = NO;
}
It calls valueForLocation and locationFromValue methods:
- (float)valueForLocation:(CGPoint)location
{
float percent = location.x / _backgroundSprite.contentSize.width;
return _minimumValue + percent * (_maximumValue - _minimumValue);
}
- (CGPoint)locationFromValue:(float)value{
float percent = self.value / self.maximumValue;
return ccp(percent * _backgroundSprite.contentSize.width, _backgroundSprite.position.y);
}
So an example of usage. I needed a slider with 3 steps and values 0, 1 and 2 on each step:
self.Slider = [CCControlSlider sliderWithBackgroundFile:#"sliderTrack.png"
progressFile:#"sliderProgress.png"
thumbFile:#"sliderThumb-hd.png"]; progressFile:#"sliderProgress.png" thumbFile:#"sliderThumb-hd.png"];
self.Slider.minimumValue = 0.0f;
self.Slider.maximumValue = 2.0f;
self.Slider.steps = 3;
self.Slider.value = [[GameSettings sharedSettings] defaultAILevel];
[self.Slider addTarget:self action:#selector(onSliderValueChanged:) forControlEvents:CCControlEventValueChanged];
Hope it may be useful
I created my discrete slider this way:
#import <UIKit/UIKit.h>
#interface DiscreteSlider : UISlider {
int step;
}
#property (nonatomic) int step;
#end
which that implementation:
#import "DiscreteSlider.h"
#implementation DiscreteSlider
#synthesize step;
- (void) recalcuateStep
{
float lValue = self.value;
int lLowerValue = (int) ( lValue / self.step );
float lDifference = lValue - ( lLowerValue * step );
float lHalfStep = ((float) step) / 2;
if( lDifference < lHalfStep ) {
} else {
self.value = (float) ( lLowerValue + step );
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
- (void) touchesMoved:(NSSet *) touches
withEvent:(UIEvent *) event
{
[super touchesMoved:touches withEvent:event];
NSLog( #"DS.touchesMoved(), event: %#", event );
[self recalcuateStep];
}
- (void) endTrackingWithTouch:(UITouch *) touch
withEvent:(UIEvent *) event
{
[super endTrackingWithTouch:touch withEvent:event];
NSLog( #"DS.endTrackingWithTouch(), event: %#", event );
[self recalcuateStep];
}
- (int) step {
return ( step ? step : 1 );
}
#end

increasing and maintaing a constant speed of an object in objective C

I have posted something similar before and I got some suggestion which I have tried but I am still having problems...thus, will like to ask for any assistance on reviewing this code.
I am actually trying to get the ball object in the code to have a better or smoother animation and to increase in its speed constantly until it attains a maximum speed but right now what I am getting is the ball starting at the specified speed and then its movement becomes erratic as the speed increases and after a few second the ball just moves off the iphone simulator screen.
Can someone help me run this code(please add an image to represent the ball in IB) to see what I am not doing correctly.
Thanks in advance for your help.
.h
#interface ViewController : UIViewController
{
UIImageView *ball;
int speedX;
int speedY;
CGPoint ballMovement;
}
#property (nonatomic, retain) IBOutlet UILabel *scoreLabel;
#property (nonatomic, retain) IBOutlet UIImageView *ball;
- (void)initializeTimer;
- (void)animateBall:(NSTimer *)theTimer;
#end
.m
#implementation ViewController
#synthesize ball;
- (void)dealloc {
[ball release];
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
ball.center = CGPointMake(50,50);
speedX = 1;
speedY = 1;
ballMovement = CGPointMake(speedX,speedY);
[self initializeTimer];
}
- (void)initializeTimer {
float theInterval = 0.1f;
[NSTimer scheduledTimerWithTimeInterval:theInterval target:self selector:#selector(animateBall:) userInfo:nil repeats:YES];
}
- (void)animateBall:(NSTimer *)theTimer {
ball.center = CGPointMake(ball.center.x+speedX, ball.center.y+speedY);
speedX += 1;
speedY += 1;
NSLog(#"%d,%d", speedX, speedY);
if (speedX <= 1)
speedX ==1;
if (speedY <= 1)
speedY ==1;
if(ball.center.x > 300 || ball.center.x < 20)
speedX = -abs(speedX);
if(ball.center.y > 440 || ball.center.y < 40)
speedY = -abs(speedY);
}
You are not capping the speed anywhere, so how is it supposed to reach a constant speed? From your code, once you pass ball.center.x > 300, you reverse the speed.
The rows
if (speedX <= 1) speedX ==1;
if (speedY <= 1) speedY ==1;
Do nothing, since they don't actually assign a value to speedX / speedY. It looks like this is what you mean:
if (speedX <= 1) speedX = 1;
if (speedY <= 1) speedY = 1;
Even so, this won't actually do what you want. If you want a max speed, then it should be something like this:
// Compact version
speedX = MIN(speedX + 1, TARGET_SPEED_X);
// More like your code:
speedX += 1;
if (speedX > TARGET_SPEED_X) speedX = TARGET_SPEED_X;
If you want the ball to bounce off the bottom, with gravity along the y axis:
- (void)animateBall:(NSTimer *)theTimer {
ball.center = CGPointMake(ball.center.x+speedX, ball.center.y+speedY);
speedY += 1;
if(ball.center.x > 300) {
speedX = -abs(speedX);
}
if(ball.center.y > 440)
speedY = -abs(speedY);
}
The main cause of the erratic movement you see is probably because of the bounce off the top/side of the screen. For instance:
if(ball.center.y > 440 || ball.center.y < 40)
speedY = -abs(speedY);
What happens when the ball is speeding towards the top here? Say ball.center.y = 30, speedY = -4.
Your speedY will then stay at -4. Next pass it's -3, then -2, then -1, and then it'll oscillate between -1 and 0. The same happens for speedX eventually.
The question is what sort of movement you are looking for. Your original code had something that looked like constant acceleration in the (1, 1) direction, with a bounce effect in the right and bottom corner, but your description said you wanted acceleration to a maximum speed.
For an accelerating ball with a maximum speed:
#interface ViewController : UIViewController {
UIImageView *ball;
double speedX;
double speedY;
int maxSpeed;
double acceleration;
CGPoint ballMovement;
}
#property (nonatomic, retain) IBOutlet UIImageView *ball;
- (void)initializeTimer;
- (void)animateBall:(NSTimer *)theTimer;
#end
#implementation ViewController
#synthesize ball;
- (void)dealloc {
[ball release];
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
ball.center = CGPointMake(50,50);
speedX = 1;
speedY = 1;
maxSpeed = 20;
acceleration = 1;
ballMovement = CGPointMake(speedX,speedY);
[self initializeTimer];
}
- (void)initializeTimer {
float theInterval = 0.1f;
[NSTimer scheduledTimerWithTimeInterval:theInterval target:self selector:#selector(animateBall:) userInfo:nil repeats:YES];
}
- (void)animateBall:(NSTimer *)theTimer {
ball.center = CGPointMake(ball.center.x + speedX, ball.center.y + speedY);
// Discover the actual speed.
double actualSpeed = sqrt(speedX * speedX + speedY * speedY);
// Increase the speed by the acceleration (actually acceleration * time interval),
// Cap at max speed
double newSpeed = MIN(acceleration + actualSpeed, maxSpeed);
// Increase velocity uniformly along both x and y axis
// (This example does not properly handle when speedX and speedY both start at zero)
speedX = speedX * newSpeed / actualSpeed;
speedY = speedY * newSpeed / actualSpeed;
// Make sure to bounce
if (ball.center.x > 300) speedX = -abs(speedX);
if (ball.center.x < 20) speedX = abs(speedX);
if (ball.center.y > 440) speedY = -abs(speedY);
if (ball.center.y < 40) speedY = abs(speedY);
}
#end
Acceleration = Speed / Delta_time
So you have to modify the code:
- (void)animateBall:(NSTimer *)theTimer {
ball.center = CGPointMake(ball.center.x+speedX, ball.center.y+speedY);
static float acceleration = 1.0f;
speedX += acceleration*theTimer.timeInterval;
speedY += acceleration*theTimer.timeInterval;
NSLog(#"%d,%d", speedX, speedY);
if (speedX <= 1)
speedX ==1;
if (speedY <= 1)
speedY ==1;
if(ball.center.x > 300 || ball.center.x < 20)
speedX = -abs(speedX);
if(ball.center.y > 440 || ball.center.y < 40)
speedY = -abs(speedY);
}

iphone code - CGPoint question

i have 10 moving objects (UIImageView),
is there a better way to write this code?
- (void) jumpOnTimer {
jumpBall1.center = CGPointMake(jumpBall1.center.x+pos1.x,jumpBall1.center.y+pos1.y);
if(jumpBall1.center.x > 60 || jumpBall1.center.x < 0)
pos1.x = -pos1.x;
if(jumpBall1.center.y > 211 || jumpBall1.center.y < 82)
pos1.y = -pos1.y;
jumpBall2.center = CGPointMake(jumpBall2.center.x+pos2.x,jumpBall2.center.y+pos2.y);
if(jumpBall2.center.x > 40 || jumpBall2.center.x < 0)
pos2.x = -pos2.x;
if(jumpBall2.center.y > 206 || jumpBall2.center.y < 82)
pos2.y = -pos2.y;
and so on...
Judging by that code snippet, it looks like you have a single controller which "owns" the ten balls, and you want the balls to bounce around according to a set of rules that are unique to each ball. A more object-oriented approach would be as follows:
#interface JumpBallClass
{
CGPoint center;
CGPoint speed;
CGPoint lowerLimit;
CGPoint upperLimit;
}
#property (assign) CGPoint lowerLimit;
#property (assign) CGPoint upperLimit;
- (void)update;
#end
#implementation JumpBallClass
- (void)update
{
center.x += speed.x;
center.y += speed.y;
if (center.x > upperLimit.x || center.x < lowerLimit.x)
{ speed.x = -speed.x; }
if (center.y > upperLimit.y || center.y < lowerLimit.y)
{ speed.y = -speed.y; }
}
#end
This setup would allow you to configure all of the balls once, by setting their upper and lower limits:
[jumpBall1 setUpperLimit:CGPointMake(60, 211)];
[jumpBall1 setLowerLimit:CGPointMake(0, 82)];
...
And then simply calling update on each ball in your timer method:
- (void) jumpOnTimer {
[jumpBall1 update];
[jumpBall2 update];
...
}
You can simplify this even further by storing all of the balls in an NSArray:
NSArray * balls = [NSArray arrayWithObjects:jumpBall1, jumpBall2, ..., nil];
And then calling makeObjectsPerformSelector:
[balls makeObjectsPerformSelector:#selector(update)];
You can make an array of jumpBalls and then loop through each and do the code for that. You can do something like this:
JumpBallClass *myjumpballs[10];
for (i=0; i<10; i++) {
myjumpballs[i].center = CGPointMake(myjumpballs[i].center.x+pos1.x,myjumpballs[i].center.y+pos1.y);
if(myjumpballs[i].center.x > 60 || myjumpballs[i].center.x < 0)
pos1.x = -pos1.x;
if(myjumpballs[i].center.y > 211 || myjumpballs[i].center.y < 82)
pos1.y = -pos1.y;
}
Looks like you're trying to manually animate. Have a look at using UIView animations instead