【完整APP】SpriteKit引擎開發iOS小遊戲之二(菜單功能實現與其他視圖控制器)

【主菜單視圖控制器】

菜單上擁有4個UIButton類型的控件,初始化它們並綁定點擊的回調處理。

- (void)SetUpButton
{
    [self CreateLoginButton];
    [self CreateStartButton];
    [self CreateAboutButton];
    [self CreateRankButton];
}

- (void)CreateLoginButton
{
    self.LoginButton = [UIButton buttonWithType:UIButtonTypeCustom];
    _LoginButton.frame = CGRectMake(0, 0, 150, 50);
    _LoginButton.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame) * 0.8);
    _LoginButton.layer.shadowOffset =  CGSizeMake(10, 10);
    _LoginButton.layer.shadowOpacity = 0.5;
    _LoginButton.layer.shadowColor =  [UIColor blackColor].CGColor;
    [_LoginButton setBackgroundImage:[UIImage imageNamed:@"button_login"] forState:UIControlStateNormal];
    
    [_LoginButton setTitleColor:[UIColor blackColor] forState:normal];
    [_LoginButton addTarget:self action:@selector(LoginButtonClicked) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_LoginButton];
}

- (void)CreateStartButton
{
    self.startButton = [UIButton buttonWithType:UIButtonTypeCustom];
    _startButton.frame = CGRectMake(0, 0, 150, 50);
    _startButton.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame) * 1.2);
    _startButton.layer.shadowOffset =  CGSizeMake(10, 10);
    _startButton.layer.shadowOpacity = 0.5;
    _startButton.layer.shadowColor =  [UIColor blackColor].CGColor;
    [_startButton setBackgroundImage:[UIImage imageNamed:@"button_start"] forState:UIControlStateNormal];
    [_startButton addTarget:self action:@selector(StartButtonClicked) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_startButton];
}

- (void)CreateAboutButton
{
    self.aboutButton = [UIButton buttonWithType:UIButtonTypeCustom];
    _aboutButton.frame = CGRectMake(0, 0, 150, 50);
    _aboutButton.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame) * 1.4);
    _aboutButton.layer.shadowOffset =  CGSizeMake(10, 10);
    _aboutButton.layer.shadowOpacity = 0.5;
    _aboutButton.layer.shadowColor =  [UIColor blackColor].CGColor;
    [_aboutButton setBackgroundImage:[UIImage imageNamed:@"button_about"] forState:UIControlStateNormal];
    [_aboutButton addTarget:self action:@selector(AboutButtonClicked) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_aboutButton];
}

- (void)CreateRankButton
{
    self.rankButton = [UIButton buttonWithType:UIButtonTypeCustom];
    _rankButton.frame = CGRectMake(0, 0, 150, 50);
    _rankButton.center = CGPointMake(CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame) * 1.6);
    _rankButton.layer.shadowOffset =  CGSizeMake(10, 10);
    _rankButton.layer.shadowOpacity = 0.5;
    _rankButton.layer.shadowColor =  [UIColor blackColor].CGColor;
    [_rankButton setBackgroundImage:[UIImage imageNamed:@"button_rank"] forState:UIControlStateNormal];
    [_rankButton addTarget:self action:@selector(RankButtonClicked) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_rankButton];
}
  1. 排行榜按鈕的點擊處理:推出新的視圖控制器RankViewController
- (void)RankButtonClicked
{
    RankViewController *rankViewController = [[RankViewController alloc] init];
    rankViewController.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:rankViewController animated:YES completion:nil];
}
  1. 遊戲介紹按鈕的點擊處理:UIAlertController控制彈窗內容
