如何在没有cocos2d的情况下从头开始编写一个弹跳球

时间:2012-12-04 15:36:08

标签: ios ios5 cocos2d-iphone ios6

根据开源项目cocos2d编写一些实现弹跳球的代码非常容易,here就是问题所在。

所以没有cocos2d,如何用最简单的代码实现它。

1 个答案:

答案 0 :(得分:11)

首先你需要创建一个球类。这个类应该有位置,速度,方向等的ivars。 当球需要改变方向时,它也应该有一些方法,比如hitTop,hitBottom,hitLeft,hitRight。它还应该有一种更新位置的方法,将其向前移动一步。 我还有一个BallView,这样我就可以使用图像或只用颜色作为球。

要使它移动你需要在你的视图控制器中有一个游戏循环,有很多方法可以做到这一点,但我觉得最容易的是CADisplayLink。

如果您在实施时遇到问题,可以使用以下代码:

<强> Ball.h

#import <Foundation/Foundation.h>
#import "MovingObjectView.h"

@interface MovingObject : NSObject

@property(nonatomic, retain) MovingObjectView *ball;

@property CGRect bounds;
@property CGPoint position;
@property CGPoint direction;
@property float velocity;

-(id)initWithBounds:(CGRect)b andPosition:(CGPoint)p;

-(BOOL)positionIsInsideRect;
-(void)update;

-(void)hitLeft;
-(void)hitRight;
-(void)hitTop;
-(void)hitBottom;

@end

<强> Ball.m

#import "MovingObject.h"

@implementation MovingObject

-(id)initWithBounds:(CGRect)b andPosition:(CGPoint)p
{
    if (self = [super init]) {
        self.bounds = b;
        self.position = p;
        self.direction = CGPointMake(1, 1);

        //Change the position to middle if position is outside bounds
        if (![self positionIsInsideRect]) {
            NSLog(@"Position changed to center");
            self.position = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
        }

        self.ball = [[[MovingObjectView alloc]initWithFrame:CGRectMake(self.position.x, self.position.y, 15, 15)]autorelease];
    }
    return self;
}

//checks if the balls position is correct
-(BOOL)positionIsInsideRect {
    if (self.position.x < self.bounds.origin.x || self.position.x > self.bounds.size.width || self.position.y < self.bounds.origin.y || self.position.y > self.bounds.size.height) {
        NSLog(@"Position is outside bounds");
        return NO;
    }else{
        return YES;
    }
}

//Call this method to move a ball
-(void)update {
    //Checks if the ball is outside bounds
    if (self.position.x-(self.ball.frame.size.width/2) <= self.bounds.origin.x) {
        [self hitLeft];
    }else if (self.position.x+(self.ball.frame.size.width/2) >= self.bounds.size.width){
        [self hitRight];
    }else if (self.position.y-(self.ball.frame.size.height/2) <= self.bounds.origin.y) {
        [self hitTop];
    }else if (self.position.y+(self.ball.frame.size.height/2) >= self.bounds.size.height){
        [self hitBottom];
    }

    //Updates the balls position
    CGPoint p = self.position;
    p.x += self.direction.x*self.velocity;
    p.y += self.direction.y*self.velocity;
    self.position = p;

    self.ball.center = self.position;
}

//Call this when the ball need to bounce
-(void)hitLeft
{
    NSLog(@"hitLeft");
    CGPoint d = self.direction;
    d.x = fabsf(self.direction.x);
    self.direction = d;
}

-(void)hitRight
{
    NSLog(@"hitRight");
    CGPoint d = self.direction;
    d.x = -fabsf(self.direction.x);
    self.direction = d;
}

-(void)hitTop
{
    NSLog(@"hitTop");
    CGPoint d = self.direction;
    d.y = fabsf(self.direction.y);
    self.direction = d;
}

-(void)hitBottom
{
    NSLog(@"hitBottom");
    CGPoint d = self.direction;
    d.y = -fabsf(self.direction.y);
    self.direction = d;
}

-(void)dealloc {
    [super dealloc];
}

@end

<强> BallView.h

#import <UIKit/UIKit.h>

@interface MovingObjectView : UIView

@property (nonatomic, retain) UIImage *img;

@end

<强> BallView.m

#import "MovingObjectView.h"

@implementation MovingObjectView

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


// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    if (self.img == nil) {
        CGRect bounds = [self bounds];
        [[UIColor blackColor]set];
        UIRectFill(bounds);
    }else {
        CGRect bounds = [self bounds];
        [[UIColor whiteColor]set];
        UIRectFill(bounds);
        [self.img drawInRect:rect];
    }
}

@end

然后终于在viewcontroller中你需要这个:

<强>的ViewController

在viewdidload中:

self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

然后添加此方法:

-(void)gameLoop
{   
    //Updates the balls position
    [self.movingBall update];

    //Here you could add your collision detection code
}