0

全て。iPhone の画面上でボールをバウンドさせるチュートリアルに従おうとしています。このチュートリアルでは、MVC スキームでアプリケーションを構築します。View 実装の drawRect メソッドに関しては、この概念に頭を悩ませています。

これは私のモデルヘッダーファイルです:

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

#define BALL_SIZE 20.0
#define VIEW_WIDTH 320.0
#define VIEW_HEIGHT 460.0

@interface TestModel : NSObject
{
    TestView* ball;
    CGPoint ballVelocity;
    CGFloat lastTime;
    CGFloat timeDelta;
}

- (void) updateModelWithTime:(CFTimeInterval) timestamp;
- (void) checkCollisionWithScreenEdges;

@property (readonly) TestView* ball;

@end

このチュートリアルでは、NSObject の init メソッドをオーバーライドするようにユーザーに指示しています。「アニメーション」ロジックを制御するためのメソッドも含めました。

    - (id) init {
        self = [super init];

        if (self) {
            ball = [[TestView alloc] initWithFrame: CGRectMake(0.0, 0.0, BALL_SIZE, BALL_SIZE)];

            // Set the initial velocity for the ball
            ballVelocity = CGPointMake(200.0, -200.0);

            // Initialize the last time
            lastTime = 0.0;
        }

        return self;
    }

- (void) checkCollisionWithScreenEdges {
    // Left Edge
    if (ball.frame.origin.x <= 0) {
        ballVelocity.x = abs(ballVelocity.x);
    }

    // Right Edge
    if (ball.frame.origin.x >= VIEW_WIDTH - BALL_SIZE) {
        ballVelocity.x = -1 * abs(ballVelocity.x);
    }

    // Top Edge
    if (ball.frame.origin.y <= 0) {
        ballVelocity.y = abs(ballVelocity.y);
    }

    // Bottom Edge
    if (ball.frame.origin.y >= VIEW_HEIGHT - BALL_SIZE) {
        ballVelocity.y = -1 * abs(ballVelocity.y);
    }
}

- (void) updateModelWithTime:(CFTimeInterval) timestamp {
    if (lastTime == 0.0) {
        // initialize lastTime if first time through
        lastTime = timestamp;
    } else {
        // Calculate time elapsed since last call
        timeDelta = timestamp - lastTime;

        // Update the lastTime
        lastTime = timestamp;

        [self checkCollisionWithScreenEdges];

        // Calculate the new position of the ball
        CGFloat x = ball.frame.origin.x + ballVelocity.x * timeDelta;
        CGFloat y = ball.frame.origin.y + ballVelocity.y * timeDelta;

        ball.frame = CGRectMake(x, y, BALL_SIZE, BALL_SIZE);
    }
}

ビューの実装ファイルは次のとおりです。

#import "TestView.h"

@implementation TestView

- (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 {

}
@end

最後に、私のView Controller:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    gameModel = [[TestModel alloc] init];

    [self.view addSubview:gameModel.ball];

    // Set up the CADisplayLink for the animation
    gameTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateDisplay:)];

    // Add the display link to the current run loop
    [gameTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void) updateDisplay:(CADisplayLink *) sender {
    [gameModel updateModelWithTime:sender.timestamp];
}

さて、コードの構造を見てきたので (うまくいけば十分です)、私の質問に移ることができます。したがって、drawRect に何かを追加すると、新しいオブジェクトが描画され、モデル ロジック メソッドによって「アニメーション化」されません。

今、私は跳ねる正方形を持っています。drawRect で四角形を楕円で塗りつぶそうとすると、バウンドする四角形がまだアクティブな間、0,0 の位置にある、希望どおりに描画された新しいオブジェクトが得られます。

ここで本当に大きな何かが欠けていると確信していますが、何時間も頭を壁にぶつけていて、それを理解できません. どんな助けでも大歓迎です!

4

1 に答える 1

0

ここにいくつかのことがあります:

1- SBのビュークラスをTestViewにオーバーライドしましたか?
2-コードを見ると、モデルがコントローラーを介してビューにどのように接続されているかわかりません。MVCモデルから、コントローラーが一番上にあり、モデルとビューに(ピラミッドスタイルで)話しかけることを思い出してください。したがって、ビューコントローラーのどこかで:
a)モデルをインスタンス化する必要があります
b)モデルから値を取得しますそれらをビュー変数に渡します-これはdrawrectで呼び出されます

最後になりましたが、ビューを呼び出して更新する方法であるルックアップsetNeedsDisplay。

これが割り当てを損なうことなく役立つことを願っています。

于 2013-02-11T05:00:29.557 に答える