首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为Pong设置CPU难度

为Pong设置CPU难度
EN

Stack Overflow用户
提问于 2014-06-12 22:43:49
回答 1查看 92关注 0票数 0

第二次来到这里,希望有人能指引我正确的方向。

我正在尝试在iOS设备(iPhone/iPod/iPad)的应用程序中实现一个乒乓球游戏,它运行得很好,除了我连CPU都打不过,更不用说得分了。下面是实现.m的代码:

代码语言:javascript
复制
#import "BTM_pongGame.h"
#import <QuartzCore/QuartzCore.h>

#define STEP_DURATION 0.05
#define RESET_BALL_ANIMATION_DURATION 0.5f
#define MARGIN_WHERE_BALL_IS_LEAVING 40
//#define CPU_SKILL 20

@interface BTM_pongGame ()

@end

@implementation BTM_pongGame


@synthesize cpuSkill, ballShape;

- (void)viewDidLoad
{
    [super viewDidLoad];

    cpuSkill = [BT_strings getJsonPropertyValue:self.screenData.jsonVars nameOfProperty:@"cpuSkill" defaultValue:@"20"];
    ballShape = [BT_strings getJsonPropertyValue:self.screenData.jsonVars nameOfProperty:@"ballShape" defaultValue:@"1"];

    if ([ballShape  isEqual: @"1"]) {

        self.ball.layer.cornerRadius = self.ball.frame.size.width / 2;

    } else {

        //self.ball.layer.cornerRadius = self.ball.frame.size.width / 2;

    }



}


- (void) wordsPerLineInfoShowAlert {

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Choose Game"
                                                    message:@"Multiplayer or Single Player? You decide! Choose below."
                                                   delegate:self
                                          cancelButtonTitle:@"Single Player"
                                          otherButtonTitles:@"Go Back",@"Multi Player", nil];

    [alert show];

}


- (void)alertView: (UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{



    NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
    if([title isEqualToString:@"Single Player"]) {

        [self resetPlayerScoreLabels];
[self updatePlayerScoreLabels];

          self.mode = kGameSinglePlayer;
        [self moveComputerPaddle];

        //Disable panning of computer paddle
        [self.playerOne.superview setGestureRecognizers:@[]];
    [self resetBoardForNewRound];

    } else if ([title isEqualToString:@"Multi Player"]) {

[self resetPlayerScoreLabels];
[self updatePlayerScoreLabels];

        self.mode = kGameMultiPlayer;


        [self resetBoardForNewRound];

    } else if ( [title isEqualToString:@"Go Back"]){


        [self navLeftTap];

    }

}







// thanks to MrsVanBeveren for coding the reset score stuff
 -(void)resetPlayerScoreLabels
{
    playerOneScore = 0;
    playerTwoScore = 0;
}




-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self wordsPerLineInfoShowAlert];

    [self startGameTimer];
}

-(void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [_gameTimer invalidate];
}

-(void)quitPressed:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

-(void)startGameTimer
{
    [_gameTimer invalidate];
    _gameTimer = [NSTimer scheduledTimerWithTimeInterval:STEP_DURATION target:self selector:@selector(step:) userInfo:nil repeats:YES];
}

#pragma mark Game setup

/*
 * Some maths to calculate a new starting direction
 * By choosing mid left/right part of the unit circle
 *  we avoid getting straight up/down directions
 */
-(void)resetBallDirection
{
    float randomUnity = arc4random_uniform(100)/100.0;
    int horizontalDirection = (arc4random() % 2 ? 1 : -1);
    float angle = M_PI_4 + randomUnity * M_PI_2;
    float direction = horizontalDirection * angle;

    dirX = sin(direction);
    dirY = cos(direction);
}

-(void)resetBoardForNewRound
{
    speed = self.view.frame.size.width / 50.0;

    [self resetBallDirection];

    [_gameTimer invalidate];

    [UIView animateWithDuration:RESET_BALL_ANIMATION_DURATION animations:^{
        self.ball.center = CGPointMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0);
    } completion:^(BOOL finished){
        [self startGameTimer];
    }];

    [self enlargeAnimation:self.ball];

}

-(void)updatePlayerScoreLabels
{
    self.playerOneScoreLabel.text = [NSString stringWithFormat:@"%d",playerOneScore];
    self.playerTwoScoreLabel.text = [NSString stringWithFormat:@"%d",playerTwoScore];
}


#pragma mark Paddle handling
- (IBAction)paddlePanned:(UIPanGestureRecognizer*)recognizer {
    UIView *paddleWrapper = recognizer.view;
    UIView *paddle = [[paddleWrapper subviews] lastObject];
    switch([recognizer state]) {
        case UIGestureRecognizerStateBegan: {
            paddle.backgroundColor = UIColor.whiteColor;
        }
            break;

        case UIGestureRecognizerStateChanged: {

            CGPoint position = [recognizer locationInView:self.view];

            CGFloat haldPaddleHeight = paddleWrapper.frame.size.height / 2.0;

            CGPoint newCenter = paddleWrapper.center;
            newCenter.y = position.y;

            newCenter.y = MAX(haldPaddleHeight, newCenter.y);
            newCenter.y = MIN(self.view.bounds.size.height - haldPaddleHeight, newCenter.y);

            paddleWrapper.center = newCenter;

        }
            break;

        case UIGestureRecognizerStateEnded: {
            paddle.backgroundColor = UIColor.grayColor;
        }
            break;

        default:
            break;
    }
}

