// // YMRoomAnimationView.m // YUMI // // Created by YUMI on 2021/12/6. // #import "XPRoomAnimationView.h" ///Third #import #import #import #import #import "QGVAPConfigModel.h" #import "UIView+VAP.h" #import #import ///Tool #import "XPGiftStorage.h" #import "YUMIMacroUitls.h" #import "ThemeColor+Room.h" #import "NetImageView.h" #import "XPRoomGiftAnimationParser.h" #import "XCCurrentVCStackManager.h" #import "AccountInfoStorage.h" #import "ClientConfig.h" ///Model #import "MicroQueueModel.h" #import "MicroStateModel.h" #import "UserInfoModel.h" #import "GiftReceiveInfoModel.h" #import "GiftInfoModel.h" #import "RoomInfoModel.h" #import "AttachmentModel.h" #import "XPGiftBigPrizeModel.h" #import "XPGiftBannerUserInfoModel.h" #import "GiftReceiveInfoModel.h" #import "XPMessageRemoteExtModel.h" #import "DatingInfoModel.h" #import "AcrossRoomPKPrizeModel.h" #import "RoomHalfHourRankModel.h" #import "ClientConfig.h" ///View #import "XPRoomGiftBannerView.h" #import "XPRoomGiftBroadcastView.h" #import "XPRoomCandyGiftView.h" #import "XPRoomDatingAnimationView.h" #import "XPRoomNobleLevelUpView.h" #import "QGVAPWrapView.h" #import "XPAcrossRoomPKPrizeView.h" #import "XPRoomViewController.h" #import "XPRoomAnchorRankBannerView.h" #import "XPRoomEnterHideTipView.h" #import "XPRoomLuckyBigPrizeView.h" #import "XPRoomGiftCompoundView.h" #import "XPSailingAnimationView.h" #import "XPRoomGraffitiGiftAnimationView.h" #import "XPRoomStarKitchenBannerView.h" #import "XPWebViewController.h" #import "PIBaseAnimationViewModel.h" #import "PIFullScreenBannerAnimation.h" #import "XPTreasureFairyGiftView.h" #import "XPRoomTarrowBannerView.h" #import "PIRoomGiftBroadcastWindow.h" @interface XPRoomAnimationView () ///展示的不同层级 ///最底层的 @property (nonatomic,strong) XPRoomAnimationHitView * lowLevelView; ///中层的 @property (nonatomic,strong) XPRoomAnimationHitView * middleLevelView; ///高层的 @property (nonatomic,strong) XPRoomAnimationHitView * highLevleView; @property(nonatomic,strong) UIStackView *highSTackView; ///动画管理类 @property (strong, nonatomic) SVGAParser *parser; ///VAP动画管理 @property (nonatomic, strong) XPRoomGiftAnimationParser *vapParser; ///送礼物的特效 @property (nonatomic,strong) SVGAImageView *giftEffectView; ///pag动效 @property(nonatomic,strong) PAGView *giftPagView; ///VAP特效 @property (nonatomic, strong) VAPView *vapGiftEffectView; ///福袋礼物送礼物的特效 @property (nonatomic,strong) SVGAImageView *luckyGiftEffectView; ///福袋礼物VAP特效 @property (nonatomic, strong) VAPView *luckyVapGiftEffectView; ///代理 @property (nonatomic,weak) iddelegate; ///复用池 @property (strong,nonatomic)NSMutableSet * bannerDequePool; ///可见池 @property (strong,nonatomic)NSMutableSet * bannerVisiablePool; ///礼物定时器 6s刷新一次 @property (nonatomic,strong)dispatch_source_t giftEffectTimer; #pragma mark - 送礼物的动画的 ///礼物的队列 @property (nonatomic,strong) NSMutableArray *giftQueue; ///定时器 @property (nonatomic ,strong)dispatch_source_t giftTimer; ///复用池 应为送礼物的动画是一个很频繁的事情 所以可以减少内存的消耗 @property (nonatomic,strong) NSMutableSet * giftReuseArray; ///可见池 @property (nonatomic,strong) NSMutableSet * giftVisibleArray; ///大礼物是否正在播放 @property (nonatomic,assign) BOOL isLargeGiftAnimating; #pragma mark - 进房座驾动画的 @property (nonatomic, strong) NSMutableArray *carEffectQueue; @property (nonatomic,strong) SVGAImageView *carEffectView; ///座驾VAP特效 @property (nonatomic, strong) VAPView *carVapEffectView; ///座驾pag动效 @property(nonatomic,strong) PAGView *carPagView; #pragma mark - 进房动画的 @property (nonatomic, strong) NSMutableArray *enterEffectQueue; @property (nonatomic,strong) SVGAImageView *enterEffectView; #pragma mark - 相亲动画的 @property (nonatomic, strong) NSMutableArray *datingEffectQueue; @property (nonatomic,strong) SVGAImageView *datingEffectView; #pragma mark - 跨房PK @property (nonatomic, strong) NSMutableArray *acrossRoomPKQueue; #pragma mark - 航海 @property (nonatomic, strong) NSMutableArray *sailingQueue; #pragma mark - 涂鸦礼物 @property (nonatomic, strong) NSMutableArray *graffitiGiftQueue; ///幸运礼物动画是否在播放 @property (nonatomic,assign) BOOL isLuckyGiftAnimation; #pragma mark - 心愿礼物 @property (nonatomic,strong) SVGAImageView *wishGiftEffectView; ///礼物飘屏 PresentAchieveAbstractMatrix @property(nonatomic,strong) NSMutableArray *animationListA; ///玩法飘屏 YUMIPresentBigCaptureMatrix @property(nonatomic,strong) NSMutableArray *animationListB; ///礼物飘屏正在播放中 @property(nonatomic,assign) BOOL isPlayOfA; ///玩法飘屏正在播放中 @property(nonatomic,assign) BOOL isPlayOfB; ///animationListA播放完后,如果有animationListB,那么要在animationListA的位置上播放animationListB,只播放一次 //@property(nonatomic,assign) BOOL isAnimationListAFinish; @property(nonatomic,strong) NSMutableArray *svgaQueue; @property(nonatomic,assign) CGFloat broadCastHieght; @end @implementation XPRoomAnimationView - (void)dealloc { [NSObject cancelPreviousPerformRequestsWithTarget:self]; [[NIMSDK sharedSDK].broadcastManager removeDelegate:self]; } -(void)resumeTimer{ if(self.giftEffectTimer != nil){ dispatch_source_cancel(self.giftEffectTimer); self.giftEffectTimer = nil; } if(self.giftTimer != nil){ dispatch_source_cancel(self.giftTimer); self.giftTimer = nil; } [self.giftPagView removeListener:self]; } - (instancetype)initWithDelegate:(id)delegate { self = [super init]; if (self) { [[NIMSDK sharedSDK].broadcastManager addDelegate:self]; self.delegate = delegate; [self initSubViews]; [self initSubViewConstraints]; } return self; } #pragma mark - Private Method - (void)initSubViews { [self addSubview:self.lowLevelView]; [self addSubview:self.middleLevelView]; [self addSubview:self.highLevleView]; } - (void)initSubViewConstraints { [self.lowLevelView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self); }]; [self.middleLevelView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self); }]; [self.highLevleView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self); }]; } //自己是否在游戏中 - (BOOL)isInSudGame { BOOL isGamePlaying = NO; if (self.delegate.getRoomInfo.type == RoomType_MiniGame) { for (int i = -1; i<5; i++) { NSMutableDictionary * micQueue = self.delegate.getMicroQueue; MicroQueueModel *micSequence = [micQueue objectForKey:[NSString stringWithFormat:@"%d", i]]; if (micSequence == nil || micSequence.userInfo == nil) { continue; } if (micSequence.userInfo.uid == [AccountInfoStorage instance].getUid.integerValue && micSequence.userInfo.gameStatus == LittleGamePlayStatus_Plying) { isGamePlaying = YES; break; } } } return isGamePlaying; } #pragma mark - NIMBroadcastDelegate // 广播消息 - (void)onReceiveBroadcastMessage:(NIMBroadcastMessage *)broadcastMessage{ if (![ClientConfig shareConfig].canOpen) { return; } if (broadcastMessage.content) { NSDictionary *msgDictionary = [broadcastMessage.content toJSONObject]; AttachmentModel *attachment = [AttachmentModel modelWithJSON:msgDictionary[@"body"]]; if (attachment.first == CustomMessageType_Gift && attachment.second == Custom_Message_Sub_Gift_ChannelNotify){///广播 全服礼物飘屏 [self receiveBroadcastGift:attachment]; } else if (attachment.first == CustomMessageType_Noble_VIP && attachment.second == Custom_Message_Sub_Room_Noble_LevelUp_Suspend) {///贵族升级全服飘屏 [self receiveNobleLevelUp:attachment]; }else if(attachment.first == CustomMessageType_LuckyBag && attachment.second == Custom_Message_Sub_Room_Gift_LuckBag_FullScree){ [self receiveLuckyGiftBigPrize:attachment]; }else if(attachment.first == CustomMessageType_Graffiti_Star_Kitchen && attachment.second == Custom_Message_Sub_Star_Kitchen_FullScreen){ [self receiveRoomGraffitiStarKitchen:attachment]; }else if(attachment.first == CustomMessageType_Look_Love && attachment.second == Custom_Message_Sub_Look_Love_InRoom_NeedAllMicSend){ [self receiveCandyTreeGiftHighLevle:attachment]; }else if (attachment.first == CustomMessageType_Treasure_Fairy && (attachment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L4 || attachment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5 || attachment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L1 || attachment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L2 || attachment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L3)) { //夺宝精灵 [self receiveTreasureFairyGiftHighLevel:attachment]; }else if (attachment.first == CustomMessageType_Tarot && (attachment.second == Custom_Message_Sub_Tarot_Advanced || attachment.second == Custom_Message_Sub_Tarot_Intermediate)){ [self receiveTarotBanner:attachment]; }else if (attachment.first == CustomMessageType_Common_H5 &&(attachment.second == Custom_Message_Sub_Common_H5_Novice || attachment.second == Custom_Message_Sub_Common_H5_Advanced)){ [self receiveCommonH5Banner:attachment]; } } } #pragma mark - RoomGuestDelegate - (void)handleNIMCustomMessage:(NIMMessage *)message { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { if (![ClientConfig shareConfig].canOpen) { AttachmentModel *attachment = (AttachmentModel *)obj.attachment; if (attachment.first == CustomMessageType_Gift) { GiftReceiveInfoModel * receiveInfo = [GiftReceiveInfoModel modelWithJSON:attachment.data]; receiveInfo.isLuckyBagGift = attachment.second == Custom_Message_Sub_Gift_LuckySend; receiveInfo.isBatch = YES; [self receiveGiftHandleSendGiftAnimation:attachment]; } else if (attachment.first == CustomMessageType_AllMicroSend) { //发送全麦礼物 或者多人礼物 GiftReceiveInfoModel * receiveInfo = [GiftReceiveInfoModel modelWithJSON:attachment.data]; receiveInfo.isLuckyBagGift = (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend); receiveInfo.isBatch = (attachment.second == Custom_Message_Sub_AllBatchSend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend); [self receiveGiftHandleSendGiftAnimation:attachment]; } return; } AttachmentModel *attachment = (AttachmentModel *)obj.attachment; if (attachment.first == CustomMessageType_Gift) { GiftReceiveInfoModel * receiveInfo = [GiftReceiveInfoModel modelWithJSON:attachment.data]; receiveInfo.isLuckyBagGift = attachment.second == Custom_Message_Sub_Gift_LuckySend; receiveInfo.isBatch = YES; [self receiveGiftHandleSendGiftAnimation:attachment]; if (receiveInfo.isLuckyBagGift) { if (!self.delegate.getRoomInfo.hasAnimationEffect) {return;} if (receiveInfo.viewUrl.length > 0) { [self playLuckyGiftEffectWithVapUrl:receiveInfo.viewUrl]; } else { NSString * svgaString = receiveInfo.luckyGiftSvgaUrl.length > 0 ? receiveInfo.luckyGiftSvgaUrl : receiveInfo.gift.luckyGiftSvgaUrl; NSURL * luckyGiftSvgaUrl = [NSURL URLWithString:svgaString]; if (luckyGiftSvgaUrl.absoluteString.length > 0) { [self playLuckyGiftEffect:luckyGiftSvgaUrl]; } } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self receiveGift:receiveInfo]; }); } else { [self receiveGift:receiveInfo]; } } else if (attachment.first == CustomMessageType_AllMicroSend) { //发送全麦礼物 或者多人礼物 GiftReceiveInfoModel * receiveInfo = [GiftReceiveInfoModel modelWithJSON:attachment.data]; receiveInfo.isLuckyBagGift = (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend); receiveInfo.isBatch = (attachment.second == Custom_Message_Sub_AllBatchSend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend); [self receiveGiftHandleSendGiftAnimation:attachment]; if (receiveInfo.isLuckyBagGift) { if (!self.delegate.getRoomInfo.hasAnimationEffect) {return;} if (receiveInfo.viewUrl.length > 0) { [self playLuckyGiftEffectWithVapUrl:receiveInfo.viewUrl]; } else { NSString * svgaString = receiveInfo.luckyGiftSvgaUrl.length > 0 ? receiveInfo.luckyGiftSvgaUrl : receiveInfo.gift.luckyGiftSvgaUrl; NSURL * luckyGiftSvgaUrl = [NSURL URLWithString:svgaString]; if (luckyGiftSvgaUrl.absoluteString.length > 0) { [self playLuckyGiftEffect:luckyGiftSvgaUrl]; } } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self receiveGift:receiveInfo]; }); } else { [self receiveGift:receiveInfo]; } } else if (attachment.first == CustomMessageType_LuckyBag ) {//福袋消息厅内展示 [self receiveLuckyGiftBigPrize:attachment]; } else if (attachment.first == CustomMessageType_Look_Love && (attachment.second == Custom_Message_Sub_Look_Love_AllRoom_Notify) ) {//寻爱之旅 [self receiveCandyTreeGiftHighLevle:attachment]; } else if (attachment.first == CustomMessageType_Car_Notify && attachment.second == Custom_Message_Sub_Car_EnterRoom ) {//座驾进房 [self receiveDriveCarEnterRoom:attachment]; } else if(attachment.first == CustomMessageType_RoomPlay_Dating && attachment.second == Custom_Message_Sub_Room_Play_Dating_Public_Result) { [self roomDatingPublicResult:attachment]; } else if(attachment.first == CustomMessageType_Across_Room_PK && attachment.second == Custom_Message_Sub_AcrossRoomPK_Result) { [self acrossRoomPKBannerAnimation:attachment]; } else if (attachment.first == CustomMessageType_Anchor_FansTeam && attachment.second == Custom_Message_Sub_FansTeam_Join_Success) {///个播粉丝团 GiftReceiveInfoModel *receiveInfo = [[GiftReceiveInfoModel alloc] init]; GiftInfoModel *giftInfo = [GiftInfoModel modelWithJSON:attachment.data[@"giftVo"]]; receiveInfo.gift = giftInfo; receiveInfo.giftInfo = giftInfo; [self receiveFansTeamGiftHandleSendGiftAnimation:attachment]; [self receiveGift:receiveInfo]; } else if (attachment.first == CustomMessageType_Across_Room_PK && attachment.second == Custom_Message_Sub_AnchorPK_Result) {//个播PK横幅 [self acrossRoomPKBannerAnimation:attachment]; } else if (attachment.first == CustomMessageType_Anchor_Hour_Rank && attachment.second == Custom_Message_Sub_Anchor_Hour_Rank) {///个播小时榜 [self receiveAnchorHourRank:attachment]; } else if (attachment.first == CustomMessageType_Licnese_Hour_Rank && attachment.second == Custom_Message_Sub_Licnese_Hour_Rank) {///牌照房小时榜 [self receiveAnchorHourRank:attachment]; } else if (attachment.first == CustomMessageType_Gift_Compound && attachment.second == Custom_Message_Sub_Gift_Compound) {///魔法小屋合成礼物 [self receiveGiftCompound:attachment]; } else if(attachment.first == CustomMessageType_Room_Sailing && (attachment.second == Custom_Message_Sub_Sailing_AllRoom_Notify || attachment.second == Custom_Message_Sub_Sailing_InRoom_NeedAllMicSend)) { [self receiveRoomSailing:attachment]; } else if(attachment.first == CustomMessageType_Graffiti_Gift) {///涂鸦礼物 [self receiveRoomGraffitiGift:attachment]; } else if(attachment.first == CustomMessageType_Graffiti_Star_Kitchen){///星级厨房飘屏 [self receiveRoomGraffitiStarKitchen:attachment]; }else if (attachment.first == CustomMessageType_Treasure_Fairy && (attachment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L4 || attachment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L1 || attachment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L2 || attachment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L3)) { //夺宝精灵 [self receiveTreasureFairyGiftHighLevel:attachment]; }else if (attachment.first == CustomMessageType_Tarot && (attachment.second == Custom_Message_Sub_Tarot_Advanced || attachment.second == Custom_Message_Sub_Tarot_Intermediate)){ PIBaseAnimationViewModel *giftNotifyInfo = [PIBaseAnimationViewModel modelWithJSON:attachment.data]; if(attachment.second == Custom_Message_Sub_Tarot_Intermediate && self.delegate.getRoomInfo.uid != giftNotifyInfo.roomUid.integerValue){ return; } [self receiveTarotBanner:attachment]; }else if (attachment.first == CustomMessageType_Common_H5 &&(attachment.second == Custom_Message_Sub_Common_H5_Novice || attachment.second == Custom_Message_Sub_Common_H5_Advanced)){ [self receiveCommonH5Banner:attachment]; } } } - (void)handleNIMNotificationMessage:(NIMMessage *)message { NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject; NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content; if (content.eventType == NIMChatroomEventTypeEnter) { NIMMessageChatroomExtension * messageExt = (NIMMessageChatroomExtension *)message.messageExt; NSDictionary * dic = [(NSDictionary *)messageExt.roomExt.toJSONObject objectForKey:message.from]; XPMessageRemoteExtModel * extModel = [XPMessageRemoteExtModel modelWithJSON:dic]; if (extModel.enterHide) {//隐身进房 if ([message.from isEqualToString:[AccountInfoStorage instance].getUid]) { [self createEnterHideAnimation:dic]; } return; } [self userEnterRoom:content ext:extModel]; } } #pragma mark - 收到星级厨房飘屏 -(void)receiveRoomGraffitiStarKitchen:(AttachmentModel *)attacment{ PIBaseAnimationViewModel *roomGraffiti = [PIBaseAnimationViewModel new]; roomGraffiti.data = attacment.data; roomGraffiti.type = GiftBannerType_kitchen; roomGraffiti.first = attacment.first; roomGraffiti.second = attacment.second; if(self.animationListB.count == 0 && self.isPlayOfB == NO){ [self createStarKitchenBannerAnimation:roomGraffiti]; } [self.animationListB addObject:roomGraffiti]; } - (void)createStarKitchenBannerAnimation:(PIBaseAnimationViewModel *)attacment{ self.isPlayOfB = YES; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); XPRoomStarKitchenBannerView *starKitchenView = [[XPRoomStarKitchenBannerView alloc]initWithFrame:CGRectMake(0, top, KScreenWidth, kGetScaleWidth(60))]; starKitchenView.isSvga = attacment.second == Custom_Message_Sub_Star_Kitchen_FullScreen; XPRoomStarKitchenModel *starModel = [XPRoomStarKitchenModel modelWithDictionary:attacment.data]; starKitchenView.delegate = self; starKitchenView.starModel = starModel; [self.highLevleView addSubview:starKitchenView]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:starKitchenView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(starKitchenView.frame.size.width / 2, starKitchenView.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, starKitchenView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, starKitchenView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [starKitchenView removeFromSuperview]; self.isPlayOfB = NO; if(self.animationListB.count > 0){ [self.animationListB removeObjectAtIndex:0]; } // if(self. isAnimationListAFinish == YES){ // // [self playAnimationWithModel]; // self.isAnimationListAFinish = NO; // return; // } [self playAnimationWithModel]; } }]; [starKitchenView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [starKitchenView pop_addAnimation:springAnimation forKey:@"starKitchenOutAnimation"]; } #pragma mark - XPRoomStarKitchenBannerViewDelegate - (void)xPRoomStarKitchenBannerView:(XPRoomStarKitchenBannerView *)view didClick:(XPRoomStarKitchenModel *)starModel{ if(starModel.skipUrl == nil || starModel.skipUrl.length == 0)return; XPWebViewController * webVC = [[XPWebViewController alloc] init]; webVC.isPush = YES; webVC.roomUid = starModel.roomUid; webVC.url = starModel.skipUrl; [self.delegate.getCurrentNav pushViewController:webVC animated:YES]; } #pragma mark - 收到h5通用飘屏 -(void)receiveCommonH5Banner:(AttachmentModel *)attachment{ if ([self isInSudGame]) {return;} PIBaseAnimationViewModel *giftNotifyInfo = [PIBaseAnimationViewModel modelWithJSON:attachment.data]; giftNotifyInfo.type = GiftBannerType_Common_H5; giftNotifyInfo.second = attachment.second; if (self.animationListB.count == 0 && self.isPlayOfB == NO) { [self createCommonH5BannerAnimation:giftNotifyInfo]; } [self.animationListB addObject:giftNotifyInfo]; } - (void)createCommonH5BannerAnimation:(PIBaseAnimationViewModel *)attatchment { CGFloat kscale = (CGFloat)55 / (CGFloat)375; self.isPlayOfB = YES; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); XPRoomTarrowBannerView *tarrowVeiw = [[XPRoomTarrowBannerView alloc]initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth , KScreenWidth * kscale)isH5:YES]; tarrowVeiw.isBig = attatchment.second == Custom_Message_Sub_Common_H5_Advanced; tarrowVeiw.giftH5Info = attatchment; [self.middleLevelView addSubview:tarrowVeiw]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:tarrowVeiw.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(tarrowVeiw.frame.size.width / 2, tarrowVeiw.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, tarrowVeiw.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2,tarrowVeiw.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [tarrowVeiw removeFromSuperview]; self.isPlayOfB = NO; if (self.animationListB.count > 0) { [self.animationListB removeObjectAtIndex:0]; } // if(self. isAnimationListAFinish == YES){ // // [self playAnimationWithModel]; // self.isAnimationListAFinish = NO; // return; // } [self playAnimationWithModel]; } }]; [tarrowVeiw pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [tarrowVeiw pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"]; } #pragma mark - 收到塔罗飘屏 -(void)receiveTarotBanner:(AttachmentModel *)attachment{ if ([self isInSudGame]) {return;} PIBaseAnimationViewModel *giftNotifyInfo = [PIBaseAnimationViewModel modelWithJSON:attachment.data]; giftNotifyInfo.type = GiftBannerType_Tarrow; giftNotifyInfo.second = attachment.second; if (self.animationListB.count == 0 && self.isPlayOfB == NO) { [self createTarotBannerAnimation:giftNotifyInfo]; } [self.animationListB addObject:giftNotifyInfo]; } - (void)createTarotBannerAnimation:(PIBaseAnimationViewModel *)attatchment { CGFloat kscale = (CGFloat)55 / (CGFloat)375; self.isPlayOfB = YES; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); XPRoomTarrowBannerView *tarrowVeiw = [[XPRoomTarrowBannerView alloc]initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth , KScreenWidth * kscale)isH5:NO]; tarrowVeiw.isBig = attatchment.second == Custom_Message_Sub_Tarot_Advanced; tarrowVeiw.giftInfo = attatchment; [self.middleLevelView addSubview:tarrowVeiw]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:tarrowVeiw.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(tarrowVeiw.frame.size.width / 2, tarrowVeiw.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, tarrowVeiw.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2,tarrowVeiw.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [tarrowVeiw removeFromSuperview]; self.isPlayOfB = NO; if (self.animationListB.count > 0) { [self.animationListB removeObjectAtIndex:0]; } // if(self. isAnimationListAFinish == YES){ // // [self playAnimationWithModel]; // self.isAnimationListAFinish = NO; // return; // } [self playAnimationWithModel]; } }]; [tarrowVeiw pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [tarrowVeiw pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"]; } #pragma mark - 夺宝精灵横幅 - (void)receiveTreasureFairyGiftHighLevel:(AttachmentModel *)attatchment { if ([self isInSudGame]) {return;} PIBaseAnimationViewModel *giftModel = [PIBaseAnimationViewModel new]; giftModel.data = attatchment.data; giftModel.second = attatchment.second; giftModel.first = attatchment.first; giftModel.type = GiftBannerType_Fairy; if (self.animationListB.count == 0 && self.isPlayOfB == NO) { [self createTreasureFairyBannerAnimation:giftModel]; } [self.animationListB addObject:giftModel]; } - (void)createTreasureFairyBannerAnimation:(PIBaseAnimationViewModel *)attatchment { self.isPlayOfB = YES; CGFloat kscale = (CGFloat)60 / (CGFloat)375; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); XPTreasureFairyGiftView *treasureView = [[XPTreasureFairyGiftView alloc] initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth , KScreenWidth * kscale)]; //最大礼物 if ((attatchment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5) || (attatchment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L3)) { treasureView.isMaxLargeGift = YES; }else{ treasureView.isMaxLargeGift = NO; } if ((attatchment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L4) || (attatchment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5)) { treasureView.isDrawGift = YES; //抽奖 }else{ treasureView.isDrawGift = NO; //召唤 } treasureView.treasureInfo = attatchment.data; [self.middleLevelView addSubview:treasureView]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:treasureView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(treasureView.frame.size.width / 2, treasureView.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, treasureView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, treasureView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [treasureView removeFromSuperview]; self.isPlayOfB = NO; if (self.animationListB.count > 0) { [self.animationListB removeObjectAtIndex:0]; } // if(self. isAnimationListAFinish == YES){ // // [self playAnimationWithModel]; // self.isAnimationListAFinish = NO; // return; // } [self playAnimationWithModel]; } }]; [treasureView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [treasureView pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"]; } #pragma mark - 涂鸦礼物动画 - (void)receiveRoomGraffitiGift:(AttachmentModel *)attacment { if (self.graffitiGiftQueue.count == 0) { [self startGraffitiGiftAnimation:attacment]; } [self.graffitiGiftQueue addObject:attacment]; } - (void)startGraffitiGiftAnimation:(AttachmentModel *)model { NSDictionary * dic = model.data; NSNumber * giftId = dic[@"giftId"]; GiftInfoModel * giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:giftId.stringValue]; NSArray * array = dic[@"drawFixedArray"]; if (giftInfo.giftUrl.length > 0 && array.count > 0) { [[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:giftInfo.giftUrl] options:SDWebImageProgressiveLoad progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) { if (error == nil && image) { XPRoomGraffitiGiftAnimationView *graffitiView = [[XPRoomGraffitiGiftAnimationView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; graffitiView.giftImage = image; graffitiView.delegate = self; graffitiView.model = model; graffitiView.pointArray = array; [graffitiView beginDrawAnimation]; [self.highLevleView addSubview:graffitiView]; } else { [self.graffitiGiftQueue removeObject:model]; if (self.graffitiGiftQueue.count > 0) { [self startGraffitiGiftAnimation:self.graffitiGiftQueue.firstObject]; } } }]; } else { [self.graffitiGiftQueue removeObject:model]; if (self.graffitiGiftQueue.count > 0) { [self startGraffitiGiftAnimation:self.graffitiGiftQueue.firstObject]; } } } - (void)xPRoomGraffitiGiftAnimationViewCompletion:(XPRoomGraffitiGiftAnimationView *)view attachment:(nonnull AttachmentModel *)attachment{ [view removeFromSuperview]; if ([self.graffitiGiftQueue containsObject:attachment]) { [self.graffitiGiftQueue removeObject:attachment]; } if (self.graffitiGiftQueue.count > 0) { [self startGraffitiGiftAnimation:self.graffitiGiftQueue.firstObject]; } } #pragma mark - 跨房PK横幅动画 - (void)acrossRoomPKBannerAnimation:(AttachmentModel *)attacment { AcrossRoomPKPrizeModel * prizeModel = [AcrossRoomPKPrizeModel modelWithJSON:attacment.data]; if (attacment.second == Custom_Message_Sub_AnchorPK_Result) { prizeModel.pkType = 1; } else { prizeModel.pkType = 0; } [self.acrossRoomPKQueue addObject:prizeModel]; if (self.acrossRoomPKQueue.count == 1 ) {//判断为1个时开始播放,防止多条消息回来后重叠播放 [self startAcrossRoomPKAnimation:self.acrossRoomPKQueue.firstObject]; } } - (void)startAcrossRoomPKAnimation:(AcrossRoomPKPrizeModel *)model { XPAcrossRoomPKPrizeView *wishEffectView = [[XPAcrossRoomPKPrizeView alloc] initWithFrame:CGRectMake(KScreenWidth, kNavigationHeight+40, KScreenWidth, 87)]; wishEffectView.data = model; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gotoPkWinRoom:)]; [wishEffectView addGestureRecognizer:tap]; [self.highLevleView addSubview:wishEffectView]; [UIView animateWithDuration:0.5 animations:^{ wishEffectView.frame = CGRectMake(0, kNavigationHeight+40, KScreenWidth, 87); } completion:^(BOOL finished) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [UIView animateWithDuration:0.5 animations:^{ wishEffectView.hidden = YES; } completion:^(BOOL finished) { [wishEffectView removeFromSuperview]; [self.acrossRoomPKQueue removeObject:model]; if (self.acrossRoomPKQueue.count > 0) { [self startAcrossRoomPKAnimation:self.acrossRoomPKQueue.firstObject]; } }]; }); }]; } - (void)gotoPkWinRoom:(UITapGestureRecognizer *)tap { XPAcrossRoomPKPrizeView * view = (XPAcrossRoomPKPrizeView *)tap.view; if (view.data.winUid.length > 0) { [self.delegate exitRoom]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:view.data.winUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } } #pragma mark - 相亲 动画 - (void)roomDatingPublicResult:(AttachmentModel *)attachment { self.datingEffectQueue = [NSMutableArray array]; ///心动结果公布的话 结果是一个数组 NSArray * results = [DatingInfoModel modelsWithArray:attachment.data[@"list"]]; [self.datingEffectQueue addObjectsFromArray:results]; if (self.datingEffectQueue.count > 0) { [self startDatingAnimation:self.datingEffectQueue.firstObject]; } } - (void)startDatingAnimation:(DatingInfoModel *)datingModel { [[NSNotificationCenter defaultCenter] postNotificationName:@"message" object:[self createRoomDatingResultMessage:datingModel]]; NSString * targetUid= [NSString stringWithFormat:@"%ld", datingModel.targetUid]; NSString * uid= [NSString stringWithFormat:@"%ld", datingModel.uid]; if (datingModel.hasHeart || datingModel.hasSelectUser) { datingModel.originPoint = [self.delegate animationPointAtStageViewByUid:uid]; datingModel.targetPoint = [self.delegate animationPointAtStageViewByUid:targetUid]; } XPRoomDatingAnimationView * datingView = [[XPRoomDatingAnimationView alloc] init]; [self.highLevleView addSubview:datingView]; [datingView startAnimationWithModel:datingModel finishBlock:^(BOOL finish) { [datingView removeFromSuperview]; [self.datingEffectQueue removeObject:datingModel]; if (self.datingEffectQueue.count > 0) { DatingInfoModel * datingModel = [self.datingEffectQueue firstObject]; [self startDatingAnimation:datingModel]; } }]; } - (NIMMessage *)createRoomDatingResultMessage:(DatingInfoModel *)datingModel { NIMMessage * message = [[NIMMessage alloc] init]; NIMSession * session = [NIMSession session:[NSString stringWithFormat:@"%ld", self.delegate.getRoomInfo.roomId] type:NIMSessionTypeChatroom]; [message setValue:session forKey:@"session"]; AttachmentModel * attach = [[AttachmentModel alloc] init]; attach.first = CustomMessageType_RoomPlay_Dating; if (datingModel.hasHeart) {///如果是互选的话 attach.second = Custom_Message_Sub_Room_Play_Dating_Result_Mutual; } else { attach.second = Custom_Message_Sub_Room_Play_Dating_Result_Not_Mutual; } attach.data = [datingModel model2dictionary]; NIMCustomObject * object = [[NIMCustomObject alloc] init]; object.attachment = attach; message.messageObject = object; return message; } #pragma mark - 进房动画 XXX来了 - (void)userEnterRoom:(NIMChatroomNotificationContent *)content ext:(XPMessageRemoteExtModel *)extModel { if (extModel.experLevelSeq < 30) return; NSString * title = [NSString stringWithFormat:YMLocalizedString(@"XPRoomAnimationView0"), content.source.nick]; if (self.enterEffectQueue.count ==0) { [self playUserEnterRoomAnimation:title experLevelSeq:extModel.experLevelSeq effectPath:extModel.enterRoomEffects]; } NSDictionary * dic= @{@"title":title, @"experLevelSeq":[NSString stringWithFormat:@"%ld", extModel.experLevelSeq], @"effectPath" : extModel.enterRoomEffects.length ? extModel.enterRoomEffects : @""}; [self.enterEffectQueue addObject:dic]; } - (void)playUserEnterRoomAnimation:(NSString *)title experLevelSeq:(NSInteger)experLevelSeq effectPath:(NSString *)effectPath { NSString * path; if (experLevelSeq >= 30 && experLevelSeq <= 39) { path = @"svga_member_in_lv30"; } else if (experLevelSeq >= 40 && experLevelSeq <= 49) { path = @"svga_member_in_lv40"; } else if (experLevelSeq >= 50 && experLevelSeq <= 59) { path = @"svga_member_in_lv50"; } else if (experLevelSeq >= 60 && experLevelSeq <= 69) { path = @"svga_member_in_lv60"; } else if (experLevelSeq >= 70 && experLevelSeq <= 79) { path = @"svga_member_in_lv70"; } else if (experLevelSeq >= 80 && experLevelSeq <= 89) { path = @"svga_member_in_lv80"; } else { path = @"svga_member_in_lv90"; } NSString * anatomiser1Name = [NSString stringWithFormat:@"%@/%@.svga", API_Image_URL, path]; if (self.enterEffectView.superview == nil) { self.enterEffectView.frame = CGRectMake(KScreenWidth, 339 + kSafeAreaTopHeight, KScreenWidth, effectPath.length ? 75 : 40); [self.lowLevelView addSubview:self.enterEffectView]; } NSMutableAttributedString * attribute = [[NSMutableAttributedString alloc] initWithString:title attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:26], NSForegroundColorAttributeName:[UIColor whiteColor]}]; [attribute setYy_alignment:NSTextAlignmentLeft]; if (effectPath.length > 0) { @kWeakify(self); [self.parser parseWithURL:[NSURL URLWithString:effectPath] completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { @kStrongify(self); self.enterEffectView.loops = 1; self.enterEffectView.hidden = NO; self.enterEffectView.clearsAfterStop = NO; self.enterEffectView.alpha = 1; self.enterEffectView.videoItem = videoItem; [self.enterEffectView setAttributedText:attribute forKey:@"room_text"]; [self.enterEffectView startAnimation]; } failureBlock:^(NSError * _Nonnull error) { }]; } else { @kWeakify(self); [self.parser parseWithURL:[NSURL URLWithString:anatomiser1Name] completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { @kStrongify(self); self.enterEffectView.loops = 1; self.enterEffectView.hidden = NO; self.enterEffectView.clearsAfterStop = NO; self.enterEffectView.alpha = 1; self.enterEffectView.videoItem = videoItem; [self.enterEffectView setAttributedText:attribute forKey:@"room_text"]; [self.enterEffectView startAnimation]; } failureBlock:^(NSError * _Nonnull error) { }]; } [UIView animateWithDuration:0.5 animations:^{ self.enterEffectView.frame = CGRectMake(0, 339 + kSafeAreaTopHeight, KScreenWidth, effectPath.length ? 75 : 40); } completion:^(BOOL finished) { }]; } ///自己的隐身进房提示 - (void)createEnterHideAnimation:(NSDictionary *)dic { XPRoomEnterHideTipView *enterHideTipView = [[XPRoomEnterHideTipView alloc] initWithFrame:CGRectMake(KScreenWidth, (KScreenHeight - 48) * 0.5, KScreenWidth, 48)]; [self.highLevleView addSubview:enterHideTipView]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:enterHideTipView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(enterHideTipView.frame.size.width / 2, enterHideTipView.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, enterHideTipView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, enterHideTipView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { [enterHideTipView removeFromSuperview]; } }]; [enterHideTipView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [enterHideTipView pop_addAnimation:springAnimation forKey:@"roomEnterTipUpspingOutAnimation"]; } #pragma mark - 座驾的动画 - (void)receiveDriveCarEnterRoom:(AttachmentModel *)attatchment { if (self.isLargeGiftAnimating) {return;} if ([self isInSudGame]) {return;} if (!self.delegate.getRoomInfo.hasAnimationEffect) {return;} NSInteger otherViewType = [attatchment.data[@"otherViewType"] integerValue]; NSString *viewUrl = attatchment.data[@"viewUrl"]; NSString * effect = attatchment.data[@"effect"]; if (viewUrl.length) { NSDictionary * dic = @{@"otherViewType":@(otherViewType), @"viewUrl":viewUrl}; if (self.carEffectQueue.count == 0) { [self playCarEffect:dic]; } [self.carEffectQueue addObject:dic]; } else if(effect.length) { NSDictionary * dic = @{@"effect":effect}; if (self.carEffectQueue.count == 0) { [self playCarEffect:dic]; } [self.carEffectQueue addObject:dic]; } } - (void)playCarEffect:(NSDictionary *)effectDict { NSString *viewUrl = [effectDict objectForKey:@"viewUrl"]; NSString *carEffect = [effectDict objectForKey:@"effect"]; if (viewUrl.length) { [self.vapParser parseWithURL:viewUrl completionBlock:^(NSString * _Nullable videoUrl) { if (videoUrl.length) { if([videoUrl containsString:@".pag"]){ self.carPagView.hidden = NO; if(self.carPagView.superview == nil){ [self.middleLevelView addSubview:self.carPagView]; [self.carPagView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; [self.carPagView setPath:videoUrl]; self.carPagView.userInteractionEnabled = NO; self.carPagView.repeatCount = 1; self.carPagView.scaleMode = PAGScaleModeStretch; [self.carPagView play]; } return; } self.carVapEffectView.hidden = NO; if (self.carVapEffectView.superview == nil) { [self.middleLevelView addSubview:self.carVapEffectView]; [self.carVapEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } [self.carVapEffectView setMute:YES]; [self.carVapEffectView playHWDMP4:videoUrl repeatCount:1 delegate:self]; } } failureBlock:^(NSError * _Nullable error) { }]; } else if (carEffect.length) { [self.parser parseWithURL:[NSURL URLWithString:carEffect] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) { if (videoItem != nil) { if (self.carEffectView.superview == nil) { [self.middleLevelView addSubview:self.carEffectView]; [self.carEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } CGFloat width = videoItem.videoSize.width; CGFloat height = videoItem.videoSize.height; if (width > height) { self.carEffectView.contentMode = UIViewContentModeScaleAspectFit; } else {//高大于宽 CGFloat resizeH = KScreenWidth * height / width;//按照屏幕的宽度去缩放,获得高度 if (resizeH > KScreenHeight) {//如果大于屏幕高度,填充 self.carEffectView.contentMode = UIViewContentModeScaleAspectFill; } else {//小于屏幕高度, self.carEffectView.contentMode = UIViewContentModeScaleAspectFit; } } self.carEffectView.hidden = NO; self.carEffectView.alpha = 1; self.carEffectView.loops = 1; self.carEffectView.clearsAfterStop = YES; self.carEffectView.videoItem = videoItem; [self.carEffectView startAnimation]; } } failureBlock:^(NSError * _Nullable error) { }]; } } #pragma mark - 糖果树横幅动画 - (void)receiveCandyTreeGiftHighLevle:(AttachmentModel *)attatchment { if ([self isInSudGame]) {return;} PIBaseAnimationViewModel *giftModel = [PIBaseAnimationViewModel new]; giftModel.data = attatchment.data; giftModel.second = attatchment.second; giftModel.first = attatchment.first; giftModel.type = GiftBannerType_Love; if (self.animationListB.count == 0 && self.isPlayOfB == NO) { [self createCandyTreeBannerAnimation:giftModel]; } [self.animationListB addObject:giftModel]; } - (void)createCandyTreeBannerAnimation:(PIBaseAnimationViewModel *)attatchment { CGFloat kscale = (CGFloat)60 / (CGFloat)375; self.isPlayOfB = YES; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); XPRoomCandyGiftView *candyTreeView = [[XPRoomCandyGiftView alloc] initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth , KScreenWidth * kscale)]; candyTreeView.isMaxLargeGift = attatchment.second == Custom_Message_Sub_Look_Love_InRoom_NeedAllMicSend; candyTreeView.candyInfo = attatchment.data; [self.middleLevelView addSubview:candyTreeView]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:candyTreeView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(candyTreeView.frame.size.width / 2, candyTreeView.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, candyTreeView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, candyTreeView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [candyTreeView removeFromSuperview]; self.isPlayOfB = NO; if (self.animationListB.count > 0) { [self.animationListB removeObjectAtIndex:0]; } // if(self. isAnimationListAFinish == YES){ // // [self playAnimationWithModel]; // self.isAnimationListAFinish = NO; // return; // } [self playAnimationWithModel]; } }]; [candyTreeView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [candyTreeView pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"]; } #pragma mark - 航海横幅 - (void)receiveRoomSailing:(AttachmentModel *)attachment { if ([self isInSudGame]) {return;} if (self.sailingQueue.count == 0) { [self createSailingBannerAnimation:attachment]; } [self.sailingQueue addObject:attachment]; } - (void)createSailingBannerAnimation:(AttachmentModel *)attatchment { CGFloat kscale = (CGFloat)60 / (CGFloat)375; XPSailingAnimationView *sailingView = [[XPSailingAnimationView alloc] initWithFrame:CGRectMake(KScreenWidth, kNavigationHeight + 15, KScreenWidth, KScreenWidth * kscale)]; sailingView.prizeInfo = attatchment.data; [self.middleLevelView addSubview:sailingView]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:sailingView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(sailingView.frame.size.width / 2, sailingView.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, sailingView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, sailingView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [sailingView removeFromSuperview]; if (self.sailingQueue.count > 0) { [self.sailingQueue removeObjectAtIndex:0]; } if (self.sailingQueue.count > 0) { [self createSailingBannerAnimation:self.sailingQueue.firstObject]; } } }]; [sailingView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [sailingView pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"]; } #pragma mark - 贵族升级 - (void)receiveNobleLevelUp:(AttachmentModel *)attachment { [[NetImageView new]loadImageWithUrl:attachment.data[@"avatar"] completion:^(UIImage * _Nonnull image, NSURL * _Nonnull url) { PIBaseAnimationViewModel *nobleModel = [PIBaseAnimationViewModel new]; nobleModel.data = attachment.data; nobleModel.type = GiftBannerType_Nobleman; if (self.animationListB.count == 0 && self.isPlayOfB == NO) { [self createNobleLevelUpBannerAnimation:nobleModel]; } [self.animationListB addObject:nobleModel]; }]; } - (void)createNobleLevelUpBannerAnimation:(PIBaseAnimationViewModel *)model { self.isPlayOfB = YES; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); XPRoomNobleLevelUpView *nobleLevelUpView = [[XPRoomNobleLevelUpView alloc] initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth, 90)]; nobleLevelUpView.nobleInfo = model.data; [self.highLevleView addSubview:nobleLevelUpView]; @kWeakify(self); @kWeakify(nobleLevelUpView); nobleLevelUpView.completionBlock = ^{ @kStrongify(self); @kStrongify(nobleLevelUpView); POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:nobleLevelUpView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(nobleLevelUpView.frame.size.width / 2, nobleLevelUpView.center.y)]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, nobleLevelUpView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, nobleLevelUpView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { self.isPlayOfB = NO; [nobleLevelUpView removeFromSuperview]; if (self.animationListB.count > 0) { [self.animationListB removeObjectAtIndex:0]; } // if(self.isAnimationListAFinish == YES){ // // [self playAnimationWithModel]; // self.isAnimationListAFinish = NO; // return; // } [self playAnimationWithModel]; } }]; [nobleLevelUpView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; }); [nobleLevelUpView pop_addAnimation:springAnimation forKey:@"nobleLevelUpspingOutAnimation"]; }; } #pragma mark - 魔法小屋礼物合成 - (void)receiveGiftCompound:(AttachmentModel *)attachment { if ([self isInSudGame]) {return;} PIBaseAnimationViewModel *magicModel =[PIBaseAnimationViewModel new]; magicModel.data = attachment.data; magicModel.type = GiftBannerType_Magic_House; if(self.animationListB.count == 0 && self.isPlayOfB == NO){ [self createGiftCompoundBannerAnimation:magicModel]; } [self.animationListB addObject:magicModel]; } - (void)createGiftCompoundBannerAnimation:(PIBaseAnimationViewModel *)attachment { self.isPlayOfB = YES; XPRoomGiftCompoundView *compoundGiftView = [[XPRoomGiftCompoundView alloc] initWithFrame:CGRectMake(KScreenWidth, kNavigationHeight + 15, KScreenWidth, 45)]; compoundGiftView.compoundGiftInfo = attachment.data; [self.middleLevelView addSubview:compoundGiftView]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:compoundGiftView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(compoundGiftView.frame.size.width / 2, compoundGiftView.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, compoundGiftView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, compoundGiftView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [compoundGiftView removeFromSuperview]; self.isPlayOfB = NO; if(self.animationListB.count > 0){ [self.animationListB removeObjectAtIndex:0]; } // if(self.isAnimationListAFinish == YES){ // self.isAnimationListAFinish = NO; // [self playAnimationWithModel]; // return; // } [self playAnimationWithModel]; } }]; [compoundGiftView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [compoundGiftView pop_addAnimation:springAnimation forKey:@"compoundGiftSpingOutAnimation"]; } #pragma mark - XPRoomAnchorRankBannerViewDelegate - (void)xPRoomAnchorRankBannerView:(XPRoomAnchorRankBannerView *)view rankInfo:(RoomHalfHourRankModel *)rankInfo{ if (rankInfo.uid.integerValue > 0 && self.delegate.getRoomInfo.uid != rankInfo.uid.integerValue) { [self.delegate exitRoom]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:rankInfo.uid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } } #pragma mark - 个播小时榜飘屏或牌照房小时榜飘屏 - (void)receiveAnchorHourRank:(AttachmentModel *)attachment { PIBaseAnimationViewModel *anchorModel =[PIBaseAnimationViewModel new]; anchorModel.data = attachment.data; anchorModel.type = GiftBannerType_AnchorHour; if(self.animationListB.count == 0 && self.isPlayOfB == NO){ [self createAnchorHourRankAnimation:anchorModel]; } [self.animationListB addObject:anchorModel]; } - (void)createAnchorHourRankAnimation:(PIBaseAnimationViewModel *)attachment { self.isPlayOfB = YES; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); XPRoomAnchorRankBannerView *anchorRankView = [[XPRoomAnchorRankBannerView alloc] initWithFrame:CGRectMake(KScreenWidth,top, KScreenWidth, kGetScaleWidth(55))]; anchorRankView.anchorRankInfo = [RoomHalfHourRankModel modelWithDictionary:attachment.data]; anchorRankView.delegate = self; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gotoTopRankAnchorRoom:)]; [anchorRankView addGestureRecognizer:tap]; [self.highLevleView addSubview:anchorRankView]; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:anchorRankView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(anchorRankView.frame.size.width / 2, anchorRankView.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, anchorRankView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, anchorRankView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + 3; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { [anchorRankView removeFromSuperview]; self.isPlayOfB = NO; if(self.animationListB.count > 0){ [self.animationListB removeObjectAtIndex:0]; } // if(self.isAnimationListAFinish == YES){ // self.isAnimationListAFinish = NO; // [self playAnimationWithModel]; // return; // } [self playAnimationWithModel]; }]; [anchorRankView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } }]; [anchorRankView pop_addAnimation:springAnimation forKey:@"nobleLevelUpspingOutAnimation"]; } - (void)gotoTopRankAnchorRoom:(UITapGestureRecognizer *)tap { XPRoomAnchorRankBannerView * view = (XPRoomAnchorRankBannerView *)tap.view; if (view.anchorRankInfo.uid.integerValue > 0) { [self.delegate exitRoom]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:view.anchorRankInfo.uid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } } #pragma mark - 展示加入粉丝团送礼动画 - (void)receiveFansTeamGiftHandleSendGiftAnimation:(AttachmentModel *)attachment { if ([self isInSudGame]) {return;} if (!self.delegate.getRoomInfo.hasAnimationEffect) {return;} GiftReceiveInfoModel *receiveInfo = [[GiftReceiveInfoModel alloc] init]; GiftInfoModel *gift = [GiftInfoModel modelWithJSON:attachment.data[@"giftVo"]]; receiveInfo.gift = gift; receiveInfo.giftInfo = gift; receiveInfo.targetUid = [NSString stringWithFormat:@"%ld", self.delegate.getRoomInfo.uid]; GiftInfoModel * giftInfo = receiveInfo.gift ? receiveInfo.gift : receiveInfo.giftInfo; if (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend || attachment.second == Custom_Message_Sub_Gift_LuckySend) { NSString * giftId = [NSString stringWithFormat:@"%ld", receiveInfo.luckyGiftList.giftList.firstObject.giftId]; giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:giftId]; } if (giftInfo == nil) { giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:receiveInfo.giftId]; } ///在最外面判断是否可以拿到那个礼物 后面使用就不用判断了 receiveInfo.gift = giftInfo; receiveInfo.isLuckyBagGift = (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend || attachment.second == Custom_Message_Sub_Gift_LuckySend); [self.giftQueue addObject:receiveInfo]; if (self.giftTimer == nil && self.giftQueue > 0) { [self startGiftQueueTimer]; } } #pragma mark - 收到礼物展示动画 - (void)receiveGiftHandleSendGiftAnimation:(AttachmentModel *)attachment { if ([self isInSudGame]) {return;} if (!self.delegate.getRoomInfo.hasAnimationEffect) {return;} GiftReceiveInfoModel * receiveInfo = [GiftReceiveInfoModel modelWithJSON:attachment.data]; GiftInfoModel * giftInfo = receiveInfo.gift ? receiveInfo.gift : receiveInfo.giftInfo; if (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend || attachment.second == Custom_Message_Sub_Gift_LuckySend) { NSString * giftId = [NSString stringWithFormat:@"%ld", receiveInfo.luckyGiftList.giftList.firstObject.giftId]; giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:giftId]; } if (giftInfo == nil) { giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:receiveInfo.giftId]; } ///在最外面判断是否可以拿到那个礼物 后面使用就不用判断了 receiveInfo.gift = giftInfo; receiveInfo.isLuckyBagGift = (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend || attachment.second == Custom_Message_Sub_Gift_LuckySend); [self.giftQueue addObject:receiveInfo]; if (self.giftTimer == nil && self.giftQueue > 0) { [self startGiftQueueTimer]; } } //扫描礼物队列 - (void)startGiftQueueTimer { NSTimeInterval period = 0.5; //设置时间间隔一个礼物动画的时间 dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0)); dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, period * NSEC_PER_SEC, 0 * NSEC_PER_SEC); dispatch_source_set_event_handler(_timer, ^{ dispatch_async(dispatch_get_main_queue(), ^{ if (self.giftQueue.count) { GiftReceiveInfoModel * receiveInfo = self.giftQueue.firstObject; [self handoutGiftDistributeAnimation:receiveInfo]; [self.giftQueue removeObject:receiveInfo]; }else { dispatch_source_cancel(_timer); self.giftTimer = nil; } }); }); dispatch_resume(_timer); self.giftTimer = _timer; } ///处理礼物的分发动画 - (void)handoutGiftDistributeAnimation:(GiftReceiveInfoModel *)receiveInfo { GiftInfoModel * giftInfo = receiveInfo.gift; NSString * sendUid = receiveInfo.uid; CGPoint starPoint = [self getGiftAnimationPoint:sendUid isEnd:NO]; CGPoint endPoint; NSArray * targetUids; if (receiveInfo.isLuckyBagGift) { targetUids = @[receiveInfo.targetUid]; } else { targetUids = receiveInfo.targetUids; if (targetUids.count <= 0) { targetUids = [receiveInfo.targetUsers valueForKeyPath:@"uid"]; if (targetUids.count <=0) { targetUids = @[receiveInfo.targetUid]; } } } for (NSString *targetUid in targetUids) { NSString * userId = targetUid; if ([userId isKindOfClass:[NSNumber class]]) { userId = ((NSNumber *)userId).stringValue; } endPoint = [self getGiftAnimationPoint:userId isEnd:YES]; dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC); dispatch_after(timer, dispatch_get_main_queue(), ^{ [self beginGiftAnimation:giftInfo.giftUrl startPoint:starPoint endPoint:endPoint]; }); } } ///起点 - (CGPoint)getGiftAnimationPoint:(NSString *)uid isEnd:(BOOL)isEnd{ CGPoint point = [self.delegate animationPointAtStageViewByUid:uid]; //没有找到那个点 那个用户不再坑位上 if (point.x <= 0 || point.y <= 0) { if (isEnd) { point = CGPointMake([UIScreen mainScreen].bounds.size.width /2 + 30, 44 + kSafeAreaTopHeight); } else { point = CGPointMake([UIScreen mainScreen].bounds.size.width / 2, 44 + kSafeAreaTopHeight); } } return point; } - (void)beginGiftAnimation:(NSString *)giftUrl startPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint { NetImageView * giftImageView = [self.giftReuseArray anyObject]; if (giftImageView == nil) { giftImageView = [[NetImageView alloc]initWithFrame:CGRectMake(0, 0 , 55, 55)]; giftImageView.center = startPoint; giftImageView.alpha = 1; giftImageView.layer.anchorPoint = CGPointMake(0.5, 0.5); giftImageView.imageUrl = giftUrl; [self.giftVisibleArray addObject:giftImageView]; }else { [self.giftReuseArray removeObject:giftImageView]; } giftImageView.hidden = NO; giftImageView.imageUrl = giftUrl; [self.lowLevelView addSubview:giftImageView]; CAAnimationGroup *group = [self createGiftAnimationStartPoint:startPoint endPoint:endPoint]; [giftImageView.layer addAnimation:group forKey:@"giftDisplayViewAnimation"]; [self performSelector:@selector(aniationDidFinish:) withObject:giftImageView afterDelay:(3.2+0.25)]; } /// 图片运动的动画组 /// @param startPoint 开始的点 /// @param endPoint 结束的点 - (CAAnimationGroup *)createGiftAnimationStartPoint:(CGPoint)startPoint endPoint:(CGPoint)endPoint{ CGPoint centerPoint = CGPointMake(KScreenWidth / 2, KScreenHeight / 2); CAKeyframeAnimation *animation0 = [CAKeyframeAnimation animation]; animation0.duration = 0.8; animation0.keyPath = @"transform.scale"; animation0.values = @[@1.0,@1.5,@2.0,@1.5]; animation0.repeatCount = 1; animation0.calculationMode = kCAAnimationCubic; animation0.removedOnCompletion = NO; animation0.fillMode = kCAFillModeForwards; CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animation]; animation1.duration = 0.8; animation1.beginTime = 0.8; animation1.keyPath = @"transform.scale"; animation1.values = @[@1.5,@2.0,@2.5,@3.0]; animation1.repeatCount = 1; animation1.calculationMode = kCAAnimationCubic; animation1.removedOnCompletion = NO; animation1.fillMode = kCAFillModeForwards; CAKeyframeAnimation *animation2 = [CAKeyframeAnimation animation]; animation2.duration = 0.8; animation2.beginTime = 0.8; animation2.keyPath = @"position"; animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];; animation2.values = @[[NSValue valueWithCGPoint:startPoint],[NSValue valueWithCGPoint:CGPointMake(centerPoint.x ,centerPoint.y)]]; animation2.repeatCount = 1; animation2.removedOnCompletion = NO; animation2.fillMode = kCAFillModeForwards; CAKeyframeAnimation *animation3 = [CAKeyframeAnimation animation]; animation3.duration = 0.8; animation3.beginTime = 2.6;//0.8+0.8+1 animation3.keyPath = @"transform.scale"; animation3.values = @[@3,@2.5,@2,@1.5,@1]; animation3.repeatCount = 1; CAKeyframeAnimation *animation4 = [CAKeyframeAnimation animation]; animation4.duration = 0.8; animation4.beginTime = 2.6; animation4.keyPath = @"position"; animation4.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; animation4.values = @[[NSValue valueWithCGPoint:CGPointMake(centerPoint.x ,centerPoint.y)],[NSValue valueWithCGPoint:endPoint]]; animation4.repeatCount = 1; CAAnimationGroup *group = [CAAnimationGroup animation]; group.duration = 3.2; group.animations = @[animation0,animation1,animation2, animation3,animation4]; group.repeatCount = 1; group.removedOnCompletion = NO; group.fillMode = kCAFillModeForwards; return group; } - (void)aniationDidFinish:(NetImageView *)giftImageView{ [giftImageView removeFromSuperview]; giftImageView.image = nil; giftImageView.hidden = YES; [self.giftVisibleArray removeObject:giftImageView]; [self.giftReuseArray addObject:giftImageView]; } #pragma mark - 全服礼物 飘屏 - (void)receiveBroadcastGift:(AttachmentModel *)attachment { if ([self isInSudGame]) {return;} GiftReceiveInfoModel *giftNotifyInfo = [GiftReceiveInfoModel modelWithJSON:attachment.data]; ///年度飘屏是广播 在tabbar中监听 if (giftNotifyInfo.ceremonyGift)return; // if(giftNotifyInfo.isHomeShow == YES)return; ///房间外飘屏 在tabbar中监听 // if(giftNotifyInfo.roomUid == self.delegate.getRoomInfo.uid)return; ///自己的房间跨房间飘屏不用走 if (self.animationListA.count == 0 && self.isPlayOfB == NO && self.isPlayOfA == NO) { [self createGiftBroadcastViewAnimation:giftNotifyInfo]; } [self.animationListA addObject:giftNotifyInfo]; } - (void)createGiftBroadcastViewAnimation:(GiftReceiveInfoModel *)giftModel { self.isPlayOfA = YES; XPRoomGiftBroadcastView * view = [[XPRoomGiftBroadcastView alloc] init]; view.delegate = self; view.frame = CGRectMake(KScreenWidth, 35 + statusbarHeight, KScreenWidth, kGetScaleWidth(69)); view.broadcastModel = giftModel; [self.highLevleView addSubview:view]; [self beginGiftBraodcastViewAnimation:view notifyStaySecond:giftModel.notifyStaySecond]; } - (void)beginGiftBraodcastViewAnimation:(XPRoomGiftBroadcastView *)view notifyStaySecond:(int)notifyStaySecond{ CGFloat startTime = notifyStaySecond > 0 ? notifyStaySecond : 3.0; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:view.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(0 + view.frame.size.width / 2, view.center.y)]; [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { if (finished) { [self removeGiftBroadcastOutAnimation:view stayTime:startTime]; } }]; [view pop_addAnimation:springAnimation forKey:@"spingOutAnimation"]; } - (void)removeGiftBroadcastOutAnimation:(XPRoomGiftBroadcastView *)view stayTime:(CGFloat)stayTime{ POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:view.center]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, view.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() + stayTime; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [view removeFromSuperview]; self.isPlayOfA = NO; if (self.animationListA.count > 0) { [self.animationListA removeObjectAtIndex:0]; } if (self.animationListA.count > 0 && self.isPlayOfB == NO && self.isPlayOfA == NO) { [self createGiftBroadcastViewAnimation:self.animationListA.firstObject]; } } }]; [view pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } #pragma mark - XPRoomGiftBroadcastViewDelegate - (void)xPRoomGiftBroadcastView:(XPRoomGiftBroadcastView *)view enterRoom:(NSString *)roomUid roomName:(NSString *)roomName{ id isShowBroadcastView = [[NSUserDefaults standardUserDefaults]valueForKey:@"kSaveBrooadcastSelectState"]; if(isShowBroadcastView == nil){ PIRoomGiftBroadcastWindow *broadcastView = [[PIRoomGiftBroadcastWindow alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; broadcastView.roodUid = roomUid; broadcastView.roomName = roomName; broadcastView.delegate = self; [kWindow addSubview:broadcastView]; return; } if (roomUid.length > 0 && self.delegate.getRoomInfo.uid != roomUid.integerValue) { [self.delegate exitRoom]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:roomUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } } #pragma mark - PIRoomGiftBroadcastWindowDelegate -(void)confirmLeaveForTheRoom:(NSString *_Nonnull)roomUid{ if (roomUid.length > 0 && self.delegate.getRoomInfo.uid != roomUid.integerValue) { [self.delegate exitRoom]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:roomUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } } #pragma mark - 福袋中 四级奖品 - (void)receiveLuckyGiftBigPrize:(AttachmentModel *)attachment { if ([self isInSudGame]) {return;} PIBaseAnimationViewModel * prizeModel = [PIBaseAnimationViewModel modelWithDictionary:attachment.data]; prizeModel.type = GiftBannerType_Lucky; prizeModel.isInRoomVisiable = attachment.second == Custom_Message_Sub_Room_Gift_LuckBag; if(self.animationListB.count == 0 && self.isPlayOfB == NO){ [self createBigPrizeAnimation:prizeModel]; } [self.animationListB addObject:prizeModel]; } - (void)createBigPrizeAnimation:(PIBaseAnimationViewModel *)prizeModel { self.isPlayOfB = YES; CGFloat top = self.isPlayOfA == YES ? (self.broadCastHieght + statusbarHeight) : (kNavigationHeight + 15); self.isLuckyGiftAnimation = YES; XPRoomLuckyBigPrizeView * luckyGiftEffectView = [[XPRoomLuckyBigPrizeView alloc] initWithFrame:CGRectMake(KScreenWidth, top, 375, 71)]; luckyGiftEffectView.delegate = self; [self.highLevleView addSubview:luckyGiftEffectView]; luckyGiftEffectView.giftInfo = prizeModel; POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; springAnimation.springSpeed = 12; springAnimation.springBounciness = 10.f; springAnimation.fromValue = [NSValue valueWithCGPoint:luckyGiftEffectView.center]; springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(KScreenWidth / 2, luckyGiftEffectView.center.y)]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 7 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, luckyGiftEffectView.center.y)]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, luckyGiftEffectView.center.y)]; moveAnimation.beginTime = CACurrentMediaTime(); moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; @kWeakify(self); [moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { @kStrongify(self); if (finished) { [luckyGiftEffectView removeFromSuperview]; if (self.animationListB.count > 0) { [self.animationListB removeObjectAtIndex:0]; } self.isPlayOfB = NO; // if(self.isAnimationListAFinish == YES){ // self.isAnimationListAFinish = NO; // [self playAnimationWithModel]; // return; // } [self playAnimationWithModel]; } }]; [luckyGiftEffectView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; }); [luckyGiftEffectView pop_addAnimation:springAnimation forKey:@"nobleLevelUpspingOutAnimation"]; } -(void)playAnimationACompletion{ PIBaseAnimationViewModel *model = self.animationListB.firstObject; if(model.type == GiftBannerType_Lucky){ [self createBigPrizeAnimation:model]; }else if (model.type == GiftBannerType_Love){ [self createCandyTreeBannerAnimation:model]; }else if(model.type == GiftBannerType_Nobleman){ [self createNobleLevelUpBannerAnimation:model]; }else if(model.type == GiftBannerType_kitchen){ [self createStarKitchenBannerAnimation:model]; }else if(model.type == GiftBannerType_AnchorHour){ [self createAnchorHourRankAnimation:model]; }else if(model.type == GiftBannerType_LicneseHour){ [self createAnchorHourRankAnimation:model]; }else if(model.type == GiftBannerType_Fairy){ [self createTreasureFairyBannerAnimation:model]; }else if(model.type == GiftBannerType_Tarrow){ [self createTarotBannerAnimation:model]; }else if(model.type == GiftBannerType_Common_H5){ [self createCommonH5BannerAnimation:model]; }else if(model.type == GiftBannerType_Magic_House){ [self createGiftCompoundBannerAnimation:model]; } } -(void)playAnimationWithModel{ // if(self.isAnimationListAFinish == YES)return; if(self.animationListB.count <= 0){ if(self.animationListA.count > 0 && self.isPlayOfB == NO && self.isPlayOfA == NO){ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self createGiftBannerViewAnimation:self.animationListA.firstObject]; }); } return; } if(self.isPlayOfB == YES)return; PIBaseAnimationViewModel *model = self.animationListB.firstObject; if(model.type == GiftBannerType_Lucky){ [self createBigPrizeAnimation:model]; }else if (model.type == GiftBannerType_Love){ [self createCandyTreeBannerAnimation:model]; }else if(model.type == GiftBannerType_Nobleman){ [self createNobleLevelUpBannerAnimation:model]; }else if(model.type == GiftBannerType_kitchen){ [self createStarKitchenBannerAnimation:model]; }else if(model.type == GiftBannerType_AnchorHour){ [self createAnchorHourRankAnimation:model]; }else if(model.type == GiftBannerType_LicneseHour){ [self createAnchorHourRankAnimation:model]; }else if(model.type == GiftBannerType_Fairy){ [self createTreasureFairyBannerAnimation:model]; }else if(model.type == GiftBannerType_Tarrow){ [self createTarotBannerAnimation:model]; }else if(model.type == GiftBannerType_Common_H5){ [self createCommonH5BannerAnimation:model]; }else if(model.type == GiftBannerType_Magic_House){ [self createGiftCompoundBannerAnimation:model]; } } #pragma mark - XPRoomLuckyBigPrizeViewDelegate - (void)xPRoomLuckyBigPrizeView:(XPRoomLuckyBigPrizeView *)view luckyGiftInfo:(PIBaseAnimationViewModel *)giftInfo { id isShowBroadcastView = [[NSUserDefaults standardUserDefaults]valueForKey:@"kSaveLuckSelectState"]; if(isShowBroadcastView == nil){ PIRoomGiftBroadcastWindow *broadcastView = [[PIRoomGiftBroadcastWindow alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; broadcastView.isLuck = YES; broadcastView.roodUid = giftInfo.roomUid; broadcastView.roomName = giftInfo.roomTitle; broadcastView.delegate = self; [kWindow addSubview:broadcastView]; return; } if (!giftInfo.isInRoomVisiable && giftInfo.roomUid.length > 0 && giftInfo.roomUid.integerValue != self.delegate.getRoomInfo.uid) { [self.delegate exitRoom]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:giftInfo.roomUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } } #pragma mark - 普通礼物 ///收到了礼物 - (void)receiveGift:(GiftReceiveInfoModel *)receiveInfo { if ([self isInSudGame]) {return;} if(receiveInfo.isHomeShow == YES)return; ///CPU警告的时候 需要停止接收动画 RoomInfoModel * roomInfor = [self.delegate getRoomInfo]; if (receiveInfo.isLuckyBagGift) { if (receiveInfo.isShowAnimation) { //如果是福袋礼物的话 就不用看他的价值了 只要有SVGA的话 就播放 if (receiveInfo.displayGift.count > 0) { [receiveInfo.displayGift enumerateObjectsUsingBlock:^(GiftInfoModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ((obj.otherViewType == GiftOtherViewTypeMp4 || obj.otherViewType == GiftOtherViewTypePag) && obj.viewUrl && obj.viewUrl.length > 0 && roomInfor.hasAnimationEffect) { GiftReceiveInfoModel * model = [[GiftReceiveInfoModel alloc] init]; model.viewUrl = obj.viewUrl; model.avatar = receiveInfo.sendUserAvatar; model.gift = obj; model.giftNum = [obj.giftNum integerValue];; model.nick = receiveInfo.nick; model.targetUids = receiveInfo.targetUids; model.isBatch = receiveInfo.isBatch; model.targetAvatar = receiveInfo.targetAvatar; model.targetNick = receiveInfo.targetNick; [self.svgaQueue addObject:model]; // [self.animationListA addObject:model]; } else if (obj.hasVggPic && roomInfor.hasAnimationEffect) { GiftReceiveInfoModel * model = [[GiftReceiveInfoModel alloc] init]; model.viewUrl = obj.viewUrl; model.avatar = receiveInfo.sendUserAvatar; model.gift = obj; model.giftNum = [obj.giftNum integerValue];; model.nick = receiveInfo.nick; model.targetUids = receiveInfo.targetUids; model.isBatch = receiveInfo.isBatch; model.targetAvatar = receiveInfo.targetAvatar; model.targetNick = receiveInfo.targetNick; [self.svgaQueue addObject:model]; // [self.animationListA addObject:model]; } }]; } } } else { GiftInfoModel *giftInfo = receiveInfo.gift != nil ? receiveInfo.gift : receiveInfo.giftInfo; if (!giftInfo) { giftInfo = [[XPGiftStorage shareStorage] findGiftInfo: receiveInfo.giftId]; } ///重新赋值一下 用的时候不用在查找了 真的没有的话 那就没有那个礼物了 if (giftInfo) { receiveInfo.gift = giftInfo; } if (receiveInfo.targetUsers.count > 0 && receiveInfo.targetUids.count <= 0) { receiveInfo.targetUids = [receiveInfo.targetUsers valueForKeyPath:@"uid"]; } NSInteger giftTotal = 0; if (receiveInfo.targetUids.count > 0) { giftTotal = receiveInfo.giftNum * giftInfo.goldPrice * receiveInfo.targetUids.count; } else { giftTotal = receiveInfo.giftNum * giftInfo.goldPrice; } if ((giftInfo.otherViewType == GiftOtherViewTypeMp4 || giftInfo.otherViewType == GiftOtherViewTypePag) && giftInfo.viewUrl.length > 0 && roomInfor.hasAnimationEffect) { receiveInfo.viewUrl = giftInfo.viewUrl; // [self.animationListA addObject:receiveInfo]; [self.svgaQueue addObject:receiveInfo]; } else if (giftInfo.hasVggPic && giftInfo.vggUrl.length > 0 && roomInfor.hasAnimationEffect) {///SVGA动画 receiveInfo.vggUrl = giftInfo.vggUrl; // [self.animationListA addObject:receiveInfo]; [self.svgaQueue addObject:receiveInfo]; } } // if (self.animationListA.count > 0 && self.isPlayOfB == NO && self.isPlayOfA == NO) { // [self createGiftBannerViewAnimation:self.animationListA.firstObject]; // } // if(self.svgaQueue.count > 0 && self.isLargeGiftAnimating == NO){ // [self createGiftSvgaAnimation:self.svgaQueue.firstObject]; // // } if (self.giftEffectTimer == nil && self.svgaQueue.count > 0) { [self startHandleGiftEffectTimer]; } } ///开启普通礼物特效定时器 - (void)startHandleGiftEffectTimer { NSTimeInterval period = 1.0; //设置时间间隔 6秒是 1、单纯的svga 2.有横幅有svga 3、只有横幅 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), period * NSEC_PER_SEC, 0); //每秒执行 @kWeakify(self); dispatch_source_set_event_handler(_timer, ^{ @kStrongify(self) if (self.svgaQueue.count > 0) { dispatch_sync(dispatch_get_main_queue(), ^{ if(self.isLargeGiftAnimating == NO){ GiftReceiveInfoModel * receiveModel = [self.svgaQueue firstObject]; [self createGiftSvgaAnimation:receiveModel]; [self.svgaQueue removeObject:receiveModel]; } }); }else { dispatch_source_cancel(_timer); self.giftEffectTimer = nil; } }); dispatch_resume(_timer); self.giftEffectTimer = _timer; } -(void)createGiftSvgaAnimation:(GiftReceiveInfoModel *)receiveInfo{ GiftInfoModel *giftInfo = receiveInfo.gift != nil ? receiveInfo.gift : receiveInfo.giftInfo; if (!giftInfo) { giftInfo = [[XPGiftStorage shareStorage] findGiftInfo: receiveInfo.giftId]; } if ((giftInfo.otherViewType == GiftOtherViewTypeMp4 || giftInfo.otherViewType == GiftOtherViewTypePag) && giftInfo.viewUrl.length > 0 && [self.delegate getRoomInfo].hasAnimationEffect) { if(giftInfo.otherViewType == GiftOtherViewTypePag){ [self largeGiftStopCarEffect:giftInfo.goldPrice]; [self playGiftEffectWithPagUrl:giftInfo.viewUrl]; }else{ [self largeGiftStopCarEffect:giftInfo.goldPrice]; [self playGiftEffectWithVapUrl:giftInfo.viewUrl]; } } if (giftInfo.hasVggPic && giftInfo.vggUrl.length > 0 && [self.delegate getRoomInfo].hasAnimationEffect) { [self largeGiftStopCarEffect:giftInfo.goldPrice]; [self playGiftEffect:giftInfo.vggUrl]; } } - (void)createGiftBannerViewAnimation:(GiftReceiveInfoModel *)receiveInfo { [self createGiftBroadcastViewAnimation:receiveInfo]; // GiftInfoModel *giftInfo = receiveInfo.gift != nil ? receiveInfo.gift : receiveInfo.giftInfo; // if (!giftInfo) { // giftInfo = [[XPGiftStorage shareStorage] findGiftInfo: receiveInfo.giftId]; // } // NSInteger giftTotal = 0; // if (receiveInfo.targetUids.count > 0) { // giftTotal = receiveInfo.giftNum * giftInfo.goldPrice * receiveInfo.targetUids.count; // } else { // giftTotal = receiveInfo.giftNum * giftInfo.goldPrice; // } // if (giftTotal >= 520) { // self.isPlayOfA = YES; // __block XPRoomGiftBannerView *view = [self.bannerDequePool anyObject]; // if (view == nil) { // view = [[XPRoomGiftBannerView alloc] init]; // [self.bannerVisiablePool addObject:view]; // }else{ // [self.bannerDequePool removeObject:view]; // } // [self removeGiftBannerView:view]; // [view configGiftBanner:receiveInfo users:[self makeBannerUsers]]; // view.frame = CGRectMake(KScreenWidth, 80, KScreenWidth, 153); // [self.highLevleView addSubview:view]; // POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter]; // springAnimation.springSpeed = 12; // springAnimation.springBounciness = 10.f; // springAnimation.fromValue = [NSValue valueWithCGPoint:view.center]; // springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(view.frame.size.width / 2, view.center.y)]; // @kWeakify(self); // [springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) { // @kStrongify(self); // if (finished) { // [self removeAnimation:view]; // } // }]; // // [springAnimation setAnimationDidStartBlock:^(POPAnimation *anim) { // @kStrongify(self); // //// if (giftInfo.otherViewType == GiftOtherViewTypeMp4 && giftInfo.viewUrl.length > 0 && [self.delegate getRoomInfo].hasAnimationEffect) { //// [self largeGiftStopCarEffect:giftInfo.goldPrice]; //// [self playGiftEffectWithVapUrl:giftInfo.viewUrl]; //// } //// if (giftInfo.hasVggPic && giftInfo.vggUrl.length > 0 && [self.delegate getRoomInfo].hasAnimationEffect) { //// [self largeGiftStopCarEffect:giftInfo.goldPrice]; //// [self playGiftEffect:giftInfo.vggUrl]; //// } // }]; // // [view pop_addAnimation:springAnimation forKey:@"spingOutAnimation"]; // } else { // //// if (giftInfo.otherViewType == GiftOtherViewTypeMp4 && receiveInfo.viewUrl.length > 0) {//播放vap动效 //// [self largeGiftStopCarEffect:giftInfo.goldPrice]; //// [self playGiftEffectWithVapUrl:receiveInfo.viewUrl]; //// } //// if (receiveInfo.vggUrl.length > 0) {///如果有特效的话就播放特效 //// //// [self largeGiftStopCarEffect:giftInfo.goldPrice]; //// [self playGiftEffect:receiveInfo.vggUrl]; //// } // [self.animationListA removeObjectAtIndex:0]; // } } - (void)largeGiftStopCarEffect:(double)goldPrice { if ([ClientConfig shareConfig].configInfo.hideCarEffectGiftPrice <= goldPrice) { self.isLargeGiftAnimating = YES; [self.carEffectView stopAnimation]; [self.carVapEffectView stopHWDMP4]; [self.carPagView stop]; [self.carEffectQueue removeAllObjects]; } } //移除特效动画 - (void)removeAnimation:(XPRoomGiftBannerView *)view{ POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter]; moveAnimation.fromValue = [NSValue valueWithCGPoint:view.center]; moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(view.center.x - KScreenWidth, view.center.y)]; moveAnimation.beginTime = CACurrentMediaTime() +5; moveAnimation.duration = 0.5; moveAnimation.repeatCount = 1; moveAnimation.removedOnCompletion = YES; moveAnimation.completionBlock = ^(POPAnimation *anim, BOOL finished) { if(finished){ [view removeFromSuperview]; self.isPlayOfA = NO; if(self.animationListA.count > 0){ [self.animationListA removeObjectAtIndex:0]; } if(self.animationListB.count > 0){ // self.isAnimationListAFinish = YES; [self playAnimationWithModel]; return; } if(self.animationListA.count > 0 && self.isPlayOfB == NO && self.isPlayOfA == NO){ [self createGiftBannerViewAnimation:self.animationListA.firstObject]; } } } ; [view pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"]; } - (NSArray *)makeBannerUsers { NSArray * microArray = [self.delegate getMicroQueue].allValues; NSMutableArray * array = [NSMutableArray array]; [microArray enumerateObjectsUsingBlock:^(MicroQueueModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { XPGiftBannerUserInfoModel * bannserUser = [[XPGiftBannerUserInfoModel alloc] init]; bannserUser.position = obj.microState.position; bannserUser.uid = obj.userInfo.uid; [array addObject:bannserUser]; }]; return array; } ///播放礼物特效 SVGA的 - (void)playGiftEffect:(NSString *)vggUrl { if ([self isInSudGame]) {return;} NSString *baseFileName = @"/GiftSvga"; NSString *filePath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:baseFileName] stringByAppendingPathComponent:vggUrl]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:filePath]){ NSData *data=[NSData dataWithContentsOfFile:filePath options:0 error:NULL]; [self.parser parseWithData:data cacheKey:nil completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { if (videoItem != nil) { self.giftEffectView.hidden = NO; if (self.giftEffectView.superview == nil) { [self.middleLevelView addSubview:self.giftEffectView]; [self.giftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } CGFloat width = videoItem.videoSize.width; CGFloat height = videoItem.videoSize.height; if (width > height) { self.giftEffectView.contentMode = UIViewContentModeScaleAspectFit; } else {//高大于宽 CGFloat resizeH = KScreenWidth * height / width;//按照屏幕的宽度去缩放,获得高度 if (resizeH > KScreenHeight) {//如果大于屏幕高度,填充 self.giftEffectView.contentMode = UIViewContentModeScaleAspectFill; } else {//小于屏幕高度, self.giftEffectView.contentMode = UIViewContentModeScaleAspectFit; } } self.giftEffectView.alpha = 1; self.giftEffectView.loops = 1; self.giftEffectView.clearsAfterStop = YES; self.giftEffectView.videoItem = videoItem; [self.giftEffectView startAnimation]; } } failureBlock:^(NSError * _Nonnull error) { self.giftEffectView.hidden = YES; }]; return; }; [self.parser parseWithURL:[NSURL URLWithString:vggUrl] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) { if (videoItem != nil) { self.giftEffectView.hidden = NO; if (self.giftEffectView.superview == nil) { [self.middleLevelView addSubview:self.giftEffectView]; [self.giftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } CGFloat width = videoItem.videoSize.width; CGFloat height = videoItem.videoSize.height; if (width > height) { self.giftEffectView.contentMode = UIViewContentModeScaleAspectFit; } else {//高大于宽 CGFloat resizeH = KScreenWidth * height / width;//按照屏幕的宽度去缩放,获得高度 if (resizeH > KScreenHeight) {//如果大于屏幕高度,填充 self.giftEffectView.contentMode = UIViewContentModeScaleAspectFill; } else {//小于屏幕高度, self.giftEffectView.contentMode = UIViewContentModeScaleAspectFit; } } self.giftEffectView.alpha = 1; self.giftEffectView.loops = 1; self.giftEffectView.clearsAfterStop = YES; self.giftEffectView.videoItem = videoItem; [self.giftEffectView startAnimation]; } } failureBlock:^(NSError * _Nullable error) { self.giftEffectView.hidden = YES; }]; } ///播放礼物特效 pag的 - (void)playGiftEffectWithPagUrl:(NSString *)pagUrl { if ([self isInSudGame]) {return;} [self.vapParser parseWithURL:pagUrl completionBlock:^(NSString * _Nullable videoUrl) { self.giftPagView.hidden = NO; if(self.giftPagView.superview == nil){ [self.middleLevelView addSubview:self.giftPagView]; [self.giftPagView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; [self.giftPagView setPath:videoUrl]; self.giftPagView.userInteractionEnabled = NO; self.giftPagView.repeatCount = 1; self.giftPagView.scaleMode = PAGScaleModeStretch; [self.giftPagView play]; } } failureBlock:^(NSError * _Nullable error) { self.giftPagView.hidden = YES; }]; } ///播放礼物特效 vap的 - (void)playGiftEffectWithVapUrl:(NSString *)vapUrl { NSString *baseFileName = @"/GiftMp4"; NSString *filePath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:baseFileName] stringByAppendingPathComponent:vapUrl]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:filePath]){ vapUrl = filePath; self.vapGiftEffectView.hidden = NO; if (self.vapGiftEffectView.superview == nil) { [self.middleLevelView addSubview:self.vapGiftEffectView]; [self.vapGiftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } [self.vapGiftEffectView setMute:YES]; [self.vapGiftEffectView playHWDMP4:vapUrl repeatCount:1 delegate:self]; return; } [self.vapParser parseWithURL:vapUrl completionBlock:^(NSString * _Nullable videoUrl) { if (videoUrl.length) { self.vapGiftEffectView.hidden = NO; if (self.vapGiftEffectView.superview == nil) { [self.middleLevelView addSubview:self.vapGiftEffectView]; [self.vapGiftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } [self.vapGiftEffectView setMute:YES]; [self.vapGiftEffectView playHWDMP4:videoUrl repeatCount:1 delegate:self]; } } failureBlock:^(NSError * _Nullable error) { self.vapGiftEffectView.hidden = YES; }]; } ///播放礼物特效 SVGA的 - (void)playLuckyGiftEffect:(NSURL *)vggUrl { if ([self isInSudGame]) {return;} NSString *baseFileName = @"/GiftSvga"; NSString *filePath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:baseFileName] stringByAppendingPathComponent:vggUrl.absoluteString]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:filePath]){ NSData *data=[NSData dataWithContentsOfFile:filePath options:0 error:NULL]; [self.parser parseWithData:data cacheKey:@"" completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { if (videoItem != nil) { self.luckyGiftEffectView.hidden = NO; if (self.luckyGiftEffectView.superview == nil) { [self.middleLevelView addSubview:self.luckyGiftEffectView]; [self.luckyGiftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } CGFloat width = videoItem.videoSize.width; CGFloat height = videoItem.videoSize.height; if (width > height) { self.luckyGiftEffectView.contentMode = UIViewContentModeScaleAspectFit; } else {//高大于宽 CGFloat resizeH = KScreenWidth * height / width;//按照屏幕的宽度去缩放,获得高度 if (resizeH > KScreenHeight) {//如果大于屏幕高度,填充 self.luckyGiftEffectView.contentMode = UIViewContentModeScaleAspectFill; } else {//小于屏幕高度, self.luckyGiftEffectView.contentMode = UIViewContentModeScaleAspectFit; } } self.luckyGiftEffectView.alpha = 1; self.luckyGiftEffectView.loops = 1; self.luckyGiftEffectView.clearsAfterStop = YES; self.luckyGiftEffectView.videoItem = videoItem; [self.luckyGiftEffectView startAnimation]; } } failureBlock:^(NSError * _Nonnull error) { self.luckyGiftEffectView.hidden = YES; }]; return; }; [self.parser parseWithURL:vggUrl completionBlock:^(SVGAVideoEntity * _Nullable videoItem) { if (videoItem != nil) { self.luckyGiftEffectView.hidden = NO; if (self.luckyGiftEffectView.superview == nil) { [self.middleLevelView addSubview:self.luckyGiftEffectView]; [self.luckyGiftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } CGFloat width = videoItem.videoSize.width; CGFloat height = videoItem.videoSize.height; if (width > height) { self.luckyGiftEffectView.contentMode = UIViewContentModeScaleAspectFit; } else {//高大于宽 CGFloat resizeH = KScreenWidth * height / width;//按照屏幕的宽度去缩放,获得高度 if (resizeH > KScreenHeight) {//如果大于屏幕高度,填充 self.luckyGiftEffectView.contentMode = UIViewContentModeScaleAspectFill; } else {//小于屏幕高度, self.luckyGiftEffectView.contentMode = UIViewContentModeScaleAspectFit; } } self.luckyGiftEffectView.alpha = 1; self.luckyGiftEffectView.loops = 1; self.luckyGiftEffectView.clearsAfterStop = YES; self.luckyGiftEffectView.videoItem = videoItem; [self.luckyGiftEffectView startAnimation]; } } failureBlock:^(NSError * _Nullable error) { self.luckyGiftEffectView.hidden = YES; }]; } ///播放礼物特效 vap的 - (void)playLuckyGiftEffectWithVapUrl:(NSString *)vapUrl { NSString *baseFileName = @"/GiftMp4"; NSString *filePath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:baseFileName] stringByAppendingPathComponent:vapUrl]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:filePath]){ vapUrl = filePath; self.luckyVapGiftEffectView.hidden = NO; if (self.luckyVapGiftEffectView.superview == nil) { [self.middleLevelView addSubview:self.luckyVapGiftEffectView]; [self.luckyVapGiftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } [self.luckyVapGiftEffectView setMute:YES]; [self.luckyVapGiftEffectView playHWDMP4:vapUrl repeatCount:1 delegate:self]; return; } [self.vapParser parseWithURL:vapUrl completionBlock:^(NSString * _Nullable videoUrl) { if (videoUrl.length) { self.luckyVapGiftEffectView.hidden = NO; if (self.luckyVapGiftEffectView.superview == nil) { [self.middleLevelView addSubview:self.luckyVapGiftEffectView]; [self.luckyVapGiftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(self.middleLevelView); make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenHeight); }]; } [self.luckyVapGiftEffectView setMute:YES]; [self.luckyVapGiftEffectView playHWDMP4:videoUrl repeatCount:1 delegate:self]; } } failureBlock:^(NSError * _Nullable error) { self.luckyVapGiftEffectView.hidden = YES; }]; } ///移除横幅的veiw 添加到复用池中 - (void)removeGiftBannerView:(XPRoomGiftBannerView *)view { [view removeFromSuperview]; [view resetData]; [self.bannerVisiablePool removeObject:view]; [self.bannerDequePool addObject:view]; ///svga的处理 [self.giftEffectView stopAnimation]; self.giftEffectView.hidden = YES; } #pragma mark - - (void)svgaPlayerDidFinishedAnimation:(SVGAPlayer *)player { if (player == self.giftEffectView) { self.giftEffectView.hidden = YES; if (self.isLargeGiftAnimating == YES) { self.isLargeGiftAnimating = NO; } } else if (player == self.luckyGiftEffectView) { self.luckyGiftEffectView.hidden = YES; } else if(player == self.carEffectView) { self.carEffectView.hidden = YES; [self.carEffectView removeFromSuperview]; if (self.carEffectQueue.count > 0) { [self.carEffectQueue removeObjectAtIndex:0]; } if (self.carEffectQueue.count > 0) { [self playCarEffect:self.carEffectQueue.firstObject]; } } else if(player == self.enterEffectView) { self.enterEffectView.hidden = YES; [self.enterEffectView removeFromSuperview]; if (self.enterEffectQueue.count > 0) { [self.enterEffectQueue removeObjectAtIndex:0]; } if (self.enterEffectQueue.count > 0) { NSString * title = [self.enterEffectQueue.firstObject objectForKey:@"title"]; NSInteger experLevelSeq = [(NSString *)[self.enterEffectQueue.firstObject objectForKey:@"experLevelSeq"] integerValue]; NSString *effectPath = [self.enterEffectQueue.firstObject objectForKey:@"effectPath"]; [self playUserEnterRoomAnimation:title experLevelSeq:experLevelSeq effectPath:effectPath]; } } } #pragma mark - 心愿礼物 - (void)receiveRoomWishGiftCelebrate:(AttachmentModel *)attachment { CGFloat x = random() % (int)(KScreenWidth - 200); CGFloat y= random() % 40 + kNavigationHeight; if (self.wishGiftEffectView.superview == nil) { [self.lowLevelView addSubview:self.wishGiftEffectView]; [self.wishGiftEffectView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(x); make.top.mas_equalTo(y); make.width.mas_equalTo(200); make.height.mas_equalTo(167); }]; } [self.wishGiftEffectView mas_updateConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(x); make.top.mas_equalTo(y); }]; NSString * anatomiser1Name = [NSString stringWithFormat:@"%@/room_wish_gift_sendCelebrate.svga", API_Image_URL]; [self.parser parseWithURL:[NSURL URLWithString:anatomiser1Name] completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { self.wishGiftEffectView.alpha = 1; self.wishGiftEffectView.loops = 1; self.wishGiftEffectView.clearsAfterStop = YES; self.wishGiftEffectView.videoItem = videoItem; [self.wishGiftEffectView startAnimation]; } failureBlock:^(NSError * _Nonnull error) { }]; } #pragma mark - HWDMP4PlayDelegate //即将开始播放时询问,true马上开始播放,false放弃播放 - (BOOL)shouldStartPlayMP4:(VAPView *)container config:(QGVAPConfigModel *)config { CGFloat width = config.info.size.width; CGFloat height = config.info.size.height; container.center = self.center; [container mas_updateConstraints:^(MASConstraintMaker *make) { make.width.mas_equalTo(KScreenWidth); make.height.mas_equalTo(KScreenWidth * height / width); }]; return YES; } - (void)viewDidFinishPlayMP4:(NSInteger)totalFrameCount view:(VAPView *)container { dispatch_async(dispatch_get_main_queue(), ^{ container.hidden = YES; if (container == self.carVapEffectView) { [self.carVapEffectView removeFromSuperview]; self.carVapEffectView = nil; if (self.carEffectQueue.count > 0) { [self.carEffectQueue removeObjectAtIndex:0]; } if (self.carEffectQueue.count > 0) { [self playCarEffect:self.carEffectQueue.firstObject]; } } else if (container == self.vapGiftEffectView) { [self.vapGiftEffectView removeFromSuperview]; self.vapGiftEffectView = nil; if (self.isLargeGiftAnimating == YES) { self.isLargeGiftAnimating = NO; } } else if(container == self.luckyVapGiftEffectView) { [self.luckyVapGiftEffectView removeFromSuperview]; self.luckyVapGiftEffectView = nil; } }); } - (void)viewDidStopPlayMP4:(NSInteger)lastFrameIndex view:(VAPView *)container { dispatch_async(dispatch_get_main_queue(), ^{ container.hidden = YES; if (container == self.carVapEffectView) { [self.carVapEffectView removeFromSuperview]; self.carVapEffectView = nil; if (self.carEffectQueue.count > 0) { [self.carEffectQueue removeObjectAtIndex:0]; } if (self.carEffectQueue.count > 0) { [self playCarEffect:self.carEffectQueue.firstObject]; } } else if (container == self.vapGiftEffectView) { [self.vapGiftEffectView removeFromSuperview]; self.vapGiftEffectView = nil; if (self.isLargeGiftAnimating == YES) { self.isLargeGiftAnimating = NO; } } else if(container == self.luckyVapGiftEffectView) { [self.luckyVapGiftEffectView removeFromSuperview]; self.luckyVapGiftEffectView = nil; } else if(container == self.wishGiftEffectView) { [self.wishGiftEffectView removeFromSuperview]; self.wishGiftEffectView = nil; } }); } #pragma mark - PAGViewListener /** * Notifies the beginning of the animation. It can be called from either the UI thread or the thread * that calls the play method. */ - (void)onAnimationStart:(PAGView*)pagView{ } /** * Notifies the end of the animation. It can only be called from the UI thread. */ - (void)onAnimationEnd:(PAGView*)pagView{ dispatch_async(dispatch_get_main_queue(), ^{ pagView.hidden = YES; if (pagView == self.giftPagView) { [self.giftPagView removeFromSuperview]; self.giftPagView = nil; if (self.isLargeGiftAnimating == YES) { self.isLargeGiftAnimating = NO; } }else if(pagView == self.carPagView){ [self.carPagView removeFromSuperview]; self.carPagView = nil; if (self.carEffectQueue.count > 0) { [self.carEffectQueue removeObjectAtIndex:0]; } if (self.carEffectQueue.count > 0) { [self playCarEffect:self.carEffectQueue.firstObject]; } } }); } /** * Notifies the cancellation of the animation. It can be called from either the UI thread or the * thread that calls the stop method. */ - (void)onAnimationCancel:(PAGView*)pagView{ dispatch_async(dispatch_get_main_queue(), ^{ pagView.hidden = YES; if (pagView == self.giftPagView) { [self.giftPagView removeFromSuperview]; self.giftPagView = nil; if (self.isLargeGiftAnimating == YES) { self.isLargeGiftAnimating = NO; } } }); } /** * Notifies the repetition of the animation. It can only be called from the UI thread. */ - (void)onAnimationRepeat:(PAGView*)pagView{ } /** * Notifies another frame of the animation has occurred. It may be called from an arbitrary * thread if the animation is running asynchronously. */ - (void)onAnimationUpdate:(PAGView*)pagView{ } #pragma mark - Getters And Setters - (SVGAImageView *)giftEffectView { if (!_giftEffectView) { _giftEffectView = [[SVGAImageView alloc]init]; _giftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; _giftEffectView.userInteractionEnabled = NO; _giftEffectView.delegate = self; _giftEffectView.hidden = YES; } return _giftEffectView; } - (VAPView *)vapGiftEffectView { if (!_vapGiftEffectView) { _vapGiftEffectView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; _vapGiftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; _vapGiftEffectView.contentMode = UIViewContentModeScaleAspectFill; _vapGiftEffectView.hidden = YES; } return _vapGiftEffectView; } - (SVGAImageView *)luckyGiftEffectView { if (!_luckyGiftEffectView) { _luckyGiftEffectView = [[SVGAImageView alloc]init]; _luckyGiftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; _luckyGiftEffectView.userInteractionEnabled = NO; _luckyGiftEffectView.delegate = self; _luckyGiftEffectView.hidden = YES; } return _luckyGiftEffectView; } - (VAPView *)luckyVapGiftEffectView { if (!_luckyVapGiftEffectView) { _luckyVapGiftEffectView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; _luckyVapGiftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5]; _luckyVapGiftEffectView.contentMode = UIViewContentModeScaleAspectFill; _luckyVapGiftEffectView.hidden = YES; } return _luckyVapGiftEffectView; } - (VAPView *)carVapEffectView { if (!_carVapEffectView) { _carVapEffectView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; _carVapEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3]; _carVapEffectView.contentMode = UIViewContentModeScaleAspectFill; _carVapEffectView.hidden = YES; } return _carVapEffectView; } - (XPRoomGiftAnimationParser *)vapParser { if (!_vapParser) { _vapParser = [[XPRoomGiftAnimationParser alloc] init]; } return _vapParser; } - (SVGAParser *)parser { if (!_parser) { _parser = [[SVGAParser alloc]init]; } return _parser; } - (NSMutableSet *)bannerDequePool { if (!_bannerDequePool) { _bannerDequePool = [NSMutableSet set]; } return _bannerDequePool; } - (NSMutableSet *)bannerVisiablePool { if (!_bannerVisiablePool) { _bannerVisiablePool = [NSMutableSet set]; } return _bannerVisiablePool; } - (XPRoomAnimationHitView *)lowLevelView { if (!_lowLevelView) { _lowLevelView = [[XPRoomAnimationHitView alloc] init]; _lowLevelView.backgroundColor = [UIColor clearColor]; _lowLevelView.userInteractionEnabled = YES; } return _lowLevelView; } - (XPRoomAnimationHitView *)middleLevelView { if (!_middleLevelView) { _middleLevelView = [[XPRoomAnimationHitView alloc] init]; _middleLevelView.backgroundColor = [UIColor clearColor]; _middleLevelView.userInteractionEnabled = YES; } return _middleLevelView; } - (XPRoomAnimationHitView *)highLevleView { if (!_highLevleView) { _highLevleView = [[XPRoomAnimationHitView alloc] init]; _highLevleView.backgroundColor = [UIColor clearColor]; _highLevleView.userInteractionEnabled = YES; } return _highLevleView; } - (NSMutableArray *)giftQueue { if (!_giftQueue) { _giftQueue = [NSMutableArray array]; } return _giftQueue; } - (NSMutableSet *)giftReuseArray { if (!_giftReuseArray) { _giftReuseArray = [NSMutableSet set]; } return _giftReuseArray; } - (NSMutableSet *)giftVisibleArray { if (!_giftVisibleArray) { _giftVisibleArray = [NSMutableSet set]; } return _giftVisibleArray; } - (NSMutableArray *)carEffectQueue { if (_carEffectQueue == nil) { _carEffectQueue = [NSMutableArray array]; } return _carEffectQueue; } - (SVGAImageView *)carEffectView { if (_carEffectView == nil) { _carEffectView = [[SVGAImageView alloc]init]; _carEffectView.delegate = self; _carEffectView.contentMode = UIViewContentModeScaleAspectFit; _carEffectView.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight); _carEffectView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3]; _carEffectView.alpha = 0; _carEffectView.userInteractionEnabled = NO; } return _carEffectView; } - (NSMutableArray *)enterEffectQueue { if (_enterEffectQueue == nil) { _enterEffectQueue = [NSMutableArray array]; } return _enterEffectQueue; } - (SVGAImageView *)enterEffectView { if (_enterEffectView == nil) { _enterEffectView = [[SVGAImageView alloc]init]; _enterEffectView.delegate = self; _enterEffectView.contentMode = UIViewContentModeScaleAspectFit; _enterEffectView.frame = CGRectMake(0, 0, KScreenWidth, 40); _enterEffectView.backgroundColor = [UIColor clearColor]; _enterEffectView.alpha = 0; _enterEffectView.userInteractionEnabled = NO; } return _enterEffectView; } - (SVGAImageView *)datingEffectView { if (_datingEffectView == nil) { _datingEffectView = [[SVGAImageView alloc]init]; _datingEffectView.delegate = self; _datingEffectView.contentMode = UIViewContentModeScaleAspectFit; _datingEffectView.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight); _datingEffectView.backgroundColor = [UIColor clearColor]; _datingEffectView.alpha = 0; _datingEffectView.userInteractionEnabled = NO; } return _datingEffectView; } - (NSMutableArray *)acrossRoomPKQueue { if (!_acrossRoomPKQueue) { _acrossRoomPKQueue = [NSMutableArray array]; } return _acrossRoomPKQueue; } - (NSMutableArray *)sailingQueue { if (!_sailingQueue) { _sailingQueue = [NSMutableArray array]; } return _sailingQueue; } - (NSMutableArray *)graffitiGiftQueue { if (!_graffitiGiftQueue) { _graffitiGiftQueue = [NSMutableArray array]; } return _graffitiGiftQueue; } - (SVGAImageView *)wishGiftEffectView { if (_wishGiftEffectView == nil) { _wishGiftEffectView = [[SVGAImageView alloc]init]; _wishGiftEffectView.delegate = self; _wishGiftEffectView.contentMode = UIViewContentModeScaleAspectFit; _wishGiftEffectView.frame = CGRectMake(0, 0, 210, 183); _wishGiftEffectView.backgroundColor = [UIColor clearColor]; _wishGiftEffectView.alpha = 1; _wishGiftEffectView.userInteractionEnabled = NO; } return _wishGiftEffectView; } - (NSMutableArray *)animationListA{ if(!_animationListA){ _animationListA = [NSMutableArray array]; } return _animationListA; } - (NSMutableArray *)animationListB{ if(!_animationListB){ _animationListB = [NSMutableArray array]; } return _animationListB; } - (NSMutableArray *)svgaQueue{ if(!_svgaQueue){ _svgaQueue = [NSMutableArray array]; } return _svgaQueue; } - (PAGView *)giftPagView{ if(!_giftPagView){ _giftPagView = [[PAGView alloc]init]; [_giftPagView addListener:self]; _giftPagView.backgroundColor = [UIColor clearColor]; } return _giftPagView; } - (PAGView *)carPagView{ if(!_carPagView){ _carPagView = [[PAGView alloc]init]; [_carPagView addListener:self]; _carPagView.backgroundColor = [UIColor clearColor]; } return _carPagView; } - (CGFloat)broadCastHieght{ if(_broadCastHieght == 0){ _broadCastHieght = 190 - 150 + kGetScaleWidth(69); } return _broadCastHieght; } @end