- (void)AboutButtonClicked
{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"遊戲說明" message:@"\n玩家化身栗子球進入到森林中飛行訓練,這裏有連續不斷的障礙物出現,也有獲得額外分數的獎勵幣出現。\n\n 登錄(如無先註冊)賬號後就可以上傳自己的記錄,在排行榜中可以觀摩大神和查看自己排名!不斷點擊屏幕讓自己拿到更高的分數吧!偷懶可是會摔死的哦\n\n 反饋Bug或參與合作請聯繫郵箱[email protected]\n\n 遊戲版本:1.0.0" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *conform = [UIAlertAction actionWithTitle:@"確認" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    }];
    [alert addAction:conform];
    [self presentViewController:alert animated:YES completion:nil];
}

  1. 賬號功能相關:判斷有無登錄用戶使用NSUserDefaults取出沙盒中的健值對信息。在viewWillAppear:週期方法中刷新賬號按鈕的外觀。並且點擊處理也會根據登錄狀態而不同,未登錄則會推出登錄的視圖控制器,登錄狀態下則會彈出是否退出登錄的確認框。
- (void)updateLoginButton
{
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSString *userName = [userDefault objectForKey:@"user_name"];
    if (userName == nil){
        [_LoginButton setTitle:@"登錄可傳成績" forState:UIControlStateNormal];
    } else{
        [_LoginButton setTitle:[NSString stringWithFormat:@"歡迎 %@",userName] forState:UIControlStateNormal];
    }
}
//登錄點擊處理
- (void)LoginButtonClicked
{
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    NSString *userName = [userDefault objectForKey:@"user_name"];
    
    if (userName == nil){
        LoginViewController *loginViewController = [[LoginViewController alloc] init];
        loginViewController.modalPresentationStyle = UIModalPresentationFullScreen;
        [self presentViewController:loginViewController animated:YES completion:nil];
    }else {
        UIAlertController *quitLoginAlert = [UIAlertController alertControllerWithTitle:@"退出賬號" message:@"是否決定退出當前登錄的賬號" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消操作" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        }];
        UIAlertAction *conform = [UIAlertAction actionWithTitle:@"確認退出" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
            [userDefault removeObjectForKey:@"user_name"];
            [self.LoginButton setTitle:@"登錄可傳成績" forState:UIControlStateNormal];
        }];
        [quitLoginAlert addAction:cancel];
        [quitLoginAlert addAction:conform];
        [self presentViewController:quitLoginAlert animated:YES completion:nil];
    }
}

【登錄/註冊視圖控制器】

  1. 登錄視圖控制器由背景、賬號&密碼輸入框、取消登錄按鈕、登錄按鈕、前往註冊按鈕組成。其UI初始化與事件綁定如下:
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor colorWithRed:51/255.0 green:204/255.0 blue:255/255.0 alpha:1]];
    [self SetUpUI];
}

