0

ユーザーが上部のステータスバーにボトルの1つを投げて、それを壊すことができる簡単なゲームをやっています。touchesMovedを使用して、ユーザーがボトル(UIView)をキャッチしたかどうかをテストしています。ボトルは、ユーザーの指のフリック方向に応じてスローされます。投げる部分は動作しますが、フレームから外れると壊れて壊れたボトルpngに変えて欲しいので、この部分が頭痛の種になります。コードの一部は次のとおりです。

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

UITouch *aTouch = [touches anyObject];
CGPoint location = [aTouch locationInView:self.view];

throwView = [self.view hitTest:location withEvent:nil];

//if the movement not on self.view, it's on the bottle.
if (bottleView != self.view) {
CGPoint loc = [aTouch locationInView:self.bottleView];
CGPoint prevloc = [aTouch previousLocationInView:self.bottleView];

//getting the finger moment
myFrame = self.bottleView.frame;
deltaX = loc.x - prevloc.x;
deltaY = loc.y - prevloc.y;

myLocation = bottleView.center;


//Here I try to multiply the finger movement to throw the bottles
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

myFrame.origin.x += deltaX*7.0;
myFrame.origin.y += deltaY*7.0; 
[self.bottleView setFrame:myFrame];
[bottleView setNeedsDisplay];
[UIView commitAnimations];


//if it hits the top of the frame..
    if (myFrame.origin.y <=20){
        [self hitTheTop];
    }
}}


   //this part gives me headache, I repeat the code again otherwise the bottle is broken before hitting the top.

-(void) hitTheTop{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

myFrame.origin.x += deltaX*7.0;
myFrame.origin.y += deltaY*7.0; 
[self.bottleView setFrame:myFrame];
[bottleView setNeedsDisplay];
[UIView commitAnimations];

//I calculate the slope and find where x should be when y is 0, 40 is half width of the bottle
myFrame.origin.x = myLocation.x + (myLocation.y / (-deltaY / deltaX)) - 40;
myFrame.origin.y = 0;

UIImageView *bottleBroken=
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"broken.png"]];
[bottleBroken setFrame:CGRectMake(-20, -30, 130, 180)];
[self.bottleView setFrame:myFrame];
[bottleView addSubview:bottleBroken];   
}

今のところ、私が得たのは、最初にボトルがフレームから飛び出し、非常に短い間、フレームの端に戻ってすでに壊れているように見え、本当に不自然に見えます。実はスローを表示するタイマーを入れようと思っているので、うまくいくかもしれません。しかし、私はタイマーなしでそれを行うためのより簡単な方法があるかどうかを探求したいだけです、どんな提案でもthx !!

4

1 に答える 1

0

これが私のゲームで衝突検出を行う方法です。

NSMutableArray *collidees = [NSMutableArray arrayWithArray:[[GRSceneController sharedSceneController] sceneObjects]]; 

[collidees removeObject:self];

NSMutableArray *collisions = [[NSMutableArray alloc] init];

position.y += speed.y;

for (GRBlock *obj in collidees) {
    if ([self.collider doesCollideWithCollider:obj.collider])
        [collisions addObject:obj];
}

if ([collisions count]) {
    [(GRSceneObject<GRColliderDelegate> *)self didCollideWith:collisions collisionType:kVerticalCollision];
}

[collisions removeAllObjects];

それから私は同じことを繰り返しますposition.x

メソッドは次のようになりdoesCollideWithCollider:ます

-(BOOL)doesCollideWithCollider:(GRColliderObject *)aCollider {

    #if defined DEBUG_COLLIDER && defined LOG
    logRect(hitBox);
    logRect(aCollider.hitBox);
    #endif

    CGRect colliderBox = aCollider.hitBox;

    return CGRectIntersectsRect(hitBox, colliderBox);
}

hitBoxオブジェクトを囲み、コライダーとして機能し、衝突を処理する単なるボックスですdidCollideWith:collisionType:

これから取り除く主なことは、速度の変数を用意し、position.y += speed.yある種の速度を作成する必要があるということです。そして、更新後の垂直方向の衝突position.yと更新後の水平方向の衝突を確認しますposition.x

于 2012-08-05T13:33:17.233 に答える