#pragma mark Game loop

/*
 * Game loop
 *  - Moves the ball and checks for obstacles
 */
- (void)step:(NSTimer*)timer
{
    speed += 0.05;
    [self checkForBallLevingSide];

    CGPoint newCenter = self.ball.center;
    CGFloat ballRadius = self.ball.frame.size.height / 2.0;

    newCenter.x += dirX * speed;
    newCenter.y += dirY * speed;

    CGFloat upperEdge = ballRadius;
    CGFloat bottomEdge = self.view.bounds.size.height - ballRadius;

    // Bounce ball of top/bottom walls
    if (newCenter.y <= upperEdge) {
        dirY = ABS(dirY);
        newCenter.y = upperEdge;
    } else if (newCenter.y >= bottomEdge) {
        dirY = -ABS(dirY);
        newCenter.y = bottomEdge;
    }

    [UIView animateWithDuration:STEP_DURATION animations:^{
        self.ball.center = newCenter;
    }];


}

-(BOOL)didBallHitPaddle:(UIView *)paddle withinLimit:(CGFloat)limit
{
    if (CGRectIntersectsRect(paddle.frame, self.ball.frame)){
        [self deflectBallFromPaddle:paddle];
        CGRect ballFrame = self.ball.frame;
        ballFrame.origin.x = limit;
        self.ball.frame = ballFrame;
        return YES;
    } else
        return NO;
}

-(void)checkForBallLevingSide
{

    float limitLeft = MARGIN_WHERE_BALL_IS_LEAVING;
    float limitRight = self.view.bounds.size.width - self.ball.frame.size.width - MARGIN_WHERE_BALL_IS_LEAVING;

    CGRect ballFrame = self.ball.frame;
    CGFloat ballX = ballFrame.origin.x;

    if (ballX < limitLeft) {
        if (![self didBallHitPaddle:self.playerOne.superview withinLimit:limitLeft])
            [self playerDidMiss:kPlayerOne];
    }else if (ballX > limitRight) {
        if (![self didBallHitPaddle:self.playerTwo.superview withinLimit:limitRight])
            [self playerDidMiss:kPlayerTwo];
    }


}

/*
 * Calculates new dirX and dirY after the bounce.
 * The longer from the paddle's middle the bigger the result angle gets. (Pong style)
 */
-(void)deflectBallFromPaddle:(UIView *)paddle
{
    dirX *= -1;

    CGFloat diff = self.ball.center.y - paddle.center.y;
    float p = diff / paddle.frame.size.height * 2.0f;
    dirY += p * 0.5;


}


-(void)playerDidMiss:(kPlayer)player
{
    if (player == kPlayerOne) {
        playerTwoScore++;
        [self victoryShake:self.playerTwo];
        [self enlargeAnimation:self.playerTwoScoreLabel];
    }
    else if (player == kPlayerTwo) {
        playerOneScore++;
        [self victoryShake:self.playerOne];
        [self enlargeAnimation:self.playerOneScoreLabel];
    }

    [self resetBoardForNewRound];
    [self updatePlayerScoreLabels];
}

-(void)moveComputerPaddle
{
    UIView *paddle = self.playerOne.superview;
    CGPoint cpuCenter = paddle.center;
    CGFloat diff = self.ball.center.y - paddle.center.y;
    CGFloat movement = MIN((int)cpuSkill, ABS(diff));

    movement *= diff > 0 ? 1 : -1;

    cpuCenter.y += movement;

    [UIView animateWithDuration:0.1 animations:^{
        self.playerOne.superview.center = cpuCenter;
    } completion:^(BOOL b) {
        [self moveComputerPaddle];
    }];
}

#pragma mark Animation
-(void)victoryShake:(UIView *)view
{
    CAKeyframeAnimation * anim = [ CAKeyframeAnimation animationWithKeyPath:@"transform" ] ;
    anim.values = [ NSArray arrayWithObjects:
                   [ NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0.0f, -20.0f, 0.0f) ],
                   [ NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0.0f, 20.0f, 0.0f) ],
                   nil ] ;
    anim.autoreverses = YES ;
    anim.repeatCount = 4.0f ;
    anim.duration = 0.07f ;

    [view.layer addAnimation:anim forKey:nil];
}

-(void)enlargeAnimation:(UIView *)view
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)];
    animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(3.0, 3.0, 1.0)];
    [animation setDuration:RESET_BALL_ANIMATION_DURATION * 0.5];
    animation.repeatCount = 1.0f ;
    [animation setAutoreverses:YES];

    [view.layer addAnimation:animation forKey:nil];
}

@end

我只是简单地尝试更改数字,在那里它表示#define CPU_SkILL,再次@"cpuSkill" defaultValue:@"20"];,但我没有在任何方向上更改数字。

有什么想法吗?

提前谢谢你。

EN

回答 1

Stack Overflow用户

发布于 2014-06-12 23:09:50

cpuSkill变量控制CPU控制的球拍的运动:

代码语言:javascript
复制
CGFloat movement = MIN((int)cpuSkill, ABS(diff));

因此,可能在任何情况下cpuSkill都比预期的要高。在计算后尝试更低的值或对移动进行一些随机的小调整。

此外,您应该ABS()cpuSkill,以避免完美的移动时,负移动。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24187323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档