- (void)SetUpUI
{
    self.textBackground =[[TextFieldBackgroundView alloc] initWithFrame:CGRectMake(20, 300, WidthSize - 40, 110)];
    _textBackground.backgroundColor = [UIColor whiteColor];
    _textBackground.layer.cornerRadius = 5.0;
    _textBackground.layer.masksToBounds = YES;
    [self.view addSubview:_textBackground];
    
    _account = [[UITextField alloc] initWithFrame:CGRectMake(20, 300, WidthSize - 40, 50)];
    _account.backgroundColor = [UIColor whiteColor];
    _account.placeholder = [NSString stringWithFormat:@"輸入您的賬號"];
    _account.layer.cornerRadius = 5.0;
    _account.keyboardType = UIKeyboardTypeAlphabet;
    _account.delegate = self;
    [self.view addSubview:_account];
    
    _password = [[UITextField alloc] initWithFrame:CGRectMake(20, 360, WidthSize - 40, 50)];
    _password.backgroundColor=[UIColor whiteColor];
    _password.placeholder=[NSString stringWithFormat:@"輸入您的賬號密碼"];
    _password.layer.cornerRadius = 5.0;
    _password.keyboardType = UIKeyboardTypeAlphabet;
    _password.delegate = self;
    [self.view addSubview:_password];
    
    _cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [_cancelButton setFrame:CGRectMake(20, 420, (WidthSize - 60) * 0.5 , 50)];
    [_cancelButton setTitle:@"我不登錄啦" forState:UIControlStateNormal];
    [_cancelButton setBackgroundColor:[UIColor colorWithRed:51/255.0 green:102/255.0 blue:255/255.0 alpha:1]];
    [_cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [_cancelButton.layer setCornerRadius:5.0];
    [_cancelButton addTarget:self action:@selector(HandleCancel) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_cancelButton];
    
    _loginButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [_loginButton setFrame:CGRectMake((WidthSize - 60) * 0.5 + 40, 420, (WidthSize - 60) * 0.5 , 50)];
    [_loginButton setTitle:@"立即登錄" forState:UIControlStateNormal];
    [_loginButton setBackgroundColor:[UIColor colorWithRed:51/255.0 green:102/255.0 blue:255/255.0 alpha:1]];
    [_loginButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [_loginButton.layer setCornerRadius:5.0];
    [_loginButton addTarget:self action:@selector(HandleLogin) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_loginButton];
    
    _registerButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [_registerButton setFrame:CGRectMake(20, 480, WidthSize - 40, 50)];
    [_registerButton setTitle:@"還沒有賬號?註冊一個" forState:UIControlStateNormal];
    [_registerButton setBackgroundColor:[UIColor colorWithRed:51/255.0 green:102/255.0 blue:255/255.0 alpha:1]];
    [_registerButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [_registerButton.layer setCornerRadius:5.0];
    [_registerButton addTarget:self action:@selector(HandleRegister) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_registerButton];
    
}
  1. 關於鍵盤收起的處理:使登錄視圖控制器遵守協議UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = touches.anyObject;
    if(![touch.view isKindOfClass:[UITextField class]]){
        [self.view endEditing:YES];
    }
}
  1. 事件處理:取消登錄、前往註冊如下。點擊登錄和網絡請求有關在後續和網絡一起介紹,這裏先不做展示。
- (void)HandleCancel
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)HandleRegister
{
    RegisterViewController *registerViewController = [[RegisterViewController alloc] init];
    registerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:registerViewController animated:YES completion:nil];
}
  1. 在UITextField輸入框有自定義的UIView子類當作背景,其.m文件如下
#import "TextFieldBackgroundView.h"

@implementation TextFieldBackgroundView


- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context,0.2);
    CGContextBeginPath(context);
    CGContextMoveToPoint(context, 5, 50);
    CGContextAddLineToPoint(context,self.frame.size.width - 5, 50);
    CGContextClosePath(context);
    [[UIColor grayColor] setStroke];
    CGContextStrokePath(context);
}


@end
  1. 註冊視圖控制器與登錄視圖控制器大體相似,不做具體展示了。

【排行榜視圖控制器】

排行榜視圖控制器比較簡單,沒有使用UITableView和UICollectionView(由於功能簡單偷懶了),外觀由一個NavigationBar、若干UIImageView、UILabel組成。由導航欄、個人信息欄、排行榜信息欄(前六位玩家的名字與成績)組成。

  1. 初始化
- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor whiteColor]];
    [self SetUpUI];
}

- (void)SetUpUI
{
    [self SetBackgroundUI];
    [self setNavigationbar];
    [self SetPlayersUI];
    [self GetPlayersInfo];
}

