最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS 簡單的操作桿旋轉(zhuǎn)實現(xiàn)示例詳解

 更新時間:2022年12月29日 12:17:03   作者:頭疼腦脹的代碼搬運工  
這篇文章主要為大家介紹了iOS 簡單的操作桿旋轉(zhuǎn)實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

一、效果實現(xiàn)

簡單實現(xiàn)了一個消滅病毒的小效果,畫面略顯粗糙,多多見諒

控制球復位

二、操作桿實現(xiàn)

實現(xiàn)拖動小球,獲取當前小球的旋轉(zhuǎn)方向,將旋轉(zhuǎn)的方向傳遞出去,旋轉(zhuǎn)“坦克”進行攻擊“病毒”。

#import "DirectionOptionView.h"
@interface DirectionOptionView()
//方向指示器滾珠
@property(nonatomic,strong) UIView * ball;
@end
@implementation DirectionOptionView
- (instancetype)initWithFrame:(CGRect)frame changeDirectionBlock:(ChangeDirectionBlock)changeDirectionBlock
{
    if (self = [super initWithFrame:frame]) {
        self.changeDirectionBlock = changeDirectionBlock;
        [self makeView];
        [self addPan];
    }
    return self;
}
//添加拖拽手勢
- (void)addPan{
    UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action: @selector(panAction:)];
    [self addGestureRecognizer:pan];
}
- (void)panAction:(UIPanGestureRecognizer *)pan
{
    switch (pan.state) {
        case UIGestureRecognizerStateBegan:
        {
            CGPoint point = [pan locationInView:**self**];
            self.ball.alpha = 1;
            [self moveWithPoint:point];
        }
            break;
        case UIGestureRecognizerStateChanged:
        {
            CGPoint point = [pan locationInView:self];
            [self moveWithPoint:point];
        }
            break;
        case UIGestureRecognizerStateEnded:
        {
            CGPoint point = [pan locationInView:self];
            [self resetBallPositionWithEndPoint:point];
        }
            break;
        default:
            break;
    }
}
//小球復位
- (void)resetBallPositionWithEndPoint:(CGPoint)point
{
    self.changeDirectionBlock(0);
    [UIView animateWithDuration:0.2 animations:^{
        self.ball.center = CGPointMake((self.frame.size.width / 2.0), (self.frame.size.height / 2.0));
        self.ball.alpha = 0.4;
    }];
}
//根據(jù)控制球位置獲取當前旋轉(zhuǎn)角度
- (void)moveWithPoint:(CGPoint)point
{
    CGFloat distanceCircle = (self.ball.frame.size.width / 2.0);
    CGFloat x = point.x;
    CGFloat y = point.y;
    CGFloat dx = x - self.frame.size.width / 2.0;
    CGFloat dy = y - self.frame.size.height / 2.0;
    CGFloat rotation = atan2(dx,dy);
    CGFloat r = self.frame.size.width / 2.0;
    CGFloat rx = (r - distanceCircle) * sin(rotation) + r;
    CGFloat ry = (r - distanceCircle) * cos(rotation) + r;
    //防止控制球越界
    if ((sqrt((dx * dx) + (dy * dy))) > (r - distanceCircle)) {
        x = rx;
        y = ry;
    }
    //用block形式向外界暴露當前控制球相對于屏幕上方的角度
    self.changeDirectionBlock(-rotation + M_PI);
    self.ball.center = CGPointMake(x, y);
}
- (void)makeView{
    //進行倒角
    self.layer.masksToBounds = YES;
    self.layer.cornerRadius = self.frame.size.width / 2.0;
    self.backgroundColor = [[UIColor groupTableViewBackgroundColor] colorWithAlphaComponent:0.7];
    //添加控制球
    [self addSubview:self.ball];
}
//控制球
- (UIView *)ball
{
    if (!_ball) {
        CGSize size = CGSizeMake(45, 45);
        _ball = [[UIView alloc] initWithFrame:CGRectMake((self.frame.size.width - size.width) / 2.0, (self.frame.size.height - size.height) / 2.0, size.width, size.height)];
        _ball.alpha = 0.4;
        _ball.layer.masksToBounds = YES;
        _ball.layer.cornerRadius = _ball.frame.size.width / 2.0;
        _ball.backgroundColor = [UIColor lightGrayColor];
    }
    return _ball;
}
@end

三、發(fā)射子彈及碰撞檢測

1、發(fā)射子彈

