【完整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功能,这些是我们自己封装的使用视图,在后续和网络部分一同进行介绍。
本文介绍了菜单功能的实现与其他视图控制器的功能与实现,下一篇文章我将主要介绍游戏内容的实现。

你可能感兴趣的:(小项目)