- (void)SetBackgroundUI
{
    self.rankBackground = [[UIImageView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height - 50)];
    [_rankBackground setImage:[UIImage imageNamed:@"rank_background"]];
    [self.view addSubview:_rankBackground];
    
    self.accoutBackground = [[UIImageView alloc] initWithFrame:CGRectMake(20, 160, self.view.frame.size.width - 40, 146)];
    [_accoutBackground setImage:[UIImage imageNamed:@"rank_account_background"]];
    [self.view addSubview:_accoutBackground];
    
    self.playersBackground = [[UIImageView alloc] initWithFrame:CGRectMake(20, 316, self.view.frame.size.width - 40, 486)];
    [_playersBackground setImage:[UIImage imageNamed:@"rank_players_background"]];
    [self.view addSubview:_playersBackground];
    

    self.playerAccoutRank = [[UILabel alloc] initWithFrame:CGRectMake(40, 220, 80, 50)];
    _playerAccoutRank.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_playerAccoutRank];
    
    self.playerAccoutName = [[UILabel alloc] initWithFrame:CGRectMake(160, 220, 80, 50)];
    _playerAccoutName.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_playerAccoutName];
    
    self.playerAccoutScore = [[UILabel alloc] initWithFrame:CGRectMake(280, 220, 100, 50)];
    _playerAccoutScore.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_playerAccoutScore];
}
  1. 導航欄使用UINavigationBar實現。結合UINavigationItem與UIBarButtonItem具體如下:
- (void)setNavigationbar
{
    self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, 60)];
    _navigationBar.backgroundColor = [UIColor clearColor];
    UINavigationItem *navigationBarTitle = [[UINavigationItem alloc] initWithTitle:@"成績排行榜"];
    UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:@selector(BackToMenu)];
    navigationBarTitle.leftBarButtonItem = item;
    [_navigationBar pushNavigationItem: navigationBarTitle animated:YES];
    [self.view addSubview: _navigationBar];
}
  1. 玩家信息設置UILabel的屬性
- (void)SetPlayersUI
{
    self.firstPlayerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 415, 150, 50)];
    [self.view addSubview:_firstPlayerNameLabel];
    self.firstPlayerScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 415, 100, 50)];
    _firstPlayerScoreLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_firstPlayerScoreLabel];
    
    self.secondPlayerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 480, 150, 50)];
    [self.view addSubview:_secondPlayerNameLabel];
    self.secondPlayerScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 480, 100, 50)];
    _secondPlayerScoreLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_secondPlayerScoreLabel];
    
    self.thirdPlayerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 545, 150, 50)];
    [self.view addSubview:_thirdPlayerNameLabel];
    self.thirdPlayerScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 545, 100, 50)];
    _thirdPlayerScoreLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_thirdPlayerScoreLabel];
    
    self.fourthPlayerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 607, 150, 50)];
    [self.view addSubview:_fourthPlayerNameLabel];
    self.fourthPlayerScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 607, 100, 50)];
    _fourthPlayerScoreLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_fourthPlayerScoreLabel];
    
    self.fifthPlayerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 667, 150, 50)];
    [self.view addSubview:_fifthPlayerNameLabel];
    self.fifthPlayerScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 667, 100, 50)];
    _fifthPlayerScoreLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_fifthPlayerScoreLabel];
    
    self.sixthPlayerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 727, 150, 50)];
    [self.view addSubview:_sixthPlayerNameLabel];
    self.sixthPlayerScoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(280, 727, 100, 50)];
    _sixthPlayerScoreLabel.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:_sixthPlayerScoreLabel];
    
    self.updateButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width - 100, 105, 80, 45)];
    [_updateButton setTitle:@"刷  新" forState:UIControlStateNormal];
    _updateButton.backgroundColor = [UIColor blackColor];
    [_updateButton addTarget:self action:@selector(updateRankInfo) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:_updateButton];

}
  1. 方法**GetPlayersInfo:**完成排行榜的數據請求,在網絡部分進行詳細介紹。此外有一個刷新的小按鈕用來重新加載數據,它的點擊回調方法如下:
- (void)updateRankInfo
{
    LJZLoading *loadingView = [[LJZLoading alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
    [self GetPlayersInfo];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [loadingView StopShowLoading];
        [[LJZToast shareInstance] ShowToast:@"更新排行榜數據成功" duration:1];
    });
}

以上不難看到還使用了Loading與Toast功能,這些是我們自己封裝的使用視圖,在後續和網絡部分一同進行介紹。
本文介紹了菜單功能的實現與其他視圖控制器的功能與實現,下一篇文章我將主要介紹遊戲內容的實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章