//根據(jù)當前角度,預判子彈動畫的結(jié)束位置
- (NSArray *)prepareBulletPath
{
    CGPoint center = self.center;
    CGFloat maxLength = sqrt(([UIScreen mainScreen].bounds.size.width * [UIScreen mainScreen].bounds.size.width) + ([UIScreen mainScreen].bounds.size.height * [UIScreen mainScreen].bounds.size.height));
    CGFloat endY = sin(self.angle - M_PI / 2.0) * maxLength + center.y;
    CGFloat endX = cos(self.angle - M_PI / 2.0) * maxLength + center.x;
    CGPoint endPoint = CGPointMake(endX, endY);
    return @[@(center),@(endPoint)];
}
- (void)fir
{
    CGFloat bulletWidth = 10;
    BulletView * lastBulletView = self.bulletArr.count > 0 ? self.bulletArr.lastObject : nil;
    if (!lastBulletView) {
        BulletView * view = [[BulletView alloc] initWithFrame:CGRectMake((self.frame.size.width - bulletWidth) / 2.0, 0,bulletWidth,bulletWidth)];
        view.points = [self prepareBulletPath];
        [self.superview insertSubview:view belowSubview:self];
        [self.bulletArr addObject:view];
        view.center = [view.points[0] CGPointValue];
        [UIView animateWithDuration:1 animations:^{
            view.center = [view.points[1] CGPointValue];
        } completion:^(BOOL finished) {
            [view removeFromSuperview];
            [self.bulletArr removeObject:view];
        }];
    }
}

fir 本身是一個定時器事件,在里面添加一些創(chuàng)建子彈的邏輯,位置移動還是用了最簡單的 UIViewanimateWithDuration 方法,但是注意這里面通過 frame 進行碰撞檢測是獲取不到,所以,添加了 CADisplayLink 屏幕刷新事件來檢測子彈視圖的 layer.presentationLayer.frame來進行與病毒的 frame 進行檢測屏幕位置是否包含。

2、檢測碰撞

bool CGRectIntersectsRect(CGRect rect1, CGRect rect2) 檢測碰撞的方法

//添加屏幕刷新事件監(jiān)聽
- (void)addScreenRefreshAction
{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector: @selector(update)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)update
{
    [self.bulletArr enumerateObjectsUsingBlock:^(BulletView * bulletView, NSUInteger idx, BOOL * _Nonnull stop) {
        [self.virusArr enumerateObjectsUsingBlock:^(VirusView * virusView, NSUInteger idx, BOOL * _Nonnull stop) {
            //檢測碰撞
            if (CGRectIntersectsRect(bulletView.layer.presentationLayer.frame, virusView.frame)) {
                [bulletView removeFromSuperview];
                [self.bulletArr removeObject:bulletView];
                [virusView attacked];
                if ([virusView isDie]) {
                    [virusView removeFromSuperview];
                    [self.virusArr removeObject:virusView];
                }
            }
        }];
    }];
    if (!self.virusArr.count) {
        [self createVirusView];
    }
}

四、添加病毒及消滅動畫

1、隨機創(chuàng)建病毒

- (void)createVirusView
{
    int width = arc4random() % 30 + 50;
    int x = arc4random() % ([[NSNumber numberWithFloat:[UIScreen mainScreen].bounds.size.width] integerValue] - width);
    int y = arc4random() % ([[NSNumber numberWithFloat:[UIScreen mainScreen].bounds.size.height / 2.0] integerValue]);
    VirusView * virusView = [[VirusView alloc] initWithFrame:CGRectMake(x, y, width, width)];
    [self.superview addSubview:virusView];
    [self.virusArr addObject:virusView];
}

2、消滅動畫

添加了一點粒子效果,顯示病毒消散動畫

- (void)fireExplode
{
    CAEmitterLayer * emitter = [CAEmitterLayer layer];
    emitter.frame = self.frame;
    [self.superview.layer addSublayer:emitter];
    emitter.renderMode = kCAEmitterLayerAdditive;
    emitter.emitterPosition = CGPointMake(emitter.frame.size.width*0.5,    emitter.frame.size.height*0.5);
    CAEmitterCell *cell = [[CAEmitterCell alloc] init];
    cell.contents = ( __bridge id)[UIImage imageNamed:@"v4"].CGImage;
    cell.birthRate = 1;//出生率
    cell.lifetime = 0.7;//生命周期
    cell.emissionLongitude = - M_PI_2;
    cell.emissionRange = M_PI_2;
    cell.alphaSpeed = -0.2;
    cell.velocity = 10;//速度
    cell.scale = 0.15;//縮放倍數(shù)
    emitter.emitterCells = @[cell];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [emitter removeFromSuperlayer];
    });
}

