本游戏的设计步骤:
一、布局界面(把图片资源拉进Main.storyboard)
二、让小球动起来(给他一个初速度)
三、碰撞检测
1、屏幕碰撞
2、砖块碰撞
3、挡板碰撞
四、挡板移动
// ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *blockImageArray;
@property (weak, nonatomic) IBOutlet UIImageView *paddleImage;
@property (weak, nonatomic) IBOutlet UIImageView *ballImage;
@end
// ViewController.m
#import "ViewController.h"
@interface ViewController ()
{
//用这个布尔值标示游戏是否正在进行中
BOOL isPlaying ;
//加一个游戏时钟
CADisplayLink *_gameTimer;
//小球移动的速度
CGPoint _speed;
//手指移动位置的差值
CGFloat chaX;
}
//1.检测屏幕碰撞
-(BOOL)checkWithScreen;
//2.砖块碰撞检测
-(BOOL)checkWithBlock;
//3.挡板碰撞
-(void)checkWithPandle;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark 1 之前进行了页面的布局
//开始游戏
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//游戏是否在进行中,如果游戏还没有开始就让游戏开始
if(!isPlaying){
isPlaying = YES;
//初始化一个游戏时钟,让step方法1/60秒执行一次
_gameTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];
//将游戏放在runloop中
/*
*
*runLoop做两件事情
1.监听输入源,一般自动放到runLoop中
2.监听定时器,一般需手动放到runLoop中
*/
//[_gameTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_gameTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//给小球一个初始的速度
_speed = CGPointMake(0, -5);
}
else
{
chaX = 0;
}
}
#pragma mark 2 让小球动起来
//让小球按照1/60的频率动起来
-(void)step{
// 如果返回值是yes就代表游戏失败
if ([self checkWithScreen]) {
[self gameOver:@"再来一次"];
}
if ( [self checkWithBlock]) {
[self gameOver:@"你真棒"];
}
[self checkWithPandle];
//小球每次的移动都是以上一次的位置作为参考
_ballImage.center = CGPointMake(_ballImage.center.x+_speed.x, _ballImage.center.y+_speed.y);
}
#pragma mark 3 碰撞检测
//1.检测屏幕碰撞
-(BOOL)checkWithScreen
{
BOOL isFail = NO;
//CGRectGetMInY 获取到小球的最小Y值
//1.顶部碰撞
if (CGRectGetMinY(_ballImage.frame) <= 0)
{
//获取到绝对值
_speed.y = fabsf(_speed.y);
}
//2.底部碰撞
if (CGRectGetMaxY(_ballImage.frame) >= (CGRectGetHeight(self.view.frame))) {
isFail = YES;
}
//3左侧碰撞
if (CGRectGetMinX(_ballImage.frame) <= 0) {
_speed.x = fabsf(_speed.x);
}
//4.右侧碰撞
if (CGRectGetMaxX(_ballImage.frame) >= CGRectGetWidth(self.view.frame)) {
_speed.x = -1*fabsf(_speed.x);
}
return isFail;
}
//2.检测板子是否碰撞
-(BOOL)checkWithBlock
{
BOOL gameWin = YES;
//通过for循环找到小球跟哪个色块碰撞了
for (UIImageView *block in _blockImageArray) {
//CGRectIntersectsRect判断;两个视图是否碰撞
if (CGRectIntersectsRect(block.frame , _ballImage.frame) && !block.hidden) {
block.hidden = YES;
_speed.y = fabsf(_speed.y);
}
}
//判断所有的砖块是否都被隐藏了
for (UIImageView *block in _blockImageArray ) {
if (block.hidden == NO) {
gameWin = NO;
break;
}
}
return gameWin;
}
//3.挡板碰撞检测
-(void)checkWithPandle
{
if(CGRectIntersectsRect(_ballImage.frame,_paddleImage.frame))
{
_speed.y = -1*fabsf(_speed.y);
//让小球的X方向的速度跟手指瞬时移动的速度相加
_speed.x += chaX;
NSLog(@"speed.x= %f",_speed.x);
}
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if (isPlaying) {
//后去我点击的手指,touches是个集合,视图有多点触摸
UITouch *touch = [touches anyObject];
//获取到当前手指x的值
CGFloat nowX = [touch locationInView:self.view].x;
//获取到上一次手指x的值
CGFloat lastX = [touch previousLocationInView:self.view].x;
chaX = nowX -lastX;
//让挡板移动
_paddleImage.center = CGPointMake(_paddleImage.center.x+chaX,_paddleImage.center.y);
}
}
#pragma mark 从底部掉下去,游戏结束
-(void)gameOver:(NSString *)string
{
isPlaying = NO;
NSLog(@"%@",string);
//销毁定时器
[_gameTimer invalidate];
for (UIImageView *block in _blockImageArray) {
block.hidden = YES;
block.alpha = 0;
}
[UIView animateWithDuration:2.0 animations:^{
for (UIImageView *block in _blockImageArray){
block.hidden = NO;
block.alpha = 1;
}
}completion:^(BOOL finshed){
_ballImage.center = CGPointMake(160, 377);
_paddleImage.center = CGPointMake(160, 397);
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end