五、思考與總結(jié)

添加 UIViewanimateWithDuration 方法后,這里用的是屏幕刷新檢測,來獲取當前控件的 layer.presentationLayer.frame 來檢測碰撞,其他邏輯都相對簡單。

以上就是iOS 簡單的操作桿旋轉(zhuǎn)實現(xiàn)示例詳解的詳細內(nèi)容,更多關(guān)于iOS 操作桿旋轉(zhuǎn)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • XCode編譯速度慢的處理方法

    XCode編譯速度慢的處理方法

    本文給大家介紹的是在IOS開發(fā)中XCode編譯速度慢的3種解決辦法,十分的實用,有需要的小伙伴可以參考下。
    2015-06-06
  • IOS 開發(fā)之swift中手勢的實例詳解

    IOS 開發(fā)之swift中手勢的實例詳解

    這篇文章主要介紹了IOS 開發(fā)之swift中手勢的實例詳解的相關(guān)資料,希望通過本文大家能掌握IOS手勢的使用方法,需要的朋友可以參考下
    2017-09-09
  • 設(shè)計模式中的迭代器模式在Cocoa Touch框架中的使用

    設(shè)計模式中的迭代器模式在Cocoa Touch框架中的使用

    這篇文章主要介紹了設(shè)計模式中的迭代器模式在Cocoa Touch框架中的使用,示例代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下
    2016-03-03
  • iOS10 推送完整剖析和注意事項

    iOS10 推送完整剖析和注意事項

    這篇文章主要為大家詳細介紹了iOS10 推送完整剖析和注意事項,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • iOS讀取txt文件出現(xiàn)中文亂碼的解決方法

    iOS讀取txt文件出現(xiàn)中文亂碼的解決方法

    這篇文章主要為大家詳細介紹了iOS讀取txt文件出現(xiàn)中文亂碼的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 開發(fā)繪圖、手勢綜合App注意點

    開發(fā)繪圖、手勢綜合App注意點

    本篇文章主要給大家詳細講述了在IOS開發(fā)繪圖、手勢綜合App容易遇到的坑以及注意事項等內(nèi)容,有興趣的朋友參考下吧。
    2018-02-02
  • iOS中的UISearchBar搜索框組件基礎(chǔ)使用指南

    iOS中的UISearchBar搜索框組件基礎(chǔ)使用指南

    iOS開發(fā)套件中自帶的UISearchBar搜索框我們平時經(jīng)??梢杂玫?我們可以在默認的基礎(chǔ)上修改文字顏色、背景顏色和背景圖片等,這里我們稍微總結(jié)一下iOS中的UISearchBar搜索框組件基礎(chǔ)使用指南.
    2016-05-05
  • IOS使用TestFlight測試的使用方法

    IOS使用TestFlight測試的使用方法

    TestFlight是iOS系統(tǒng)上用來測試軟件的,打開了這個APP就相當于打開了新世界的大門,這個APP直接可以改變你對IOS系統(tǒng)封閉的看法,讓你擁有媲美安卓用戶的更多自主權(quán)!
    2022-12-12
  • iOS中g(shù)if圖的顯示方法示例

    iOS中g(shù)if圖的顯示方法示例

    這篇文章主要給大家介紹了關(guān)于iOS中g(shù)if圖的示的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位iOS開發(fā)者們具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-06-06
  • iOS實現(xiàn)計算器小功能

    iOS實現(xiàn)計算器小功能

    這篇文章主要介紹了iOS實現(xiàn)計算器小功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

久治县| 新野县| 铁岭市| 民县| 阳原县| 沙坪坝区| 广安市| 斗六市| 神农架林区| 财经| 太谷县| 云和县| 宜丰县| 宜君县| 泰兴市| 巢湖市| 连云港市| 全南县| 闵行区| 霍州市| 汉沽区| 高雄市| 吉隆县| 汝州市| 凤山市| 中江县| 荥阳市| 台前县| 嘉黎县| 平武县| 滁州市| 正镶白旗| 黄骅市| 正安县| 高要市| 西乌珠穆沁旗| 湖口县| 滨州市| 疏勒县| 临武县| 开原市|